feat(Production): Mount application code in PHP containers for live deployment

- Mount /home/deploy/michaelschiemer/current:/var/www/html:ro in php and queue-worker services
- This allows deployment via rsync without requiring Docker image rebuild
- Storage volume still mounted as writable overlay for runtime data
- Change default DB_DRIVER to 'pgsql' for PostgreSQL

Deployment Architecture:
- rsync deploys code to /home/deploy/michaelschiemer/releases/{timestamp}
- Atomic symlink switch to /home/deploy/michaelschiemer/current
- PHP containers mount current/ for immediate code updates
- No rebuild needed - code changes are live after symlink switch

Benefits:
- Faster deployments (no Docker rebuild)
- Code changes reflected immediately
- Zero-downtime releases
- Easy rollback via symlink change
This commit is contained in:
2025-10-26 23:30:43 +01:00
parent 3b623e7afb
commit 799f74f00a
2 changed files with 18 additions and 12 deletions

View File

@@ -17,12 +17,17 @@ services:
# Production restart policy # Production restart policy
restart: always restart: always
# Override volumes - use Let's Encrypt certificates # Production port mappings for Let's Encrypt
ports:
- "80:80" # HTTP for ACME challenge
- "443:443" # HTTPS for production traffic
# Override volumes - use Let's Encrypt certificates and mount application code
volumes: volumes:
- certbot-conf:/etc/letsencrypt:ro - certbot-conf:/etc/letsencrypt:ro
- certbot-www:/var/www/certbot:ro - certbot-www:/var/www/certbot:ro
# Remove development host mounts for security # Application code via rsync deployment
# Application code deployed via Docker image build - /home/deploy/michaelschiemer/current:/var/www/html:ro
environment: environment:
- APP_ENV=production - APP_ENV=production
@@ -110,10 +115,11 @@ services:
memory: 512M memory: 512M
cpus: '1.0' cpus: '1.0'
# Remove development volumes # Production volumes
volumes: volumes:
# Mount entire storage directory as single volume to avoid subdirectory mount issues # Mount application code from rsync deployment (read-only)
# on read-only overlay filesystem - /home/deploy/michaelschiemer/current:/var/www/html:ro
# Mount storage directory as writable volume (overlays the read-only code mount)
- storage:/var/www/html/storage:rw - storage:/var/www/html/storage:rw
# Mount .env file from shared directory (production environment variables) # Mount .env file from shared directory (production environment variables)
- /home/deploy/michaelschiemer/shared/.env.production:/var/www/html/.env:ro - /home/deploy/michaelschiemer/shared/.env.production:/var/www/html/.env:ro
@@ -203,10 +209,11 @@ services:
# Worker command - executed after entrypoint setup # Worker command - executed after entrypoint setup
command: ["php", "/var/www/html/worker.php"] command: ["php", "/var/www/html/worker.php"]
# Remove development volumes # Production volumes
volumes: volumes:
# Mount entire storage directory as single volume to avoid subdirectory mount issues # Mount application code from rsync deployment (read-only)
# on read-only overlay filesystem - /home/deploy/michaelschiemer/current:/var/www/html:ro
# Mount storage directory as writable volume (overlays the read-only code mount)
- storage:/var/www/html/storage:rw - storage:/var/www/html/storage:rw
# Mount .env file from shared directory (production environment variables) # Mount .env file from shared directory (production environment variables)
- /home/deploy/michaelschiemer/shared/.env.production:/var/www/html/.env:ro - /home/deploy/michaelschiemer/shared/.env.production:/var/www/html/.env:ro

View File

@@ -14,13 +14,12 @@ final readonly class DatabasePlatformInitializer
{ {
public function __construct( public function __construct(
private Environment $environment private Environment $environment
) { ) {}
}
#[Initializer] #[Initializer]
public function __invoke(): DatabasePlatform public function __invoke(): DatabasePlatform
{ {
$driver = $this->environment->get('DB_DRIVER', 'mysql'); $driver = $this->environment->get('DB_DRIVER', 'pgsql');
return match($driver) { return match($driver) {
'mysql', 'mysqli' => new MySQLPlatform(), 'mysql', 'mysqli' => new MySQLPlatform(),