Deployment

Production deployment with Dokploy and Docker

Deployment

This guide covers deploying the backend with Dokploy. The CI/CD pipeline builds a production Docker image and triggers deployment via a webhook.

Prerequisites

  • A server with Dokploy installed
  • A domain name pointed to your server
  • The CI/CD pipeline configured (see CI/CD)

Step-by-Step Setup

1. Create the Dokploy Application

In the Dokploy dashboard:

  1. Create a new application
  2. Set the source to Docker (from GitHub Container Registry)
  3. Configure the image: ghcr.io/{owner}/{repo}:main
  4. Set up a domain with HTTPS

2. Create the Database

Use the built-in Dokploy CLI command:

docker compose exec php bin/console app:dokploy

This interactive command helps you create a PostgreSQL database service and configure deployment settings.

3. Configure Environment Variables

Set these in Dokploy application settings:

APP_ENV=prod
APP_SECRET=<random-string>
DATABASE_URL=postgresql://user:password@host:5432/dbname
JWT_PASSPHRASE=<your-passphrase>

STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_SUCCESS_URL=https://yourdomain.com/payment/success
STRIPE_CANCEL_URL=https://yourdomain.com/payment/cancel

EMAIL_SENDER_EMAIL=noreply@yourdomain.com
EMAIL_SENDER_NAME=Your App Name
BREVO_API_KEY=xkeysib-...

EMAIL_VALIDATION_REDIRECT_URL=https://yourdomain.com/auth/email-verified
FRONTEND_RESET_PASSWORD_URL=https://yourdomain.com/auth/reset-password

FIREBASE_PROJECT_ID=your-firebase-project-id
CORS_ALLOW_ORIGIN=^https://yourdomain\.com$

4. Mount JWT Certificates

JWT keys need to persist between deployments. Mount them via Dokploy:

  1. Go to your service → AdvancedVolumes
  2. Mount private.pem to /app/config/jwt/private.pem
  3. Mount public.pem to /app/config/jwt/public.pem

5. Set Up the Deployment Webhook

  1. In Dokploy → application → Settings → Webhooks, copy the webhook URL
  2. Add it as a GitHub secret: DOKPLOY_WEBHOOK_URL

6. Initial Setup Commands

After the first deployment, run inside the production container:

bin/console doctrine:migrations:migrate --no-interaction
bin/console app:stripe:sync-plans
bin/console app:user:promote-admin admin@yourdomain.com

7. Configure Stripe Webhook (Production)

In the Stripe Dashboard → Developers → Webhooks:

  1. Add endpoint: https://yourdomain.com/api/v1/webhooks/stripe
  2. Select events: checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.payment_failed, invoice.paid
  3. Copy the signing secret to STRIPE_WEBHOOK_SECRET