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
- Go to
dashboard.stripe.com→ sign in - Top-left dropdown → confirm you're in Test mode (toggle top-right) to start
- Left sidebar → Developers → API keys
- Copy Publishable key (
pk_test_...) →STRIPE_PUBLISHABLE_KEY - Click Reveal on Secret key (
sk_test_...) →STRIPE_SECRET_KEY - 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)
- Open
http://your-vps-ip:8090/_/in your browser - Create your admin email and password — one-time setup
- Create collections from
pb_hooks/SCHEMA.md:- Extend the built-in
userscollection withcredits_balance,free_used,fingerprint_id - Create
conversions,transactions,purchasescollections as documented
- Extend the built-in
- Go to Settings → API keys → create a new key → copy it
- Add to
.envon 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
- Stripe dashboard → Developers → Webhooks → Add endpoint
- URL:
https://yourdomain.com/api/payments/webhook - Event:
payment_intent.succeeded - Click Add endpoint → copy the Signing secret (
whsec_...) - 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:
- Settings → Git providers → connect your GitHub account
- 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
- Dokploy dashboard → Projects → Create project
- Name it
idconvert
Step 4 — Add a Compose service
- Inside the project → Create service → Compose
- Name it
idconvert-stack - Source:
- If using GitHub: select your repository and branch (
main) - If using local path: select Filesystem and enter
/opt/idconvert
- If using GitHub: select your repository and branch (
- Docker Compose path:
docker-compose.yml - 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
- Service → Deployments tab → Deploy
- Dokploy pulls the code, builds all images, and starts the stack
- Watch the build log in real time in the dashboard
Step 7 — Set up PocketBase (first boot only)
- Dokploy exposes the PocketBase port — find it in the service's Ports tab
or access it at
http://your-vps-ip:8090/_/ - Create your PocketBase admin email and password
- Create collections from
pb_hooks/SCHEMA.md - Go to Settings → API keys → create a key → copy it
- Go back to Dokploy → service → Environment → add
POCKETBASE_ADMIN_TOKEN=... - 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.
- Service → Domains tab
- Add your domain:
yourdomain.com - Select which container port maps to it:
yourdomain.com→ port3000(frontend)api.yourdomain.com→ port8000(backend)
- Toggle HTTPS on — Dokploy issues the SSL certificate automatically
- In your DNS provider, add an A record:
yourdomain.com → your-vps-ip
Step 9 — Set up Stripe webhook
- Stripe dashboard → Developers → Webhooks → Add endpoint
- URL:
https://yourdomain.com/api/payments/webhook(orhttps://api.yourdomain.com/api/payments/webhookif using a subdomain) - Event:
payment_intent.succeeded - Copy the Signing secret (
whsec_...) - Dokploy → service → Environment → add
STRIPE_WEBHOOK_SECRET=whsec_... - 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.