How-To
Deploy with Docker

How to Deploy with Docker

This guide walks through deploying the NAT self-hosted server in a production Docker environment.

For a pip-based (non-Docker) deployment, see the Self-Hosted Setup guide.

Prepare your server

A Linux server with Docker and Docker Compose installed. Minimum specs:

  • OS: Ubuntu 22.04 LTS or Debian 12
  • RAM: 2 GB minimum, 4 GB recommended
  • Disk: 20 GB (for Docker image + scan data storage)
  • Docker: 24.x or later
  • Docker Compose: v2.x or later

Generate a secret key

python3 -c "import secrets; print(secrets.token_hex(32))"
# 3f8a2b1c9e4d7f0a6c5e2b8d1f4a7c0e3b6d9f2a5c8e1b4d7f0a3c6e9b2d5f8a

Save this — you'll need it in the next step.

Create the project directory

mkdir -p /opt/nat && cd /opt/nat
mkdir -p data

Create the environment file

cat > /opt/nat/.env << 'EOF'
NAT_SECRET_KEY=your-generated-secret-key-here
NAT_LOG_LEVEL=info
NAT_DATA_DIR=/data
EOF
 
chmod 600 /opt/nat/.env

Create the Docker Compose file

cat > /opt/nat/docker-compose.yml << 'EOF'
version: '3.8'
 
services:
  nat-server:
    image: natengine/nat:latest
    command: nat server start --host 0.0.0.0 --port 8080
    ports:
      - "127.0.0.1:8080:8080"   # only expose locally; nginx handles external access
    volumes:
      - ./data:/data
    env_file: .env
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s
 
EOF

Start the NAT server

docker compose up -d
docker compose logs -f nat-server

Confirm it's healthy:

docker compose ps
# nat-server   Up (healthy)

Set up nginx as a reverse proxy with TLS

Install nginx and Certbot:

sudo apt update
sudo apt install nginx certbot python3-certbot-nginx

Create the nginx config:

sudo cat > /etc/nginx/sites-available/nat << 'EOF'
server {
    server_name nat.example.com;
 
    location / {
        proxy_pass         http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_set_header   Upgrade           $http_upgrade;
        proxy_set_header   Connection        "upgrade";
        proxy_read_timeout 300s;
    }
}
EOF
 
sudo ln -s /etc/nginx/sites-available/nat /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

Obtain a TLS certificate:

sudo certbot --nginx -d nat.example.com

Verify the deployment

Open https://nat.example.com in your browser. You should see the NAT dashboard login page.

Updating NAT

cd /opt/nat
 
# Pull the latest image
docker compose pull nat-server
 
# Restart with the new image
docker compose up -d nat-server
 
# Verify
docker compose ps
docker compose logs nat-server --tail 20
⚠️

Always check the Changelog before updating to review breaking changes and migration notes.

Backups

Back up the data directory regularly:

# Stop the server briefly for a clean backup
docker compose stop nat-server
tar -czf /backup/nat-data-$(date +%Y%m%d).tar.gz /opt/nat/data
docker compose start nat-server

Automate with cron:

# /etc/cron.d/nat-backup
0 3 * * * root docker compose -f /opt/nat/docker-compose.yml stop nat-server && \
  tar -czf /backup/nat-data-$(date +\%Y\%m\%d).tar.gz /opt/nat/data && \
  docker compose -f /opt/nat/docker-compose.yml start nat-server

Troubleshooting

See Docker Issues troubleshooting for common Docker deployment problems.

Next steps