Gitea / Forgejo Setup: Self-Hosted Git Server
Gitea or Forgejo Docker installation, repository management, CI/CD (Gitea Actions), SSH key configuration, organization and team management, mirror and webhook.
Table of Contents
Gitea / Forgejo Setup: Self-Hosted Git Server
Gitea and Forgejo are open-source, lightweight, self-hosted alternatives to GitHub and GitLab. You can host Git repositories on your own server, run CI/CD pipelines, and collaborate on code with your team. Forgejo is a community-focused fork of Gitea, and both are largely compatible with each other.
Gitea vs Forgejo
| Feature | Gitea | Forgejo |
|---|---|---|
| License | MIT | GPL-3.0 |
| Governance | Company-backed | Community-governed |
| Compatibility | Reference implementation | Gitea-compatible |
| Updates | Regular | More frequent |
| Recommended for | Enterprise | Community |
Both projects use the same docker-compose structure; only the image name differs.
System Requirements
- Server with Docker and Docker Compose installed
- Minimum 512 MB RAM (1 GB recommended)
- PostgreSQL or MySQL (recommended) or SQLite
- Port 22 or custom port for SSH access
Installation with Docker
docker-compose.yml (Gitea)
version: '3.8'
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=postgres
- GITEA__database__HOST=db:5432
- GITEA__database__NAME=gitea
- GITEA__database__USER=gitea
- GITEA__database__PASSWD=strong-password
- GITEA__server__DOMAIN=git.example.com
- GITEA__server__SSH_DOMAIN=git.example.com
- GITEA__server__ROOT_URL=https://git.example.com/
- GITEA__server__SSH_PORT=2222
volumes:
- ./gitea-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "127.0.0.1:3000:3000"
- "2222:22"
depends_on:
- db
db:
image: postgres:15
container_name: gitea-db
restart: unless-stopped
environment:
POSTGRES_DB: gitea
POSTGRES_USER: gitea
POSTGRES_PASSWORD: strong-password
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:
Switching to Forgejo
# Just change the image line:
image: codeberg.org/forgejo/forgejo:latest
# Start the container
docker compose up -d
# Check logs
docker logs gitea -f
Nginx Reverse Proxy
server {
listen 80;
server_name git.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name git.example.com;
ssl_certificate /etc/letsencrypt/live/git.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.example.com/privkey.pem;
client_max_body_size 512M;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Initial Configuration
After installation, go to https://git.example.com:
- Database settings are auto-filled (from env)
- General settings: Site title, admin email
- Create admin account
- Complete the setup
Advanced Configuration with app.ini
# /data/gitea/conf/app.ini
[server]
DOMAIN = git.example.com
ROOT_URL = https://git.example.com/
SSH_DOMAIN = git.example.com
SSH_PORT = 2222
DISABLE_SSH = false
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false
[mailer]
ENABLED = true
FROM = gitea@example.com
SMTP_ADDR = smtp.example.com
SMTP_PORT = 587
USER = gitea@example.com
PASSWD = smtp-password
SSH Key Configuration
Adding User SSH Key
# Generate SSH key
ssh-keygen -t ed25519 -C "user@example.com"
# Copy public key
cat ~/.ssh/id_ed25519.pub
In Gitea: Profile → Settings → SSH/GPG Keys → Add SSH Key
Clone via SSH
# Clone via SSH (port 2222)
git clone ssh://git@git.example.com:2222/user/repo.git
# Simplify with ~/.ssh/config
Host git.example.com
HostName git.example.com
User git
Port 2222
IdentityFile ~/.ssh/id_ed25519
# After config
git clone git@git.example.com:user/repo.git
Repository Management
Creating a Repository
# Create new repo and push
mkdir myproject && cd myproject
git init
git add .
git commit -m "Initial commit"
git remote add origin https://git.example.com/user/myproject.git
git push -u origin main
Mirror Repository
Creating a mirror from GitHub/GitLab:
New Repository → Migrate → GitHub/GitLab/Bitbucket
- Clone URL: https://github.com/user/repo.git
- Mirror (auto-sync): Enabled
- Sync interval: 8 hours
Gitea Actions (CI/CD)
Actions Runner Setup
# Add to docker-compose.yml
runner:
image: gitea/act_runner:latest
container_name: gitea-runner
restart: unless-stopped
environment:
- GITEA_INSTANCE_URL=https://git.example.com
- GITEA_RUNNER_REGISTRATION_TOKEN=RUNNER_TOKEN
- GITEA_RUNNER_NAME=my-runner
volumes:
- ./runner-data:/data
- /var/run/docker.sock:/var/run/docker.sock
Workflow File
# .gitea/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Build
run: npm run build
Organization and Team Management
Create Organization:
+ → New Organization → Name and visibility
Create Team:
Organization → Teams → New Team
- Permissions: Owner, Admin, Write, Read
- Repository access: Specific or all
Invite Member:
Team → Members → Add User
Webhook Configuration
Repository → Settings → Webhooks → Add Webhook
Payload URL: https://ci.example.com/webhook
Content Type: application/json
Secret: webhook-secret-key
Events: Push, Pull Request, Release
Backup
# Backup Gitea data
docker exec gitea gitea dump -c /data/gitea/conf/app.ini
# Database backup
docker exec gitea-db pg_dump -U gitea gitea > gitea-db-$(date +%Y%m%d).sql
# Full data directory
tar -czf gitea-backup-$(date +%Y%m%d).tar.gz ./gitea-data/
With Gitea/Forgejo on REXE VPS servers, you can manage your entire team's code infrastructure. 1 GB RAM is ideal for small to medium teams.
Related Articles
Coolify Setup: Application Deployment with Self-Hosted PaaS
Coolify installation, Docker and Git integration, application deployment, database management, SSL certificates, environment variables, and self-hosted PaaS alternative to Heroku/Netlify.
Nextcloud Setup: Self-Hosted Cloud Storage and Collaboration
Nextcloud installation with Docker, Apache/Nginx configuration, database setup, SSL certificate, file synchronization, app store, and performance optimization.
Docker Management with Portainer: Web-Based Container Control
Portainer CE installation, Docker and Kubernetes management, stack deployment, volume/network management, user authorization, webhook and GitOps integration.