payment-gateway.app Docs
Getting Started

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, and openssl installed
  • At least 4 CPU cores and 8 GB RAM
  • DNS control for the hostnames below
  • Registry access credentials from the license dashboard
  • Inbound ports 80 and 443 open
  • Outbound HTTPS to payment-gateway.app, registry.payment-gateway.app, and registry-auth.payment-gateway.app

Required Domains

Point these hostnames to your server's public IP:

PurposeVariableExample
Admin frontendADMIN_FRONTEND_DOMAINadmin.example.com
Admin APIADMIN_BACKEND_DOMAINapi.example.com
Checkout frontendMAIN_FRONTEND_DOMAINpay.example.com
Webhook endpointMAIN_BACKEND_DOMAINwebhook.example.com
Database adminMONGO_EXPRESS_DOMAINdb.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/metadata

Keep 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.sh

On 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:

  1. Domains — replace every occurrence of yourdomain.com with your actual domain. The template uses matching subdomains across the MPG_*, REACT_APP_*, and Caddy *_DOMAIN variables, so a global find-and-replace works.

  2. ACME email — set CADDY_EMAIL to a valid address for Let's Encrypt certificate registration.

  3. Registry access — paste the REGISTRY_ACCESS_ID and REGISTRY_ACCESS_SECRET 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-compose

Then set MONGO_TLS_ENABLED=true in .env.

Step 5: Deploy the Stack

./deploy.sh

The 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-backend

Confirm 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 stable

The 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-compose

The 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

On this page