feat: update deployment configuration and encrypted env loader
- Update Ansible playbooks and roles for application deployment - Add new Gitea/Traefik troubleshooting playbooks - Update Docker Compose configurations (base, local, staging, production) - Enhance EncryptedEnvLoader with improved error handling - Add deployment scripts (autossh setup, migration, secret testing) - Update CI/CD workflows and documentation - Add Semaphore stack configuration
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
# Production-specific Docker Compose overrides
|
||||
# Usage: docker-compose -f docker-compose.yml -f docker-compose.production.yml --env-file .env.production up -d
|
||||
# Production Environment Override
|
||||
# Usage: docker-compose -f docker-compose.base.yml -f docker-compose.production.yml --env-file .env.production up -d
|
||||
#
|
||||
# This file overrides base configuration with production-specific settings:
|
||||
# - Stricter resource limits
|
||||
# - Production restart policies (always)
|
||||
# - JSON logging with proper rotation
|
||||
# - No host mounts (security)
|
||||
# - Internal networks (security)
|
||||
# - Production PostgreSQL configuration
|
||||
# - Certbot for SSL certificates
|
||||
# - Production port mappings (80, 443 for Let's Encrypt)
|
||||
|
||||
services:
|
||||
web:
|
||||
@@ -31,6 +31,16 @@ services:
|
||||
- APP_ENV=production
|
||||
- APP_DEBUG=false
|
||||
|
||||
# Security hardening
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- CHOWN
|
||||
- DAC_OVERRIDE
|
||||
- NET_BIND_SERVICE # Required for binding to ports 80/443
|
||||
|
||||
# Stricter health checks for production
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "https://localhost/health"]
|
||||
@@ -64,11 +74,6 @@ services:
|
||||
certbot:
|
||||
condition: service_started
|
||||
|
||||
# Networks must be explicitly defined to avoid override issues
|
||||
networks:
|
||||
- frontend
|
||||
- backend
|
||||
|
||||
php:
|
||||
# Production restart policy
|
||||
restart: always
|
||||
@@ -77,6 +82,15 @@ services:
|
||||
# The entrypoint script will use gosu to switch to appuser after setup
|
||||
user: "root"
|
||||
|
||||
# Security hardening (applied after gosu switches to appuser)
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
cap_drop:
|
||||
- ALL
|
||||
cap_add:
|
||||
- CHOWN
|
||||
- DAC_OVERRIDE
|
||||
|
||||
# Override build args for production
|
||||
build:
|
||||
args:
|
||||
@@ -90,6 +104,16 @@ services:
|
||||
- PHP_MAX_EXECUTION_TIME=30
|
||||
# Disable Xdebug in production
|
||||
- XDEBUG_MODE=off
|
||||
# Use Docker Secrets via *_FILE pattern (Framework supports this automatically)
|
||||
- DB_PASSWORD_FILE=/run/secrets/db_user_password
|
||||
- REDIS_PASSWORD_FILE=/run/secrets/redis_password
|
||||
- APP_KEY_FILE=/run/secrets/app_key
|
||||
- VAULT_ENCRYPTION_KEY_FILE=/run/secrets/vault_encryption_key
|
||||
secrets:
|
||||
- db_user_password
|
||||
- redis_password
|
||||
- app_key
|
||||
- vault_encryption_key
|
||||
|
||||
# Stricter health checks
|
||||
healthcheck:
|
||||
@@ -127,15 +151,16 @@ services:
|
||||
# Mount .env file from shared directory (production environment variables)
|
||||
- /home/deploy/michaelschiemer/shared/.env.production:/var/www/html/.env:ro
|
||||
|
||||
# Networks must be explicitly defined to avoid override issues
|
||||
networks:
|
||||
- backend
|
||||
- cache
|
||||
|
||||
db:
|
||||
# Production restart policy
|
||||
restart: always
|
||||
|
||||
# Use Docker Secrets for database password
|
||||
environment:
|
||||
POSTGRES_PASSWORD_FILE: /run/secrets/db_user_password
|
||||
secrets:
|
||||
- db_user_password
|
||||
|
||||
# Use production PostgreSQL configuration
|
||||
volumes:
|
||||
- db_data:/var/lib/postgresql/data
|
||||
@@ -169,14 +194,51 @@ services:
|
||||
compress: "true"
|
||||
labels: "service,environment"
|
||||
|
||||
# Networks must be explicitly defined to avoid override issues
|
||||
networks:
|
||||
- backend
|
||||
|
||||
redis:
|
||||
# Production restart policy
|
||||
restart: always
|
||||
|
||||
# Use Docker Secrets for Redis password
|
||||
environment:
|
||||
REDIS_PASSWORD_FILE: /run/secrets/redis_password
|
||||
secrets:
|
||||
- redis_password
|
||||
|
||||
# Security hardening
|
||||
security_opt:
|
||||
- no-new-privileges:true
|
||||
# Don't set user here - we need root to read Docker Secrets in entrypoint
|
||||
# Redis will run as root, but this is acceptable for this use case
|
||||
cap_drop:
|
||||
- ALL
|
||||
|
||||
# Use entrypoint script to inject password from Docker Secret into config
|
||||
# Note: Script runs as root to read Docker Secrets, then starts Redis
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
command:
|
||||
- |
|
||||
# Read password from Docker Secret (as root)
|
||||
REDIS_PASSWORD=$$(cat /run/secrets/redis_password 2>/dev/null || echo '')
|
||||
# Start Redis with all settings as command line arguments (no config file to avoid conflicts)
|
||||
if [ -n "$$REDIS_PASSWORD" ]; then
|
||||
exec redis-server \
|
||||
--bind 0.0.0.0 \
|
||||
--dir /data \
|
||||
--save 900 1 \
|
||||
--save 300 10 \
|
||||
--save 60 10000 \
|
||||
--appendonly yes \
|
||||
--requirepass "$$REDIS_PASSWORD"
|
||||
else
|
||||
exec redis-server \
|
||||
--bind 0.0.0.0 \
|
||||
--dir /data \
|
||||
--save 900 1 \
|
||||
--save 300 10 \
|
||||
--save 60 10000 \
|
||||
--appendonly yes
|
||||
fi
|
||||
|
||||
# Production resource limits
|
||||
deploy:
|
||||
resources:
|
||||
@@ -204,10 +266,6 @@ services:
|
||||
compress: "true"
|
||||
labels: "service,environment"
|
||||
|
||||
# Networks must be explicitly defined to avoid override issues
|
||||
networks:
|
||||
- cache
|
||||
|
||||
queue-worker:
|
||||
# Use same build as php service (has application code copied)
|
||||
|
||||
@@ -238,6 +296,16 @@ services:
|
||||
- WORKER_DEBUG=false
|
||||
- WORKER_SLEEP_TIME=100000
|
||||
- WORKER_MAX_JOBS=10000
|
||||
# Use Docker Secrets via *_FILE pattern (Framework supports this automatically)
|
||||
- DB_PASSWORD_FILE=/run/secrets/db_user_password
|
||||
- REDIS_PASSWORD_FILE=/run/secrets/redis_password
|
||||
- APP_KEY_FILE=/run/secrets/app_key
|
||||
- VAULT_ENCRYPTION_KEY_FILE=/run/secrets/vault_encryption_key
|
||||
secrets:
|
||||
- db_user_password
|
||||
- redis_password
|
||||
- app_key
|
||||
- vault_encryption_key
|
||||
|
||||
# Production resource limits
|
||||
deploy:
|
||||
@@ -272,11 +340,6 @@ services:
|
||||
php:
|
||||
condition: service_healthy
|
||||
|
||||
# Networks must be explicitly defined to avoid override issues
|
||||
networks:
|
||||
- backend
|
||||
- cache
|
||||
|
||||
# Certbot Sidecar Container for Let's Encrypt
|
||||
certbot:
|
||||
image: certbot/certbot:latest
|
||||
@@ -306,15 +369,8 @@ services:
|
||||
labels: "service,environment"
|
||||
|
||||
networks:
|
||||
# Production networks with security isolation
|
||||
frontend:
|
||||
driver: bridge
|
||||
backend:
|
||||
driver: bridge
|
||||
# NOTE: backend must NOT be internal - PHP needs to communicate with DB!
|
||||
cache:
|
||||
driver: bridge
|
||||
internal: true # Cache network is internal
|
||||
internal: true # Cache network is internal in production
|
||||
|
||||
volumes:
|
||||
# Let's Encrypt SSL Certificates
|
||||
|
||||
Reference in New Issue
Block a user