Gitea Advanced Configuration and CI/CD
Gitea is a lightweight self-hosted Git platform that now includes Gitea Actions for CI/CD, making it a complete GitHub alternative. This guide covers advanced Gitea configuration including Actions runners, LDAP authentication, repository mirroring, webhook integration, and backup strategies.
Prerequisites
- Gitea 1.19+ installed and running
- Docker installed (for act runners)
- Root or sudo access
- Domain with SSL configured
If you need to install Gitea first:
# Download the latest binary
wget -O /usr/local/bin/gitea \
https://dl.gitea.com/gitea/$(curl -s https://dl.gitea.com/gitea/version.json | \
python3 -c "import sys,json; print(json.load(sys.stdin)['latest']['version'])")/gitea-*-linux-amd64
chmod +x /usr/local/bin/gitea
Gitea Actions Setup
Enable Gitea Actions in app.ini:
sudo nano /etc/gitea/app.ini
[actions]
ENABLED = true
DEFAULT_ACTIONS_URL = https://gitea.com ; fallback for actions/checkout etc.
sudo systemctl restart gitea
In your Gitea web UI, go to Site Administration > Configuration and verify Actions is enabled. Repository owners must also enable Actions per-repo under Settings > Actions.
Running Act Runners
Gitea Actions uses act_runner to execute workflow jobs:
# Download act_runner
wget -O /usr/local/bin/act_runner \
https://gitea.com/gitea/act_runner/releases/download/v0.2.10/act_runner-0.2.10-linux-amd64
chmod +x /usr/local/bin/act_runner
# Register the runner (get token from Site Admin > Runners)
act_runner register \
--instance https://git.yourdomain.com \
--token YOUR_RUNNER_TOKEN \
--name my-runner \
--labels ubuntu-latest:docker://node:18-bullseye
# Start the runner
act_runner daemon
Run as a systemd service:
sudo tee /etc/systemd/system/act_runner.service << 'EOF'
[Unit]
Description=Gitea Act Runner
After=network.target gitea.service
[Service]
Type=simple
User=gitea
WorkingDirectory=/var/lib/gitea
ExecStart=/usr/local/bin/act_runner daemon --config /etc/gitea/act_runner.yaml
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable --now act_runner
Example workflow file in your repository:
# .gitea/workflows/build.yaml
name: Build and Test
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run tests
run: |
npm install
npm test
Webhook Configuration
Gitea webhooks notify external services on repository events:
- Go to Repository > Settings > Webhooks > Add Webhook
- Select type (Gitea, Slack, Discord, etc.)
- Set the payload URL and secret
For custom webhooks, Gitea sends JSON payloads. Verify webhook delivery under Recent Deliveries.
CLI-based webhook testing:
# Send a test ping to your webhook endpoint
curl -X POST https://your-endpoint.com/webhook \
-H "Content-Type: application/json" \
-H "X-Gitea-Signature: sha256=..." \
-d '{"action": "ping"}'
Add webhook secrets in app.ini for additional validation:
[webhook]
ALLOWED_HOST_LIST = * ; restrict to specific hosts in production
SKIP_TLS_VERIFY = false
LDAP Authentication
Integrate Gitea with an LDAP/Active Directory server:
- Go to Site Administration > Authentication Sources > Add Authentication Source
- Select LDAP (via BindDN)
Key settings:
| Field | Example Value |
|---|---|
| Host | ldap.company.com |
| Port | 389 (or 636 for LDAPS) |
| Bind DN | cn=gitea,ou=services,dc=company,dc=com |
| User Search Base | ou=users,dc=company,dc=com |
| User Filter | (&(objectClass=person)(uid=%s)) |
| Username Attribute | uid |
| Email Attribute |
For Active Directory:
User Filter: (&(objectCategory=person)(sAMAccountName=%s))
Username Attribute: sAMAccountName
Email Attribute: mail
Test the LDAP connection after saving:
# Test from the server
ldapsearch -x -H ldap://ldap.company.com \
-D "cn=gitea,ou=services,dc=company,dc=com" \
-W -b "ou=users,dc=company,dc=com" "(uid=testuser)"
Repository Mirroring
Mirror repositories from GitHub, GitLab, or other sources:
- Create a mirror: New Repository > Migration > Choose source
- For push mirrors: Repository > Settings > Mirror Settings
Configure auto-sync interval in app.ini:
[mirror]
DEFAULT_INTERVAL = 8h ; sync every 8 hours
MIN_INTERVAL = 10m
Mirror via API:
# Create a pull mirror via API
curl -X POST https://git.yourdomain.com/api/v1/repos/migrate \
-H "Authorization: token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"clone_addr": "https://github.com/user/repo",
"uid": 1,
"repo_name": "mirrored-repo",
"mirror": true,
"mirror_interval": "8h0m0s"
}'
Performance Tuning
# /etc/gitea/app.ini
[database]
DB_TYPE = postgres ; prefer PostgreSQL over SQLite for production
MAX_OPEN_CONNS = 100
MAX_IDLE_CONNS = 50
[cache]
ADAPTER = redis
HOST = network=tcp,addr=127.0.0.1:6379,db=0,pool_size=100
[session]
PROVIDER = redis
PROVIDER_CONFIG = network=tcp,addr=127.0.0.1:6379,db=1
[queue]
TYPE = redis
CONN_STR = redis://127.0.0.1:6379/2
[server]
LFS_CONTENT_PATH = /var/lib/gitea/lfs ; store LFS on fast storage
Backup and Restore
# Create a full backup (binary must be run as the gitea user)
sudo -u gitea gitea admin dump \
--config /etc/gitea/app.ini \
--file /backup/gitea-backup-$(date +%Y%m%d).zip
# What's included: database, config, repositories, LFS, attachments
# Restore from backup
sudo systemctl stop gitea
sudo -u gitea unzip gitea-backup-20240101.zip -d /tmp/gitea-restore
# Restore each component (database, repos, etc.) according to the dump structure
sudo systemctl start gitea
Automate with a cron job:
sudo crontab -u gitea -e
# Add:
# 0 2 * * * /usr/local/bin/gitea admin dump --config /etc/gitea/app.ini --file /backup/gitea-$(date +\%Y\%m\%d).zip
Troubleshooting
Actions not triggering:
# Check that the runner is connected
# Site Admin > Runners - verify runner status is "Online"
journalctl -u act_runner -f
# Ensure Actions is enabled for the repository
# Repo > Settings > Actions > Enable
Git operations slow over SSH:
# In app.ini, tune SSH settings
[server]
START_SSH_SERVER = true
SSH_LISTEN_PORT = 2222
# Or use system SSH with gitea shell
LDAP users can't log in:
# Test the LDAP bind from the server
ldapwhoami -H ldap://ldap.company.com \
-D "cn=gitea,ou=services,dc=company,dc=com" -W
# Check Gitea logs
journalctl -u gitea -f | grep -i ldap
Database migration errors after upgrade:
# Run migrations manually
sudo -u gitea gitea migrate --config /etc/gitea/app.ini
Conclusion
Gitea's advanced features make it a capable self-hosted Git platform for teams of any size. With Gitea Actions providing native CI/CD, LDAP integration for enterprise authentication, and robust backup options, it can replace GitHub or GitLab in air-gapped or cost-sensitive environments. Keep Gitea updated and run regular backups to ensure data safety.


