Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions deploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ curl -fsS http://127.0.0.1:13001/ready
- If you already run host-level Nginx/Caddy for TLS, proxy `https://your-domain` to `http://127.0.0.1:${TRACKING_CONSOLE_PORT}`.
- `tracking-api` may still need a public endpoint for ingestion (`POST /track`) depending on your architecture.
- If GHCR images are private, `docker login ghcr.io` is required on the VPS.
- Internal API port is always `3000` inside container. External host port is `${TRACKING_API_PORT:-13001}`.
- For single-domain production on Nginx Proxy Manager, see `deploy/vps/README.md` and `deploy/vps/npm-one-domain-walk-cwish-me.md`.

## GHCR image naming from CI

Expand Down
2 changes: 1 addition & 1 deletion deploy/app/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ services:
- .env
environment:
NODE_ENV: production
PORT: ${TRACKING_API_PORT:-13001}
PORT: 3000
ports:
- "${TRACKING_API_PORT:-13001}:3000"
healthcheck:
Expand Down
40 changes: 40 additions & 0 deletions deploy/vps/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ Edit `.env.app` with production values:
- `ADMIN_API_TOKEN=...`
- `TRACKING_API_SECRET=...`

Recommended production values:

- `NODE_ENV=production`
- `TRACKING_API_AUTH_MODE=shared-secret`
- `REDIS_URL=redis://tracking-redis:6379/0` (container-to-container, do not use `localhost`)
- `TRACKING_CORS_ALLOW_ORIGINS=https://staging.prankbook.com,https://prankbook.com,https://walk.cwish.me`

## Run containers

```bash
Expand All @@ -51,6 +58,39 @@ curl -fsS http://127.0.0.1:13001/health
curl -fsS http://127.0.0.1:13001/ready
```

## Port map (current standard)

- `tracking-console` container: `80` -> host `${TRACKING_CONSOLE_PORT}` (default `18081`)
- `tracking-api` container: `3000` -> host `${TRACKING_API_PORT}` (default `13001`)
- `redis` container: `6379` -> host `${REDIS_PORT}` (default `6379`)

## Single-domain setup (Nginx Proxy Manager)

When using one public domain (example: `walk.cwish.me`) for both console and API:

1. Proxy Host Details:
- Domain: `walk.cwish.me`
- Forward Hostname/IP: `77.42.71.202`
- Forward Port: `18081`
2. SSL tab:
- Enable certificate for `walk.cwish.me`
- Force SSL enabled
3. Custom Nginx config (gear icon):
- copy from `deploy/vps/npm-one-domain-walk-cwish-me.md`

Why this is needed:

- `/api/*` admin routes need `ADMIN_API_TOKEN` header. Nginx normally rejects underscore headers unless configured.
- `/track` needs preflight `OPTIONS` and must route to API (`13001`) instead of console (`18081`).

Quick validation:

```bash
curl -i https://walk.cwish.me/health
curl -i https://walk.cwish.me/ready
curl -i "https://walk.cwish.me/api/admin/events?limit=1&offset=0" -H "ADMIN_API_TOKEN: <ADMIN_API_TOKEN>"
```

## Host Nginx

1. Copy `nginx.tracking-base.conf.example` to `/etc/nginx/sites-available/tracking-base.conf`
Expand Down
62 changes: 62 additions & 0 deletions deploy/vps/npm-one-domain-walk-cwish-me.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Nginx Proxy Manager: One-Domain Config (`walk.cwish.me`)

Use this in Proxy Host -> Edit -> gear icon -> `Custom Nginx Configuration`.

Important:

- Replace `77.42.71.202` if VPS IP changes.
- Replace `<TRACKING_API_SECRET>` with your real value.
- Do not commit real secrets.

```nginx
underscores_in_headers on;
ignore_invalid_headers off;

location /api/ {
proxy_pass http://77.42.71.202:13001/;
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 ADMIN_API_TOKEN $http_admin_api_token;
}

location = /api/track {
proxy_pass http://77.42.71.202:13001/track;
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 X-Tracking-Secret <TRACKING_API_SECRET>;
}

location = /track {
proxy_pass http://77.42.71.202:13001/track;
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;
}
```

## Why these blocks exist

- `underscores_in_headers on;` and `ignore_invalid_headers off;` allow forwarding `ADMIN_API_TOKEN`.
- `/api/` forwards dashboard admin API calls to tracking-api.
- `/api/track` forwards frontend `/api/track` calls and injects `x-tracking-secret`.
- `/track` forwards direct SDK/browser calls and preserves CORS preflight behavior.

## Validation commands

```bash
curl -i -X OPTIONS https://walk.cwish.me/track \
-H 'Origin: https://staging.prankbook.com' \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: content-type,x-tracking-secret'

curl -i "https://walk.cwish.me/api/admin/events?limit=1&offset=0" \
-H "ADMIN_API_TOKEN: <ADMIN_API_TOKEN>"
```
2 changes: 2 additions & 0 deletions docs/07-ops/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@

- [Configuration](configuration.md)
- [Runbooks](runbooks.md)
- [Deploy folder guide](../../deploy/README.md)
- [VPS upload-only guide](../../deploy/vps/README.md)
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ The layout is designed so humans and coding agents can navigate the repository w
- [`06-frontend/`](06-frontend/tracking-sdk.md): browser and backend client integration
- [`06-frontend/frontend-layout-architecture.md`](06-frontend/frontend-layout-architecture.md): canonical frontend layering rules
- [`07-ops/`](07-ops/deployment.md): deployment and operations
- [`../deploy/vps/README.md`](../deploy/vps/README.md): VPS deployment checklist (compose + proxy)
- [`07-ops/queue-worker-go-live-checklist.md`](07-ops/queue-worker-go-live-checklist.md): step-by-step queue/worker go-live checklist
- [`08-security/`](08-security/privacy-and-gdpr.md): privacy and security controls
- [`09-testing/`](09-testing/test-strategy.md): quality gates
Expand Down
Loading