Docker Compose — Linux / VPS¶
This is the standard deployment method for a Linux server, cloud VPS (DigitalOcean, Linode, Hetzner, AWS EC2, etc.), or any bare-metal Linux machine.
Prerequisites¶
- A Linux server (Ubuntu 22.04+ recommended, but any modern distro works)
- Docker and Docker Compose installed
- SSH access to the server
- A Cloudflare API token — see Cloudflare Setup
- (Optional) A domain name pointing to your server for HTTPS access
Step 1 — Install Docker¶
If Docker isn't installed yet:
# Install Docker using the official convenience script
curl -fsSL https://get.docker.com | sh
# Add your user to the docker group (avoids needing sudo every time)
sudo usermod -aG docker $USER
# Apply group change without logging out
newgrp docker
# Verify
docker --version
docker compose version
Step 2 — Clone the Repository¶
git clone https://github.com/dreadnought-0/Dreadnought-DDNS.git
cd Dreadnought-DDNS
Choose a good location — /opt/dreadnought or your home directory both work fine. The app files don't need to be in any particular place.
Step 3 — Configure Environment¶
cp .env.sample .env
nano .env # or vim, or any editor you prefer
Fill in all required values:
# Required
CF_API_TOKEN=your_cloudflare_api_token_here
ADMIN_EMAIL=you@example.com
ADMIN_PASSWORD=a-strong-password
# Generate with: openssl rand -hex 32
SECRET_KEY=paste-your-64-char-hex-key-here
# Optional
POLL_INTERVAL_SECONDS=300
IPV6_ENABLED=false
DISCORD_WEBHOOK_URL=
TZ=America/New_York
Generate a SECRET_KEY:
openssl rand -hex 32
Step 4 — Prepare the Data Directory¶
mkdir -p ./data
chmod 777 ./data
Or use the included setup script:
chmod +x setup.sh && ./setup.sh
Why is this needed? The API and worker containers run as a non-root user (UID 1000). The ./data directory must be writable by that UID before the containers start, otherwise SQLite can't create the database file.
Step 5 — Configure NEXT_PUBLIC_API_URL¶
For local / LAN-only access (default): No change needed. The default http://localhost:8081 works when you're accessing from the same machine.
For access from other devices on your LAN:
Edit docker-compose.yml and update the web service:
web:
environment:
- NEXT_PUBLIC_API_URL=http://192.168.1.100:8081 # your server's LAN IP
- NODE_ENV=production
For public HTTPS access (with a reverse proxy):
web:
environment:
- NEXT_PUBLIC_API_URL=https://ddns-api.yourdomain.com
- NODE_ENV=production
Step 6 — Start the App¶
docker compose up -d
First run downloads and builds images. This takes 2–5 minutes depending on your server speed.
Verify all containers are running:
docker compose ps
Expected output:
NAME STATUS PORTS
dreadnought-api-1 running (healthy) 0.0.0.0:8081->8000/tcp
dreadnought-web-1 running (healthy) 0.0.0.0:8082->3000/tcp
dreadnought-worker-1 running
Follow logs:
docker compose logs -f
# Or per service:
docker compose logs -f api
docker compose logs -f worker
docker compose logs -f web
Step 7 — Access the Dashboard¶
Open in a browser on the same machine:
http://localhost:8082
Or from another device (replace with your server's IP):
http://your-server-ip:8082
Log in with your ADMIN_EMAIL and ADMIN_PASSWORD.
Step 8 — (Optional) Expose with HTTPS¶
For public access with a domain name and HTTPS, add a reverse proxy: - Nginx guide - Traefik guide - Caddy guide
Managing the App¶
Restart services¶
docker compose restart
# Or just one service:
docker compose restart api
docker compose restart worker
docker compose restart web
Stop everything (data preserved)¶
docker compose down
Start again¶
docker compose up -d
Rebuild after code changes¶
docker compose up -d --build
Auto-Start on Server Reboot¶
The containers use restart: unless-stopped, which means Docker will restart them automatically when the Docker daemon starts. To make Docker start on boot:
sudo systemctl enable docker
sudo systemctl start docker
After this, Dreadnought will start automatically whenever your server reboots.
Firewall Configuration¶
If your server has a firewall (recommended), open only the ports you need:
sudo ufw allow ssh
sudo ufw allow 80/tcp # HTTP (for Let's Encrypt challenges)
sudo ufw allow 443/tcp # HTTPS
# Block direct access to app ports (force traffic through reverse proxy)
sudo ufw deny 8081/tcp
sudo ufw deny 8082/tcp
sudo ufw enable
If you want to allow LAN access to the app directly (without a reverse proxy):
sudo ufw allow from 192.168.0.0/24 to any port 8081 # Adjust subnet
sudo ufw allow from 192.168.0.0/24 to any port 8082
Updating¶
cd /path/to/Dreadnought-DDNS
git pull origin main
# Rebuild and restart (data in ./data is unaffected)
docker compose up -d --build
# Clean up old build layers (optional)
docker system prune -f
Monitoring¶
Container resource usage:
docker stats
Disk usage:
# Database size
du -sh ./data/ddns.db
# Docker images/volumes
docker system df
API health check:
curl http://localhost:8081/health