warmbox/docs/deploy-ubuntu-docker.md
Jonny Nguyen ed3ec86025 Add Woodpecker CI/CD pipeline configuration and new chart components
Introduce a Woodpecker CI/CD pipeline in `.woodpecker.yml` for automated deployment on pushes to the main branch. Add new components for visualizing campaign performance, including `DailyPerformanceChart`, `InboxPlacementChart`, and `InboxVsSpamChart`, to enhance the Campaign Detail page. Update `WarmupPlanChart` to include additional metrics and improve tooltip information. Enhance utility functions for chart data formatting and daily statistics mapping.
2026-06-26 14:23:18 -07:00

5.5 KiB
Raw Blame History

Deploy Warmbox with Nginx Proxy Manager (Docker)

Warmbox runs as one container on your existing npm_network. Nginx Proxy Manager (NPM) terminates HTTPS and forwards to http://warmbox:3000.

Internet → warmbox.jonnyn.com (DNS) → NPM :443 → warmbox:3000 (Docker network)

No host port is published. Warmbox can run alongside homepage on host port 3000 — they do not conflict.


Prerequisites

  • Ubuntu server with Docker + Compose v2
  • Nginx Proxy Manager already running on Docker network npm_network
  • DNS A record: warmbox.jonnyn.com → your home public IP
  • Router forwards 80 and 443 to NPM (if not already)

Confirm NPMs network name:

docker network ls | grep npm
docker inspect <npm-container-name> --format '{{json .NetworkSettings.Networks}}' | jq

If your network is not npm_network, edit networks.default.name in docker-compose.yml.


1. Clone and configure

cd /srv/docker-configs/warmbox   # or your path
git pull                         # get latest docker-compose.yml

cp .env.example .env
nano .env

Required variables:

ENCRYPTION_KEY=<openssl rand -hex 32>   # never change after first deploy
API_KEY=<openssl rand -hex 24>          # dashboard login
PUBLIC_BASE_URL=https://warmbox.jonnyn.com
AI_API_KEY=sk-or-v1-...

Migrating from your Mac: use the same ENCRYPTION_KEY and copy prisma/dev.db (see §6).


2. Start Warmbox

cd /srv/docker-configs/warmbox

# Stop any old stack (including previous compose overrides)
docker compose down

# Build and start — joins npm_network automatically
docker compose up -d --build

Verify:

docker compose ps
docker compose logs -f warmbox

Warmbox should be healthy. Check it is on npm_network:

docker inspect warmbox --format '{{range $k,$v := .NetworkSettings.Networks}}{{$k}} {{end}}'
# should include: npm_network

Test from another container on the same network (e.g. NPM):

docker exec -it <npm-app-container> wget -qO- http://warmbox:3000/health
# expect: {"status":"ok"}

3. Nginx Proxy Manager — proxy host

Open NPM UI (usually http://<server-ip>:81).

Hosts → Proxy Hosts → Add Proxy Host

Tab / field Value
Domain names warmbox.jonnyn.com
Scheme http
Forward hostname / IP warmbox
Forward port 3000
Cache assets off
Block common exploits on
Websockets support on

SSL tab:

  • SSL Certificate: Request a new Let's Encrypt certificate
  • Force SSL: on
  • HTTP/2: on

If Cloudflare proxies your A record (orange cloud), set Cloudflare SSL mode to Full or Full (strict).

Save, then test:

curl -s https://warmbox.jonnyn.com/health

4. Dashboard login

  1. Open https://warmbox.jonnyn.com
  2. Enter API_KEY from .env
  3. Leave Base URL empty (same origin in production)

5. OAuth redirect URIs

Update in Google Cloud / Azure if you use these integrations:

Integration Redirect URI
Google Postmaster https://warmbox.jonnyn.com/api/integrations/google/callback
Microsoft Outlook https://warmbox.jonnyn.com/api/integrations/microsoft/callback

6. Migrate local database (optional)

# On your Mac
scp prisma/dev.db jonnyn@burke:/tmp/warmbox.db

# On server
cd /srv/docker-configs/warmbox
docker compose down
docker run --rm -v warmbox_warmbox-data:/data -v /tmp:/backup alpine \
  cp /backup/warmbox.db /data/warmbox.db
docker compose up -d

Use the same ENCRYPTION_KEY as on your Mac.


7. Day-to-day commands

cd /srv/docker-configs/warmbox

docker compose logs -f warmbox          # live logs
docker compose up -d --build              # rebuild after git pull
docker compose down                       # stop
docker compose restart warmbox            # restart app only

# Backup SQLite
docker compose exec warmbox sh -c 'cp /data/warmbox.db /data/warmbox-$(date +%F).db'

Troubleshooting

port 3000 already allocated

Your docker-compose.yml must not have a ports: section under warmbox:

grep ports docker-compose.yml
# should return nothing (or only comments)

Warmbox uses port 3000 inside the container only. homepage on host 0.0.0.0:3000 is unrelated.

NPM 502 Bad Gateway

  1. Warmbox running and healthy: docker compose ps
  2. On npm_network: docker inspect warmbox --format '{{json .NetworkSettings.Networks}}'
  3. NPM forward host is warmbox (not localhost, not 127.0.0.1)
  4. NPM forward port is 3000
  5. Logs: docker compose logs warmbox

network npm_network not found

Create it or fix the name to match NPM:

docker network ls
# edit docker-compose.yml → networks.default.name

Login fails

  • API_KEY in .env must match what you type
  • Restart after .env change: docker compose up -d --force-recreate

Container unhealthy

docker compose logs warmbox

Common causes: missing ENCRYPTION_KEY, bad DATABASE_URL, migration error.


Why only npm_network?

NPM and Warmbox must share a Docker network so NPM can resolve the hostname warmbox. A separate warmbox_internal network is unnecessary for this setup — one external network is enough.

See also self-host-hardening.md.


CI/CD (Woodpecker)

Push to main on Forgejo → automatic deploy. See deploy-ci-cd.md.