Table of Contents#
Deployment Topology#
Dual-Role Dockerfile#
One root Dockerfile, three stages:1.
frontend stage — nginx:1.27-alpine; copies fullstack/Frontend/ into the web root plus its nginx.conf and entrypoint.sh. Entrypoint can rewrite the API base URL into served config at boot.
2.
vendor stage — php:8.5-fpm-alpine; installs composer deps with --no-dev --optimize-autoloader for layer caching.
3.
backend stage — php-fpm + nginx under supervisor (web + queue worker in one container), production php.ini, app overrides from fullstack/Backend/docker/php.ini, storage dirs provisioned and chowned to www-data. Final line FROM ${SERVICE_ROLE} selects the variant — Railway injects the per-service env var as a build arg.Extension notes baked into the image: gd/zip/bcmath/pdo_mysql/mbstring/exif/pcntl compiled; no ext-redis (predis is pure PHP; pecl redis fails on PHP 8.5).Railway Configuration#
{ "build": { "builder": "DOCKERFILE", "dockerfilePath": "Dockerfile", "buildEnvironment": "V3" },
"deploy": { "runtime": "V2", "numReplicas": 1, "sleepApplication": false,
"restartPolicyType": "ON_FAILURE", "restartPolicyMaxRetries": 10 } }
Single replica, never sleeps (webhooks must always land), restart-on-failure up to 10 attempts.Continuous Integration#
| Job | Steps |
|---|
| Code Style (Pint) | setup-php 8.2 → composer install → vendor/bin/pint --test |
| PHPUnit Tests | setup-php 8.2 (+ mbstring, pdo_sqlite, dom, gd, intl, zip) → env bootstrap (key:generate, jwt:secret) → php artisan test |
Tests run on SQLite — no database service container required.Health Checks & Runtime Guards#
| Surface | Mechanism |
|---|
| Frontend container | HEALTHCHECK: wget / every 30s (Dockerfile#L19-L20) |
| Backend container | HEALTHCHECK: curl /up expecting "status":"ok"; generous 60s start period for migrations warm-up |
| Supervisor | keeps php-fpm, nginx and queue worker alive inside backend image (supervisord.conf) |
| Scheduled expiry | console commands expire:stale-orders, expire:stale-subscriptions, expire:password-tokens intended for cron/scheduler |
Modified at 2026-08-25 22:41:45