Preparing the API for Production
Preparing the API for Production
~16 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026
EVERY secret that served as a placeholder in THIS course (MERCURE_JWT_SECRET, the JWT key pair, database credentials) MUST be REPLACED before a PRODUCTION deployment.
Environment variables for production
APP_ENV=prod
APP_DEBUG=0
APP_SECRET=
DATABASE_URL="postgresql://prod_user:REAL_PASSWORD@db-prod-host:5432/aufgaben_manager"
MERCURE_JWT_SECRET=
CORS_ALLOW_ORIGIN='^https://aufgaben-manager\.example\.com$' Achtung: CORS_ALLOW_ORIGIN must NEVER be a wildcard pattern in production like in local development (chapter 8) – ONLY the ACTUAL domain of the frontend belongs in this regular expression.
Generating JWT keys for production
php bin/console lexik:jwt:generate-keypair --overwrite
# Keep the generated files (config/jwt/private.pem, public.pem) SECURELY
# outside version control, e.g. via secrets managementBuilding the production container
The api-platform distribution ALREADY ships a compose.prod.yaml – UNLIKE the local compose.yaml (chapter 2), it builds an OPTIMIZED, production-ready FrankenPHP image WITHOUT development tools (Xdebug, Composer dev dependencies).
docker compose -f compose.yaml -f compose.prod.yaml build
docker compose -f compose.yaml -f compose.prod.yaml up -dMigrations and cache in production
docker compose exec php bin/console doctrine:migrations:migrate --no-interaction
docker compose exec php bin/console cache:warmupAchtung: doctrine:fixtures:load from chapter 15 NEVER belongs in production – the test data (45 sample projects) would OVERWRITE REAL user data. Migrations ALONE are sufficient for a PRODUCTION database.
HTTPS in production
EXACTLY as the local, SELF-SIGNED certificate (chapter 2) is only SUITABLE for development, PRODUCTION needs a REAL certificate – Caddy/FrankenPHP (ALREADY part of the distribution) can obtain Let's Encrypt certificates AUTOMATICALLY, once a REAL domain is configured.
Tipp: A .env.prod.local (analogous to .env.local from chapter 8) is the USUAL place for the ACTUAL production secrets, OUTSIDE version control – Symfony's secrets vault (bin/console secrets:set) is the EVEN SAFER alternative for SENSITIVE values.