Production Deployment & Infrastructure Guide
This document details the containerization architecture, production hosting on Render, Cloudflare R2 / AWS S3 storage, and operational runbooks for Eniceberny Bakery and Culinary Hub.
1. Production Architecture Overview
The production infrastructure is orchestrated via Docker containers running on Render PaaS backed by managed PostgreSQL:
graph TD
subgraph Public Web Traffic
DNS[Cloudflare / Custom Domain enicebakerygh.com] -->|HTTPS 443| LB[Render Load Balancer]
end
subgraph Container Services
LB --> Web[eniceberny-web: Apache + PHP 8.4]
Web -->|Dispatch Async Jobs| Queue[(Redis / Database Queue)]
Queue --> Worker[eniceberny-worker: php artisan queue:work]
Cron[eniceberny-scheduler: php artisan schedule:run] --> Web
end
subgraph Data & Storage
Web --> DB[(Managed PostgreSQL 16)]
Worker --> DB
Web --> Storage[Cloudflare R2 / S3 Media Bucket]
end
2. Multi-Stage Dockerfile Architecture
The production image is built using a clean two-stage Dockerfile to minimize attack surface and image size:
Stage 1 — Node 20 Builder
- Base image:
node:20-alpine. - Copies
package.json,package-lock.json, and installs production dependencies. - Compiles frontend assets with Vite:
npm run build. - Outputs optimized bundles to
public/build/.
Stage 2 — PHP 8.4 Apache Runtime
- Base image:
php:8.4-apache. - Installs system libraries and compiled extensions:
pdo,pdo_pgsql,pgsql,mbstring,exif,pcntl,bcmath,gd(with FreeType and JPEG support),zip,opcache. - Configures Apache
mod_rewrite, sets document root to/var/www/html/public, and enforcesAllowOverride All. - Injects Composer, installs production PHP dependencies (
composer install --no-dev --optimize-autoloader). - Copies compiled assets from Stage 1.
- Implements healthcheck probe targeting
/up.
3. Infrastructure as Code (render.yaml)
The platform includes an automated Render blueprint (render.yaml) defining all components:
| Service Name | Type | Environment | Plan | Key Responsibilities |
|---|---|---|---|---|
eniceberny-web |
Web Service | Docker | Starter / Standard | Serves HTTP/HTTPS storefront, admin portal, POS counter, and API endpoints. Health check at /up. |
eniceberny-worker |
Background Worker | Docker | Starter | Processes asynchronous email dispatches (OrderPlacedReceiptMail, VerifyEmailOtpMail), PDF generation jobs. |
eniceberny-scheduler |
Cron Job | Docker | Free / Starter | Executes php artisan schedule:run every minute to process inventory alerts and cache purges. |
eniceberny-db |
Managed Database | PostgreSQL 16 | Starter | Relational storage with automated daily snapshots and encrypted storage. |
4. Environment Variables Directory
The following environment variables must be configured in production:
| Variable | Description | Recommended Setting |
|---|---|---|
APP_ENV |
Application environment mode | production |
APP_DEBUG |
Debug stack traces | false (Never set true in production) |
APP_KEY |
32-character AES encryption key | Auto-generated via php artisan key:generate |
APP_URL |
Canonical application domain | https://enicebakerygh.com |
DB_CONNECTION |
Database driver | pgsql |
DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD |
PostgreSQL credentials | Injected automatically from eniceberny-db |
MEDIA_DISK |
Storage driver for user uploads | s3 (or public if using persistent disk) |
AWS_ENDPOINT |
Cloudflare R2 / S3 endpoint | https://<account-id>.r2.cloudflarestorage.com |
AWS_BUCKET |
Storage bucket name | eniceberny-media-prod |
PAYSTACK_PUBLIC_KEY |
Paystack public key | pk_live_... |
PAYSTACK_SECRET_KEY |
Paystack secret key | sk_live_... |
MAIL_MAILER |
Email driver | smtp |
MAIL_HOST, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWORD |
SMTP credentials | Configured via SendGrid, Mailgun, or Postmark |
5. Post-Deployment Runbook
On initial launch or subsequent database schema updates:
- Execute Database Migrations:
php artisan migrate --force - Seed Default Catalog & Operational Sample Data:
php artisan db:seed --class=DatabaseSeeder --force - Verify Super Admin Access:
php artisan auth:ensure-admin - Optimize Caches:
php artisan config:cache php artisan route:cache php artisan view:cache - Verify Public Probes:
- Check
GET https://enicebakerygh.com/upreturns HTTP 200 OK. - Verify XML sitemap at
GET https://enicebakerygh.com/sitemap.xml. - Verify robots rules at
GET https://enicebakerygh.com/robots.txt.
- Check
6. Worker Daemon & Cron Resilience on Render
To prevent worker crashes, deploy timeouts, and memory exhaustion:
6.1 Database Polling Check (wait_for_db)
The container entrypoint (docker/entrypoint.sh) executes a lightweight PDO polling routine using getenv() before starting web, worker, or cron services. It checks PostgreSQL connectivity up to 30 times with 2-second intervals, ensuring worker or web processes never crash if the managed database is booting.
6.2 Self-Healing Worker Loop
The queue worker runs inside a self-healing daemon loop with generous 24-hour runtime and 512MB memory headroom:
php -d memory_limit=512M artisan queue:work --sleep=3 --tries=3 --max-time=86400 --memory=512 --timeout=300
--max-time=86400: Cycles worker process once every 24 hours (86,400s) to clear PHP memory leaks without triggering premature "Maximum run time exceeded" restart events.--memory=512&-d memory_limit=512M: Grants full access to available container memory allocation.--timeout=300: Allows up to 300 seconds (5 minutes) for multi-step jobs such as report generation, PDF rendering, or slow payment webhook dispatches.- Restart Loop: When a cycle finishes with exit code 0 or an unhandled exception occurs, the container entrypoint sleeps 3 seconds and automatically restarts the worker without terminating the container.
- Signal Trapping: Traps
SIGTERMandSIGINTto exit cleanly during Render deployments.
6.3 Automated Production Cron Schedules
The eniceberny-scheduler cron service triggers php -d memory_limit=512M -d max_execution_time=300 artisan schedule:run --no-interaction every minute to execute:
queue:prune-failed --hours=168(Daily): Removes failed jobs older than 7 days (protected bywithoutOverlapping(60)).queue:prune-batches --hours=48(Daily): Removes completed job batches older than 48 hours (protected bywithoutOverlapping(60)).seo:ping(Daily at 04:00 UTC): Pings search engines with updated sitemaps with 15s timeout and resilient error handling.withoutOverlapping(60): Automatically releases mutex cache locks after 60 minutes if an unexpected exit occurs.
7. Automated CI / CD Pipeline (.github/workflows/ci.yml)
Every push and pull request to main triggers the GitHub Actions pipeline:
- PHP 8.4 Setup: Configures PHP with all required extensions (
mbstring,xml,ctype,iconv,intl,pdo,pdo_sqlite,sqlite3,pdo_pgsql,bcmath,gd,zip). - Node 20 Setup: Installs npm dependencies and compiles production assets with Vite (
npm run build). - Application Environment: Generates application key, initializes SQLite test database, and validates routing.
- Verification Gates:
php artisan schedule:list(Validates scheduled tasks and console command registrations)php artisan route:list --except-vendor(Validates zero routing syntax errors)php artisan platform:test-all --quick --report(Validates all 12 operational subsystems across 48 automated checks)php artisan test --colors=always(Runs complete 116-test automated test suite with 539 assertions)
- Render Deploy Hook: Dispatches webhook to Render if
RENDER_DEPLOY_HOOK_URLsecret is configured, or relies on Render's native GitHub auto-deploy onmain.
8. Pre-Flight Platform Verification Scripts
Before deploying new releases or promoting staging environments, operators can run automated verification runners that inspect the entire stack:
# Linux / macOS / Render Containers
bash scripts/test-all-features.sh [--quick] [--skip-build]
# Windows PowerShell
powershell -ExecutionPolicy Bypass -File .\scripts\test-all-features.ps1 [-Quick] [-SkipBuild]
These scripts execute a 6-phase sequence:
- Runtime environment and dependencies check (PHP, Node, Composer)
- Production frontend asset compilation (
npm run build) - Database migrations and schema baseline check (
php artisan migrate --force) - Full PHPUnit test suite execution (116 tests, 539 assertions)
- Comprehensive in-app feature audit across all 12 modules (
php artisan platform:test-all) - Route catalog and cron scheduler integrity validation