Files
Obsidian-Vault/Personal/Areas/Servers/TrueNAS/Recommended Setup.md

7.1 KiB

created, updated
created updated
2025-11-02 10:47 2025-11-02 10:47

Recommended Setup for Your TrueNAS

Your Situation

  • Hardware: i7-1065G7, 16GB RAM (plenty of resources)
  • Domain: Cloudflare-managed domain
  • Requirements:
    • Gitea for self-hosted Git
    • Existing Docker stack
    • External access via Traefik
    • Separate stacks (good practice!)

Single Traefik Instance + Multiple Independent Stacks

Internet (Port 80/443)
    ↓
Router Port Forwarding
    ↓
┌─────────────────────────────┐
│   Traefik Container         │
│   - SSL Certificates        │
│   - Routing                 │
└──────────┬──────────────────┘
           │ traefik_proxy network
    ┌──────┼──────┐
    ↓      ↓      ↓
┌───────┐ ┌────────┐ ┌─────────┐
│ Gitea │ │ Other  │ │ Future  │
│ Stack │ │ Stack  │ │ Service │
└───────┘ └────────┘ └─────────┘

Each stack has its own:

  • Directory: /mnt/[pool]/docker/[service-name]/
  • docker-compose.yml
  • Data volumes
  • Can be started/stopped/updated independently

Shared:

  • One Traefik instance handles routing for all
  • One traefik_proxy network connects everything
  • One SSL certificate manager (via Cloudflare DNS)

Implementation Steps

1. Deploy Traefik (Once, First)

Location: /mnt/tank/stacks/traefik/

Key features:

  • Cloudflare DNS challenge for SSL (works even without port 80 exposed)
  • Dashboard at traefik.yourdomain.com
  • Automatic SSL renewal
  • HTTP → HTTPS redirect

See: Traefik Multi-Stack Setup#Step 1

2. Deploy Gitea Stack

Location: /mnt/tank/stacks/gitea/

Connects to: traefik_proxy network (external)

Exposes:

  • Port 2222 for SSH (git operations)
  • Port 3000 internally to Traefik (for web UI)

Accessible at: https://git.yourdomain.com

See: Traefik Multi-Stack Setup#Step 2

3. Connect Your Existing Stack

Modify your existing stack's docker-compose.yml:

  1. Add external network reference:

    networks:
      traefik_proxy:
        external: true
    
  2. Add network to your service:

    services:
      your-service:
        networks:
          - traefik_proxy
    
  3. Add Traefik labels:

        labels:
          - "traefik.enable=true"
          - "traefik.docker.network=traefik_proxy"
          - "traefik.http.routers.yourservice.rule=Host(`service.yourdomain.com`)"
          - "traefik.http.routers.yourservice.entrypoints=websecure"
          - "traefik.http.routers.yourservice.tls.certresolver=cloudflare"
          - "traefik.http.services.yourservice.loadbalancer.server.port=INTERNAL_PORT"
    
  4. Remove any exposed ports (Traefik handles routing)

See: Traefik Multi-Stack Setup#Step 3


Cloudflare Configuration

DNS Records

Add A records pointing to your public IP:

git.yourdomain.com      → Your-Public-IP (DNS only, gray cloud)
traefik.yourdomain.com  → Your-Public-IP (DNS only, gray cloud)
service.yourdomain.com  → Your-Public-IP (DNS only, gray cloud)

Important: Use "DNS only" mode, not proxied (gray cloud, not orange).

API Credentials

For Traefik to manage SSL certificates via Cloudflare DNS:

Option 1: API Token (Recommended)

  1. Cloudflare Dashboard → Profile → API Tokens
  2. Create Token → "Edit zone DNS" template
  3. Zone Resources: Include → Specific zone → yourdomain.com
  4. Use in Traefik: CF_DNS_API_TOKEN

Option 2: Global API Key

  1. Cloudflare Dashboard → Profile → API Tokens
  2. View Global API Key
  3. Use in Traefik: CF_API_EMAIL + CF_API_KEY

Router Port Forwarding

One-time setup:

External Port Internal Port Protocol Target
80 80 TCP TrueNAS IP
443 443 TCP TrueNAS IP
2222 2222 TCP TrueNAS IP

That's it! All HTTP/HTTPS traffic goes to Traefik, which routes to the correct service based on domain name.


Directory Structure

Your layout:

/mnt/tank/stacks/
├── traefik/
│   ├── docker-compose.yml
│   ├── traefik.yml
│   └── letsencrypt/
│       └── acme.json
├── gitea/
│   ├── docker-compose.yml
│   └── data/
├── servarr/
│   ├── docker-compose.yml  (or servarr.yaml)
│   └── ...
└── dozzle/  (optional split from servarr)
    └── docker-compose.yml

Benefits of This Setup

Independent stacks - Update Gitea without touching other services One SSL manager - Traefik handles certificates for all domains Easy to add services - Just add labels and deploy Clean separation - Each service in its own directory Professional setup - Industry-standard architecture Low overhead - Traefik uses ~30-50MB RAM Cloudflare integration - DNS challenge works behind CGNAT


Common Operations

Start Everything

# Start Traefik first
cd /mnt/tank/stacks/traefik
docker compose up -d

# Then start services in any order
cd /mnt/tank/stacks/gitea
docker compose up -d

cd /mnt/tank/stacks/servarr
docker compose up -d

Update One Service

cd /mnt/tank/stacks/gitea
docker compose pull
docker compose up -d
# Other services unaffected

Check Status

# See all running services
docker ps

# Check what's connected to Traefik
docker network inspect traefik_proxy | grep Name

View Logs

# Traefik routing logs
docker logs traefik -f

# Service logs
docker logs gitea -f

Timeline Estimate

If you already have:

  • Cloudflare domain
  • Port forwarding access
  • SSH to TrueNAS

Setup time:

  • Traefik deployment: 15 minutes
  • Gitea deployment: 10 minutes
  • Connect existing stack: 5 minutes
  • DNS propagation: 5-30 minutes
  • Total: ~45 minutes to 1 hour

Setup Status

Completed Steps

  • Get Cloudflare API token/key
  • SSH into TrueNAS
  • Verify /mnt/tank/stacks/ directory structure
  • Deploy Traefik stack
  • Configure router port forwarding (80, 443, 2222)
  • Add DNS records in Cloudflare
  • Deploy Gitea stack
  • Test access to all services via HTTPS

Status: Git service is operational and working! 🎉

🔜 Optional Next Steps

  • Modify existing Servarr stack to connect to Traefik (if desired)
  • Configure automated backups for Gitea
  • Set up additional services through Traefik
  • Configure Traefik dashboard access

Helpful Documentation


Notes

  • Your i7-1065G7 can easily handle Traefik + Gitea + several other services
  • Expected RAM usage: Traefik (30MB) + Gitea (150MB) = ~200MB total
  • Cloudflare DNS challenge means SSL works even if ISP blocks port 80
  • Each stack can use different databases, networks, etc. without conflicts