500 lines
10 KiB
Markdown
500 lines
10 KiB
Markdown
# 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!
|