10 KiB
Docker Gitea with Traefik Setup
Overview
Complete setup for self-hosted Gitea with Traefik reverse proxy for secure external access on TrueNAS Scale.
Stack:
- Gitea (Git server)
- Traefik (Reverse proxy with automatic SSL)
- Docker Compose
Prerequisites
-
Domain name (or subdomain) pointed to your public IP
- Example:
git.yourdomain.com - Can use free services like DuckDNS, Cloudflare, etc.
- Example:
-
Port forwarding on your router
- Port 80 (HTTP) → TrueNAS IP
- Port 443 (HTTPS) → TrueNAS IP
-
SSH access to TrueNAS Scale
Step 1: Create Datasets
SSH into TrueNAS and create storage locations:
# Create main directory for docker compose projects
cd /mnt/[your-pool-name]
mkdir -p docker/gitea
mkdir -p docker/traefik
# Create data directories
mkdir -p docker/gitea/data
mkdir -p docker/traefik/letsencrypt
Or create via TrueNAS web UI:
- Storage → Create Dataset →
docker - Then create subdirectories via SSH or UI
Step 2: Traefik Configuration
Create Traefik Config Directory
cd /mnt/[your-pool-name]/docker/traefik
Create traefik.yml
api:
dashboard: true
insecure: false
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
network: traefik_proxy
certificatesResolvers:
letsencrypt:
acme:
email: your-email@example.com
storage: /letsencrypt/acme.json
httpChallenge:
entryPoint: web
Create docker-compose.yml for Traefik
version: '3.8'
networks:
traefik_proxy:
name: traefik_proxy
driver: bridge
services:
traefik:
image: traefik:v2.10
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- traefik_proxy
ports:
- "80:80"
- "443:443"
environment:
- TZ=America/New_York # Adjust to your timezone
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/traefik.yml:ro
- ./letsencrypt:/letsencrypt
labels:
- "traefik.enable=true"
# Dashboard
- "traefik.http.routers.traefik.rule=Host(`traefik.yourdomain.com`)"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik.service=api@internal"
# Basic auth for dashboard (optional but recommended)
# Generate password: echo $(htpasswd -nb admin yourpassword) | sed -e s/\\$/\\$\\$/g
- "traefik.http.routers.traefik.middlewares=traefik-auth"
- "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$apr1$$xyz$$abc123" # Replace with your hash
Start Traefik
cd /mnt/[your-pool-name]/docker/traefik
docker compose up -d
Step 3: Gitea with Traefik Integration
Create docker-compose.yml for Gitea
cd /mnt/[your-pool-name]/docker/gitea
Create docker-compose.yml:
version: '3.8'
networks:
traefik_proxy:
external: true
gitea_internal:
driver: bridge
services:
gitea:
image: gitea/gitea:latest
container_name: gitea
restart: unless-stopped
environment:
- USER_UID=1000
- USER_GID=1000
- GITEA__database__DB_TYPE=sqlite3
- GITEA__server__DOMAIN=git.yourdomain.com
- GITEA__server__SSH_DOMAIN=git.yourdomain.com
- GITEA__server__ROOT_URL=https://git.yourdomain.com
- GITEA__server__SSH_PORT=2222
- GITEA__server__SSH_LISTEN_PORT=22
networks:
- traefik_proxy
- gitea_internal
volumes:
- ./data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "2222:22" # SSH for git operations
labels:
- "traefik.enable=true"
- "traefik.docker.network=traefik_proxy"
# HTTP/HTTPS
- "traefik.http.routers.gitea.rule=Host(`git.yourdomain.com`)"
- "traefik.http.routers.gitea.entrypoints=websecure"
- "traefik.http.routers.gitea.tls.certresolver=letsencrypt"
- "traefik.http.services.gitea.loadbalancer.server.port=3000"
Start Gitea
docker compose up -d
Step 4: Router Configuration
Port Forwarding Rules
On your router, forward these ports to your TrueNAS IP:
| External Port | Internal Port | Protocol | Service |
|---|---|---|---|
| 80 | 80 | TCP | HTTP (Traefik) |
| 443 | 443 | TCP | HTTPS (Traefik) |
| 2222 | 2222 | TCP | SSH (Git operations) |
Step 5: DNS Configuration
Point your domain/subdomain to your public IP:
Option A: Cloudflare (Recommended)
- Add A record:
git.yourdomain.com→ Your public IP - Optional: Enable Cloudflare proxy (orange cloud)
- Pros: DDoS protection, caching
- Cons: Need to configure Traefik for Cloudflare SSL
Option B: DuckDNS (Free Dynamic DNS)
- Create account at duckdns.org
- Create subdomain:
yourname.duckdns.org - Set up auto-update script on TrueNAS for dynamic IP
Option C: Your Domain Registrar
- Add A record:
git→ Your public IP - Wait for DNS propagation (up to 24 hours)
Step 6: Initial Gitea Setup
- Navigate to
https://git.yourdomain.com - Complete first-time setup wizard:
- Database: SQLite (default is fine for personal use)
- SSH Server Domain:
git.yourdomain.com - SSH Port:
2222 - Base URL:
https://git.yourdomain.com - Disable registration (personal use only)
- Create admin account
Step 7: Configure Git Client
SSH Config
Add to ~/.ssh/config:
Host git.yourdomain.com
HostName git.yourdomain.com
Port 2222
User git
IdentityFile ~/.ssh/id_ed25519 # Or your SSH key
Add SSH Key to Gitea
-
Generate SSH key (if needed):
ssh-keygen -t ed25519 -C "your-email@example.com" -
Copy public key:
cat ~/.ssh/id_ed25519.pub -
In Gitea: Settings → SSH/GPG Keys → Add Key
Test SSH Connection
ssh -T git@git.yourdomain.com
Expected output:
Hi there, username! You've successfully authenticated...
Step 8: Usage Examples
Clone Repository
# HTTPS
git clone https://git.yourdomain.com/username/repo.git
# SSH (recommended)
git clone git@git.yourdomain.com:username/repo.git
Push Existing Repository
cd /path/to/your/repo
git remote add origin git@git.yourdomain.com:username/repo.git
git push -u origin main
Backup Strategy
Manual Backup
# Stop Gitea
cd /mnt/[your-pool-name]/docker/gitea
docker compose down
# Backup data directory
tar -czf gitea-backup-$(date +%Y%m%d).tar.gz data/
# Restart Gitea
docker compose up -d
Automated Backup (Gitea Built-in)
Create cron job on TrueNAS:
# Add to crontab (System Settings → Advanced → Cron Jobs in TrueNAS UI)
0 2 * * * docker exec gitea gitea dump -c /data/gitea/conf/app.ini -f /data/gitea-backup-$(date +\%Y\%m\%d).zip
TrueNAS Snapshots
- Enable periodic snapshots for
docker/giteadataset - Retention: Daily for 7 days, weekly for 4 weeks
- Optional: Replicate to another location
Maintenance
Update Containers
# Traefik
cd /mnt/[your-pool-name]/docker/traefik
docker compose pull
docker compose up -d
# Gitea
cd /mnt/[your-pool-name]/docker/gitea
docker compose pull
docker compose up -d
View Logs
# Traefik
docker logs traefik -f
# Gitea
docker logs gitea -f
Restart Services
# Restart Gitea
docker restart gitea
# Restart Traefik
docker restart traefik
Security Hardening
1. Disable Gitea Registration
In Gitea settings or app.ini:
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = true # Optional: require login to view
2. Fail2Ban (Optional)
Protect against brute force attacks:
# Install fail2ban on TrueNAS
# Configure jail for Gitea SSH attempts
3. Firewall Rules
On TrueNAS, restrict access if needed:
# Only allow specific IPs (example)
iptables -A INPUT -p tcp --dport 2222 -s YOUR_IP -j ACCEPT
iptables -A INPUT -p tcp --dport 2222 -j DROP
4. Regular Updates
- Update Docker images monthly
- Monitor Gitea security advisories
- Keep TrueNAS Scale updated
Troubleshooting
SSL Certificate Not Generated
Check Traefik logs:
docker logs traefik | grep -i error
Common issues:
- Port 80/443 not properly forwarded
- DNS not pointing to your IP
- Email in traefik.yml incorrect
- Firewall blocking ports
Can't Access Externally
- Verify port forwarding on router
- Check public IP:
curl ifconfig.me - Test DNS:
nslookup git.yourdomain.com - Check Traefik dashboard for routes
SSH Clone Not Working
- Verify port 2222 is forwarded
- Test:
nc -zv git.yourdomain.com 2222 - Check SSH key is added in Gitea
- Verify SSH config (~/.ssh/config)
Gitea Container Won't Start
# Check logs
docker logs gitea
# Common issues:
# - Port conflicts (3000 or 2222 in use)
# - Permission issues on data directory
# - Network conflicts
Resource Usage
Expected usage on your i7-1065G7 with 16GB RAM:
- Traefik: ~30-50 MB RAM, minimal CPU
- Gitea: ~100-150 MB RAM, <5% CPU (idle)
- Total: ~150-200 MB RAM combined
Plenty of headroom for other services!
Next Steps
- Decide on domain name (purchase or use DuckDNS)
- Create datasets on TrueNAS
- Set up Traefik with docker-compose
- Configure DNS records
- Set up router port forwarding
- Deploy Gitea container
- Complete Gitea initial setup
- Configure SSH keys
- Test external access
- Set up automated backups
- Migrate repositories from GitHub
Additional Services to Consider
Once Traefik is set up, you can easily add more services:
- Uptime Kuma - Monitoring dashboard
- Vaultwarden - Self-hosted Bitwarden
- Nextcloud - File sync and sharing
- Portainer - Docker management UI
- Homer/Heimdall - Homepage dashboard
All use the same Traefik setup for automatic SSL!