Self-Hosted Installation
Docker Compose installation guide for the self-hosted Payment Gateway stack.
Self-Hosted Installation
Deploy the Payment Gateway stack on your own infrastructure with Docker Compose. This guide covers domains, registry access, first startup, license activation, and updates.
For rootless Linux deployment with systemd integration, see Podman Deployment after reading this page.
Prerequisites
- A Linux server or VM with a public IP address
- Docker Engine 24+ and Docker Compose v2
git,curl,jq, andopensslinstalled- At least 4 CPU cores and 8 GB RAM
- DNS control for the hostnames below
- Registry access credentials from the license dashboard
- Inbound ports
80and443open - Outbound HTTPS to
payment-gateway.app,registry.payment-gateway.app, andregistry-auth.payment-gateway.app
Required Domains
Point these hostnames to your server's public IP:
| Purpose | Variable | Example |
|---|---|---|
| Admin frontend | ADMIN_FRONTEND_DOMAIN | admin.example.com |
| Admin API | ADMIN_BACKEND_DOMAIN | api.example.com |
| Checkout frontend | MAIN_FRONTEND_DOMAIN | pay.example.com |
| Webhook endpoint | MAIN_BACKEND_DOMAIN | webhook.example.com |
| Database admin | MONGO_EXPRESS_DOMAIN | db.example.com |
All hostnames must resolve before the first deployment so Caddy can issue TLS certificates. Use any subdomain labels you prefer as long as they match your .env file. MONGO_EXPRESS_DOMAIN is optional — remove the route from your reverse proxy configuration if you do not need it.
Step 1: Retrieve Registry Access Credentials
Open the license dashboard, select the license you want to deploy, and reveal the registry access credentials. Copy the deploy environment snippet:
REGISTRY_HOST=registry.payment-gateway.app
REGISTRY_TOKEN_SERVICE_URL=https://registry-auth.payment-gateway.app/token
REGISTRY_ACCESS_ID=<from dashboard>
REGISTRY_ACCESS_SECRET=<from dashboard>
RELEASE_METADATA_URL=https://payment-gateway.app/api/releases/metadataKeep these values private. The deploy and update scripts exchange them for short-lived registry bearer tokens automatically.
Step 2: Clone and Initialize
git clone https://github.com/root-sector-ltd-and-co-kg/payment-gateway-deploy
cd payment-gateway-deploy/docker-compose
./deploy.shOn first run, deploy.sh creates .env from the template and exits so you can configure it before the actual deployment.
Step 3: Configure the Environment
Edit docker-compose/.env:
-
Domains — replace every occurrence of
yourdomain.comwith your actual domain. The template uses matching subdomains across theMPG_*,REACT_APP_*, and Caddy*_DOMAINvariables, so a global find-and-replace works. -
ACME email — set
CADDY_EMAILto a valid address for Let's Encrypt certificate registration. -
Registry access — paste the
REGISTRY_ACCESS_IDandREGISTRY_ACCESS_SECRETvalues from Step 1.
All other values in the template have working defaults.
Step 4: Optional — MongoDB TLS
For production TLS on MongoDB connections, generate the certificates before the first deploy so the auto-generated secrets include TLS connection strings:
cd .. && ./scripts/generate-mongo-certs.sh && cd docker-composeThen set MONGO_TLS_ENABLED=true in .env.
Step 5: Deploy the Stack
./deploy.shThe script auto-generates .env.secrets (cryptographic keys, passwords, database URIs) if it does not exist yet, authenticates to the registry, pulls images, and starts all services.
The first successful registry pull binds the host's public IP to the license access grant.
Step 6: Verify the Startup
docker compose ps
docker compose logs -f payment-gateway-admin-backendConfirm that https://<ADMIN_FRONTEND_DOMAIN> and https://<MAIN_FRONTEND_DOMAIN> load over HTTPS.
If the stack does not start cleanly, see Troubleshooting before attempting activation.
Step 7: Activate the License
Open the Admin frontend and navigate to System → Licensing. The admin backend creates the installation ID on first startup. Activate the license from the same host that pulled the images so the public IP binding and license activation match.
After activation, the license dashboard changes the license status from Unassigned to Assigned and shows the installation binding.
Step 8: Run Future Updates
From the repository root of payment-gateway-deploy (if you are still inside docker-compose/, run cd .. first):
./scripts/update.sh --engine docker-compose --channel stableThe updater fetches the entitled release manifest from the metadata endpoint using your registry access credentials, validates image digests, and redeploys changed components. If the metadata endpoint is unreachable, the update aborts — there is no local fallback.
To automate weekly updates with a systemd timer:
bash ./scripts/install-update-timer.sh --engine docker-composeThe script installs a user-level systemd timer that runs every Sunday at 03:00 UTC with up to 30 minutes of jitter. Set AUTO_UPDATE_ENABLED=false in the service environment to pause scheduled updates without removing the timer.
For the full maintenance workflow, see Updates & Automation.
After Installation
- Quick Start — create your first checkout flow
- Server Integration Checklist — hostnames, provider webhooks, API keys, checkout POST flow
- Provider Setup — connect Stripe, GoCardless, Wise, or wire transfer
- Testing — verify before moving live traffic
- Licensing — license state and runtime behavior