Skip to content

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