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, image 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
- Deployment access credentials from your license dashboard
- Inbound ports
80and443open - Outbound HTTPS to the vendor endpoints shown in your deployment access snippet
Required Domains
Point these hostnames to your server's public IP:
| Purpose | Caddy / routing variable | Backend / frontend (MPG_*) | Example |
|---|---|---|---|
| Admin frontend | ADMIN_FRONTEND_DOMAIN | MPG_ADMIN_FRONTEND_DOMAIN | admin.example.com |
| Admin API | ADMIN_BACKEND_DOMAIN | MPG_ADMIN_BACKEND_DOMAIN | api.example.com |
| Checkout frontend | MAIN_FRONTEND_DOMAIN | MPG_MAIN_FRONTEND_DOMAIN | pay.example.com |
| Webhook endpoint | MAIN_BACKEND_DOMAIN | MPG_MAIN_BACKEND_DOMAIN | webhook.example.com |
| Database admin | MONGO_EXPRESS_DOMAIN | — | db.example.com |
The deploy template sets matching values for Caddy *_DOMAIN variables and MPG_* hostnames (plus REACT_APP_* where frontends need them). Replace yourdomain.com once; both sides stay in sync.
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 Deployment Access Credentials
Open the license dashboard, select the license you want to deploy, and reveal the deployment access credentials. Copy the deploy environment snippet. It contains the image source, metadata URL, and the access ID/secret used by the deploy scripts:
REGISTRY_HOST=<from dashboard>
REGISTRY_TOKEN_SERVICE_URL=<from dashboard>
REGISTRY_ACCESS_ID=<from dashboard>
REGISTRY_ACCESS_SECRET=<from dashboard>
RELEASE_METADATA_URL=<from dashboard>Keep these values private. The deploy and update scripts use them to fetch the entitled release metadata and pull the images allowed by the license.
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 mirrors each public hostname in Caddy*_DOMAINentries and the correspondingMPG_*/REACT_APP_*variables, so a global find-and-replace keeps routing and container config aligned. - ACME email - set
CADDY_EMAILto a valid address for Let's Encrypt certificate registration. - Image access - paste the access values 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 with the configured image source, pulls images, and starts all services.
The first successful image pull can bind the host's public IP to the license access grant, depending on your deployment policy.
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 deployment 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 deployment 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, Mollie, GoCardless, Wise, PayPal, or wire transfer
- Testing - verify before moving live traffic
- Licensing - license state and runtime behavior