This Docker Compose setup configures Traefik as a reverse proxy with automatic Let's Encrypt SSL certificates using DNS challenge via DigitalOcean.
- Automatic HTTPS with Let's Encrypt SSL certificates
- DNS challenge using DigitalOcean (works for internal IPs)
- Automatic certificate renewal
- HTTP to HTTPS redirection
- Traefik dashboard for monitoring
- Easy to extend with additional services
- Docker and Docker Compose installed on your NAS
- Domain
console.lolwith DNS pointing to your NAS IP (10.0.0.54) - DigitalOcean account with API token for DNS challenge
- DNS records configured:
*.console.lol→ 10.0.0.54 (wildcard A record)- Or individual A records for each subdomain
In your DigitalOcean DNS panel for console.lol:
Type: A
Hostname: *
Value: 10.0.0.54
TTL: 3600
Or create individual A records:
nas.console.lol→ 10.0.0.54syncthing.console.lol→ 10.0.0.54traefik.console.lol→ 10.0.0.54
- Go to https://cloud.digitalocean.com/account/api/tokens
- Generate a new token with read/write access
- Copy the token
cp .env.example .envEdit .env and add your DigitalOcean API token:
DO_AUTH_TOKEN=your_actual_token_here
Edit traefik/traefik.yml and replace your-email@example.com with your actual email address for Let's Encrypt notifications.
docker network create proxydocker compose up -ddocker compose logs -f traefikWatch for successful certificate generation. It should show:
- Certificate obtained for
console.loland*.console.lol
The following services are pre-configured:
| Service | URL | Backend |
|---|---|---|
| NAS ADM | https://nas.console.lol | http://10.0.0.54:8001 |
| Syncthing | https://syncthing.console.lol | http://10.0.0.54:28384 |
| Traefik Dashboard | https://traefik.console.lol | Internal |
The dashboard is protected with basic auth:
- Username:
admin - Password:
admin(change this!)
To generate a new password hash:
echo $(htpasswd -nb admin your_password) | sed -e s/\\$/\\$\\$/gUpdate the hash in docker-compose.yml under the traefik-auth.basicauth.users label.
To add a new service, edit traefik/config.yml:
http:
routers:
your-service-name:
entryPoints:
- 'https'
rule: 'Host(`your-service.console.lol`)'
middlewares:
- default-headers
tls:
certResolver: digitalocean
service: your-service-name
services:
your-service-name:
loadBalancer:
servers:
- url: 'http://10.0.0.54:PORT'
passHostHeader: trueThen reload Traefik:
docker compose restart traefik.
├── docker-compose.yml # Main Docker Compose configuration
├── .env # Environment variables (DO NOT commit)
├── .env.example # Example environment file
├── traefik/
│ ├── traefik.yml # Static Traefik configuration
│ ├── config.yml # Dynamic configuration (routes/services)
│ └── acme.json # Let's Encrypt certificates storage
└── README.md # This file
- Check DigitalOcean API token is correct
- Verify DNS records are propagated:
dig nas.console.lol - Check Traefik logs:
docker compose logs -f traefik - Ensure
acme.jsonhas 600 permissions
- Check the backend service is running on the specified port
- Verify firewall allows ports 80 and 443
- Check Traefik dashboard for router status
- Test backend directly:
curl http://10.0.0.54:PORT
Certificates auto-renew 30 days before expiration. Check logs around renewal time.
- The
.envfile contains sensitive API tokens - never commit it to version control - Change the default Traefik dashboard password
- Consider restricting access to the Traefik dashboard to local network only
- The
default-whitelistmiddleware is configured for private IP ranges
After making changes to traefik/config.yml:
docker compose restart traefikAfter making changes to traefik/traefik.yml or docker-compose.yml:
docker compose down
docker compose up -ddocker compose down