223 lines
5.3 KiB
Markdown
223 lines
5.3 KiB
Markdown
# 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`.
|
||
|
||
```text
|
||
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](https://nginxproxymanager.com/) 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 NPM’s network name:
|
||
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
cd /srv/docker-configs/warmbox # or your path
|
||
git pull # get latest docker-compose.yml
|
||
|
||
cp .env.example .env
|
||
nano .env
|
||
```
|
||
|
||
Required variables:
|
||
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
docker compose ps
|
||
docker compose logs -f warmbox
|
||
```
|
||
|
||
Warmbox should be **healthy**. Check it is on `npm_network`:
|
||
|
||
```bash
|
||
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):
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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)
|
||
|
||
```bash
|
||
# 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
|
||
|
||
```bash
|
||
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`:
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
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](./self-host-hardening.md).
|