feat(deployment): migrate to external Redis stack
Architecture Changes: - Remove embedded Redis service from production configuration - Remove port 80/443 direct bindings (Traefik handles routing) - Update queue-worker and scheduler dependencies (Redis now external) - Completes Redis stack migration following PostgreSQL pattern - Resolves port conflict with Traefik reverse proxy Related Files: - deployment/stacks/redis/docker-compose.yml (Redis stack - already deployed) - docker-compose.redis-override.yml (application integration - already created) Migration Benefits: - Architectural consistency with PostgreSQL stack pattern - Better separation of concerns (infrastructure vs application) - Independent Redis lifecycle management - Shared Redis instance via app-internal network - Eliminated port 80 binding conflict Deployment Command: docker compose -f docker-compose.base.yml -f docker-compose.production.yml \ -f docker-compose.postgres-override.yml -f docker-compose.redis-override.yml up -d
This commit is contained in:
@@ -19,10 +19,8 @@ services:
|
|||||||
# Production restart policy
|
# Production restart policy
|
||||||
restart: always
|
restart: always
|
||||||
|
|
||||||
# Production port mappings for Let's Encrypt
|
# Note: Port mappings removed - Traefik handles all external routing
|
||||||
ports:
|
# No direct port bindings needed, Traefik proxies traffic to this container
|
||||||
- "80:80" # HTTP for ACME challenge
|
|
||||||
- "443:443" # HTTPS for production traffic
|
|
||||||
|
|
||||||
# Override volumes - use Let's Encrypt certificates and mount application code
|
# Override volumes - use Let's Encrypt certificates and mount application code
|
||||||
volumes:
|
volumes:
|
||||||
@@ -152,82 +150,8 @@ services:
|
|||||||
# Database service removed - using external PostgreSQL Stack (deployment/stacks/postgresql/)
|
# Database service removed - using external PostgreSQL Stack (deployment/stacks/postgresql/)
|
||||||
# Connection via app-internal network using docker-compose.postgres-override.yml
|
# Connection via app-internal network using docker-compose.postgres-override.yml
|
||||||
|
|
||||||
redis:
|
# Redis service removed - using external Redis Stack (deployment/stacks/redis/)
|
||||||
# Production restart policy
|
# Connection via app-internal network using docker-compose.redis-override.yml
|
||||||
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
|
|
||||||
cap_add:
|
|
||||||
- CHOWN # Required for creating appendonlydir with correct permissions
|
|
||||||
- DAC_OVERRIDE # Required for writing to /data volume owned by redis user
|
|
||||||
|
|
||||||
# Use entrypoint script to inject password from Docker Secret into environment
|
|
||||||
# This makes password available to both Redis startup AND health check
|
|
||||||
# Note: Script runs as root to read Docker Secrets, then starts Redis
|
|
||||||
entrypoint: ["/bin/sh", "-c"]
|
|
||||||
command:
|
|
||||||
- |
|
|
||||||
# Read password from Docker Secret (as root) and export for health check
|
|
||||||
export 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:
|
|
||||||
limits:
|
|
||||||
memory: 512M
|
|
||||||
cpus: '1.0'
|
|
||||||
reservations:
|
|
||||||
memory: 256M
|
|
||||||
cpus: '0.5'
|
|
||||||
|
|
||||||
# Stricter health checks
|
|
||||||
# Health check reads password directly from Docker Secret
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "redis-cli -a \"$(cat /run/secrets/redis_password 2>/dev/null || echo '')\" ping | grep -q PONG"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 3s
|
|
||||||
retries: 5
|
|
||||||
start_period: 30s
|
|
||||||
|
|
||||||
# JSON logging
|
|
||||||
logging:
|
|
||||||
driver: json-file
|
|
||||||
options:
|
|
||||||
max-size: "10m"
|
|
||||||
max-file: "5"
|
|
||||||
compress: "true"
|
|
||||||
labels: "service,environment"
|
|
||||||
|
|
||||||
queue-worker:
|
queue-worker:
|
||||||
# Use pre-built image from registry (override build from base)
|
# Use pre-built image from registry (override build from base)
|
||||||
@@ -292,11 +216,9 @@ services:
|
|||||||
|
|
||||||
# Wait for dependencies to be healthy before starting
|
# Wait for dependencies to be healthy before starting
|
||||||
depends_on:
|
depends_on:
|
||||||
redis:
|
|
||||||
condition: service_healthy
|
|
||||||
php:
|
php:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
# Note: PostgreSQL (postgres) is external service, connection via app-internal network
|
# Note: PostgreSQL and Redis are external services, connection via app-internal network
|
||||||
|
|
||||||
# Scheduler (Cron Jobs)
|
# Scheduler (Cron Jobs)
|
||||||
scheduler:
|
scheduler:
|
||||||
@@ -366,11 +288,9 @@ services:
|
|||||||
|
|
||||||
# Wait for dependencies to be healthy before starting
|
# Wait for dependencies to be healthy before starting
|
||||||
depends_on:
|
depends_on:
|
||||||
redis:
|
|
||||||
condition: service_healthy
|
|
||||||
php:
|
php:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
# Note: PostgreSQL (postgres) is external service, connection via app-internal network
|
# Note: PostgreSQL and Redis are external services, connection via app-internal network
|
||||||
|
|
||||||
# Certbot Sidecar Container for Let's Encrypt
|
# Certbot Sidecar Container for Let's Encrypt
|
||||||
certbot:
|
certbot:
|
||||||
|
|||||||
Reference in New Issue
Block a user