# 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 1. **Domain name** (or subdomain) pointed to your public IP - Example: `git.yourdomain.com` - Can use free services like DuckDNS, Cloudflare, etc. 2. **Port forwarding** on your router - Port 80 (HTTP) → TrueNAS IP - Port 443 (HTTPS) → TrueNAS IP 3. **SSH access** to TrueNAS Scale --- ## Step 1: Create Datasets SSH into TrueNAS and create storage locations: ```bash # 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 ```bash cd /mnt/[your-pool-name]/docker/traefik ``` ### Create `traefik.yml` ```yaml 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 ```yaml 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 ```bash cd /mnt/[your-pool-name]/docker/traefik docker compose up -d ``` --- ## Step 3: Gitea with Traefik Integration ### Create `docker-compose.yml` for Gitea ```bash cd /mnt/[your-pool-name]/docker/gitea ``` Create `docker-compose.yml`: ```yaml 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 ```bash 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) 1. Add A record: `git.yourdomain.com` → Your public IP 2. Optional: Enable Cloudflare proxy (orange cloud) - Pros: DDoS protection, caching - Cons: Need to configure Traefik for Cloudflare SSL ### Option B: DuckDNS (Free Dynamic DNS) 1. Create account at duckdns.org 2. Create subdomain: `yourname.duckdns.org` 3. Set up auto-update script on TrueNAS for dynamic IP ### Option C: Your Domain Registrar 1. Add A record: `git` → Your public IP 2. Wait for DNS propagation (up to 24 hours) --- ## Step 6: Initial Gitea Setup 1. Navigate to `https://git.yourdomain.com` 2. 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 1. Generate SSH key (if needed): ```bash ssh-keygen -t ed25519 -C "your-email@example.com" ``` 2. Copy public key: ```bash cat ~/.ssh/id_ed25519.pub ``` 3. In Gitea: Settings → SSH/GPG Keys → Add Key ### Test SSH Connection ```bash ssh -T git@git.yourdomain.com ``` Expected output: ``` Hi there, username! You've successfully authenticated... ``` --- ## Step 8: Usage Examples ### Clone Repository ```bash # HTTPS git clone https://git.yourdomain.com/username/repo.git # SSH (recommended) git clone git@git.yourdomain.com:username/repo.git ``` ### Push Existing Repository ```bash 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 ```bash # 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: ```bash # 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/gitea` dataset - Retention: Daily for 7 days, weekly for 4 weeks - Optional: Replicate to another location --- ## Maintenance ### Update Containers ```bash # 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 ```bash # Traefik docker logs traefik -f # Gitea docker logs gitea -f ``` ### Restart Services ```bash # Restart Gitea docker restart gitea # Restart Traefik docker restart traefik ``` --- ## Security Hardening ### 1. Disable Gitea Registration In Gitea settings or `app.ini`: ```ini [service] DISABLE_REGISTRATION = true REQUIRE_SIGNIN_VIEW = true # Optional: require login to view ``` ### 2. Fail2Ban (Optional) Protect against brute force attacks: ```bash # Install fail2ban on TrueNAS # Configure jail for Gitea SSH attempts ``` ### 3. Firewall Rules On TrueNAS, restrict access if needed: ```bash # 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:** ```bash 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 1. Verify port forwarding on router 2. Check public IP: `curl ifconfig.me` 3. Test DNS: `nslookup git.yourdomain.com` 4. Check Traefik dashboard for routes ### SSH Clone Not Working 1. Verify port 2222 is forwarded 2. Test: `nc -zv git.yourdomain.com 2222` 3. Check SSH key is added in Gitea 4. Verify SSH config (~/.ssh/config) ### Gitea Container Won't Start ```bash # 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!