Init
This commit is contained in:
499
Personal/Areas/Servers/TrueNAS/Docker Gitea with Traefik.md
Normal file
499
Personal/Areas/Servers/TrueNAS/Docker Gitea with Traefik.md
Normal file
@@ -0,0 +1,499 @@
|
||||
# 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!
|
||||
Reference in New Issue
Block a user