idconvert/deployment_guide.md

12 KiB

IDconvert Deployment Guide

Two deployment paths are covered:

  • Path A — Manual: rsync code to a VPS, run Docker Compose directly
  • Path B — Dokploy: self-hosted PaaS UI on the VPS, deploy via GitHub or rsync

Prerequisites (both paths)

Stripe API keys

  1. Go to dashboard.stripe.com → sign in
  2. Top-left dropdown → confirm you're in Test mode (toggle top-right) to start
  3. Left sidebar → DevelopersAPI keys
  4. Copy Publishable key (pk_test_...) → STRIPE_PUBLISHABLE_KEY
  5. Click Reveal on Secret key (sk_test_...) → STRIPE_SECRET_KEY
  6. Webhook secret — leave blank until your server is live with a domain (Step 6 in each path)

Create your local .env file

cp .env.example .env

Fill in .env:

STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_WEBHOOK_SECRET=          # fill in after server is live

# MinIO credentials — you choose these, they are self-set
AWS_ACCESS_KEY_ID=choose_a_username
AWS_SECRET_ACCESS_KEY=choose_a_strong_password

POCKETBASE_ADMIN_TOKEN=         # fill in after first boot (Step 5 in each path)

# Leave these as-is — correct for docker-compose networking
POCKETBASE_URL=http://pocketbase:8090
S3_ENDPOINT_URL=http://minio:9000
S3_BUCKET=idconvert
S3_REGION=us-east-1
FRONTEND_ORIGIN=https://yourdomain.com
NUXT_PUBLIC_API_BASE=https://yourdomain.com
NUXT_PUBLIC_POCKETBASE_URL=https://yourdomain.com:8090
NUXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...


Path A — Manual rsync + Docker Compose

Step 1 — Transfer code to your VPS

rsync -avz --progress \
  --exclude '.git' \
  --exclude 'node_modules' \
  --exclude 'frontend/.nuxt' \
  --exclude 'frontend/.output' \
  --exclude 'backend/venv' \
  --exclude 'backend/__pycache__' \
  --exclude '**/*.pyc' \
  "/Users/JasonJFraser/Desktop/desktop files/apps/idconvert/" \
  user@your-vps-ip:/opt/idconvert/

Copy your .env separately (never commit this to git):

scp "/Users/JasonJFraser/Desktop/desktop files/apps/idconvert/.env" \
    user@your-vps-ip:/opt/idconvert/.env

Step 2 — Install Docker on the VPS

SSH in:

ssh user@your-vps-ip

Install Docker:

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
exit  # log out so the group change takes effect

SSH back in, then verify:

docker --version
docker compose version

Step 3 — Build and start

cd /opt/idconvert
docker compose --env-file .env up -d --build
docker compose logs -f  # watch for errors until all services show healthy

Step 4 — Set up PocketBase (first boot only)

  1. Open http://your-vps-ip:8090/_/ in your browser
  2. Create your admin email and password — one-time setup
  3. Create collections from pb_hooks/SCHEMA.md:
    • Extend the built-in users collection with credits_balance, free_used, fingerprint_id
    • Create conversions, transactions, purchases collections as documented
  4. Go to Settings → API keys → create a new key → copy it
  5. Add to .env on the VPS: POCKETBASE_ADMIN_TOKEN=...
# Restart backend to pick up the new token
cd /opt/idconvert
docker compose restart backend

Step 5 — Point your domain at the VPS

In your DNS provider, create an A record:

yourdomain.com  →  your-vps-ip

Then set up a reverse proxy (nginx or Caddy) to route traffic to the containers. Caddy is the simplest option — it handles SSL automatically:

sudo apt install -y caddy

/etc/caddy/Caddyfile:

yourdomain.com {
    reverse_proxy localhost:3000  # frontend
}

api.yourdomain.com {
    reverse_proxy localhost:8000  # backend
}

Or use a single domain with path routing:

yourdomain.com {
    handle /api/* {
        reverse_proxy localhost:8000
    }
    handle /payments/* {
        reverse_proxy localhost:8000
    }
    handle {
        reverse_proxy localhost:3000
    }
}
sudo systemctl reload caddy

Step 6 — Set up Stripe webhook

  1. Stripe dashboard → DevelopersWebhooksAdd endpoint
  2. URL: https://yourdomain.com/api/payments/webhook
  3. Event: payment_intent.succeeded
  4. Click Add endpoint → copy the Signing secret (whsec_...)
  5. Add to .env: STRIPE_WEBHOOK_SECRET=whsec_...
cd /opt/idconvert
docker compose restart backend

Re-deploying after a code change

# 1. Push updated code from your Mac
rsync -avz --progress \
  --exclude '.git' \
  --exclude 'node_modules' \
  --exclude 'frontend/.nuxt' \
  --exclude 'frontend/.output' \
  --exclude 'backend/venv' \
  --exclude 'backend/__pycache__' \
  --exclude '**/*.pyc' \
  "/Users/JasonJFraser/Desktop/desktop files/apps/idconvert/" \
  user@your-vps-ip:/opt/idconvert/

# 2. Rebuild and restart on the VPS
ssh user@your-vps-ip "cd /opt/idconvert && docker compose up -d --build"

Useful management commands

docker compose ps                        # list containers and health status
docker compose logs -f backend           # tail backend logs
docker compose logs -f frontend          # tail frontend logs
docker compose restart backend           # restart one service
docker compose down                      # stop everything (data preserved)
docker compose down -v                   # stop and wipe all volumes (destructive)
docker compose exec backend bash         # shell into the backend container

First-boot order summary

1. docker compose up --build
2. Visit :8090/_/ → create PocketBase admin
3. Create collections (pb_hooks/SCHEMA.md)
4. Generate PocketBase API key → add to .env → restart backend
5. Point domain at VPS → configure reverse proxy
6. Set up Stripe webhook → add whsec to .env → restart backend
7. Switch Stripe from test mode to live → swap pk/sk in .env → restart backend


Path B — Dokploy (Recommended for easier ongoing management)

Dokploy is a self-hosted PaaS that runs on your VPS and gives you a web UI for deployments, environment variables, logs, and SSL. It reads your docker-compose.yml directly.

Step 1 — Install Dokploy on your VPS

SSH into your VPS and run the installer:

ssh user@your-vps-ip

curl -sSL https://dokploy.com/install.sh | sh

The installer:

  • Installs Docker if not already present
  • Pulls and starts Dokploy
  • Prints the URL to access the dashboard (typically http://your-vps-ip:3000)

Open that URL in your browser and create your Dokploy admin account.

Note: Dokploy itself runs on port 3000. Your IDconvert frontend will be assigned a different port or subdomain by Dokploy — it handles this for you.

Step 2 — Connect your code to Dokploy

Option A — Via GitHub (recommended for automatic deploys):

First, initialise git locally if you haven't already:

cd "/Users/JasonJFraser/Desktop/desktop files/apps/idconvert"
git init
git add .
git commit -m "Initial commit"

Push to a new private GitHub repository (create one at github.com first):

git remote add origin git@github.com:youruser/idconvert.git
git push -u origin main

In Dokploy dashboard:

  1. Settings → Git providers → connect your GitHub account
  2. This allows Dokploy to pull from your private repo

Option B — Via rsync (if you prefer not to use GitHub):

Transfer the code to the VPS first (same rsync command as Path A Step 1), placing it at /opt/idconvert/. Then in Dokploy, point to that local path.

Step 3 — Create a project in Dokploy

  1. Dokploy dashboard → ProjectsCreate project
  2. Name it idconvert

Step 4 — Add a Compose service

  1. Inside the project → Create serviceCompose
  2. Name it idconvert-stack
  3. Source:
    • If using GitHub: select your repository and branch (main)
    • If using local path: select Filesystem and enter /opt/idconvert
  4. Docker Compose path: docker-compose.yml
  5. Click Save

Step 5 — Set environment variables in Dokploy

In the service → Environment tab, paste your entire .env file contents.

Dokploy stores these securely and injects them at deploy time — you do not need a .env file on the server.

Key variables to set:

STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_WEBHOOK_SECRET=          # add after Step 8
AWS_ACCESS_KEY_ID=choose_a_username
AWS_SECRET_ACCESS_KEY=choose_a_strong_password
POCKETBASE_ADMIN_TOKEN=         # add after Step 7
POCKETBASE_URL=http://pocketbase:8090
S3_ENDPOINT_URL=http://minio:9000
S3_BUCKET=idconvert
S3_REGION=us-east-1
FRONTEND_ORIGIN=https://yourdomain.com
NUXT_PUBLIC_API_BASE=https://yourdomain.com
NUXT_PUBLIC_POCKETBASE_URL=https://yourdomain.com:8090
NUXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...

Step 6 — Deploy

  1. Service → Deployments tab → Deploy
  2. Dokploy pulls the code, builds all images, and starts the stack
  3. Watch the build log in real time in the dashboard

Step 7 — Set up PocketBase (first boot only)

  1. Dokploy exposes the PocketBase port — find it in the service's Ports tab or access it at http://your-vps-ip:8090/_/
  2. Create your PocketBase admin email and password
  3. Create collections from pb_hooks/SCHEMA.md
  4. Go to Settings → API keys → create a key → copy it
  5. Go back to Dokploy → service → Environment → add POCKETBASE_ADMIN_TOKEN=...
  6. Redeploy (Dokploy → Deploy button) to apply the new env var

Step 8 — Configure domain and SSL in Dokploy

Dokploy handles SSL (Let's Encrypt) automatically.

  1. Service → Domains tab
  2. Add your domain: yourdomain.com
  3. Select which container port maps to it:
    • yourdomain.com → port 3000 (frontend)
    • api.yourdomain.com → port 8000 (backend)
  4. Toggle HTTPS on — Dokploy issues the SSL certificate automatically
  5. In your DNS provider, add an A record: yourdomain.com → your-vps-ip

Step 9 — Set up Stripe webhook

  1. Stripe dashboard → DevelopersWebhooksAdd endpoint
  2. URL: https://yourdomain.com/api/payments/webhook (or https://api.yourdomain.com/api/payments/webhook if using a subdomain)
  3. Event: payment_intent.succeeded
  4. Copy the Signing secret (whsec_...)
  5. Dokploy → service → Environment → add STRIPE_WEBHOOK_SECRET=whsec_...
  6. Click Deploy to apply

Re-deploying after a code change

If using GitHub:

git add .
git commit -m "your change"
git push

Then in Dokploy → Deploy (or enable Auto deploy on push in the service settings).

If using rsync:

rsync -avz --progress \
  --exclude '.git' \
  --exclude 'node_modules' \
  --exclude 'frontend/.nuxt' \
  --exclude 'frontend/.output' \
  --exclude 'backend/venv' \
  --exclude 'backend/__pycache__' \
  --exclude '**/*.pyc' \
  "/Users/JasonJFraser/Desktop/desktop files/apps/idconvert/" \
  user@your-vps-ip:/opt/idconvert/

Then in Dokploy → Deploy.

First-boot order summary (Dokploy)

1. Install Dokploy on VPS (curl installer)
2. Create project → add Compose service → set env vars → Deploy
3. Visit :8090/_/ → create PocketBase admin
4. Create collections (pb_hooks/SCHEMA.md)
5. Generate PocketBase API key → add to Dokploy env → Redeploy
6. Add domain in Dokploy → point DNS → SSL issued automatically
7. Set up Stripe webhook → add whsec to Dokploy env → Redeploy
8. Switch Stripe test → live keys in Dokploy env → Redeploy

Path A vs Path B — when to use each

Path A (rsync + manual Docker) Path B (Dokploy)
Setup time Faster initially Slightly more upfront
Ongoing deploys Manual rsync + SSH commands One click (or git push)
SSL Manual (Caddy/nginx) Automatic (built into Dokploy)
Logs SSH + docker compose logs Web UI dashboard
Env var changes Edit .env on server + restart Dokploy UI + Redeploy
Best for One-off / simple setups Ongoing product with regular deploys

For a product with paying customers and regular updates, Path B (Dokploy) is recommended.