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
|
||||
restart: always
|
||||
|
||||
# Production port mappings for Let's Encrypt
|
||||
ports:
|
||||
- "80:80" # HTTP for ACME challenge
|
||||
- "443:443" # HTTPS for production traffic
|
||||
# Note: Port mappings removed - Traefik handles all external routing
|
||||
# No direct port bindings needed, Traefik proxies traffic to this container
|
||||
|
||||
# Override volumes - use Let's Encrypt certificates and mount application code
|
||||
volumes:
|
||||
@@ -152,82 +150,8 @@ services:
|
||||
# Database service removed - using external PostgreSQL Stack (deployment/stacks/postgresql/)
|
||||
# Connection via app-internal network using docker-compose.postgres-override.yml
|
||||
|
||||
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
|
||||
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"
|
||||
# Redis service removed - using external Redis Stack (deployment/stacks/redis/)
|
||||
# Connection via app-internal network using docker-compose.redis-override.yml
|
||||
|
||||
queue-worker:
|
||||
# Use pre-built image from registry (override build from base)
|
||||
@@ -292,11 +216,9 @@ services:
|
||||
|
||||
# Wait for dependencies to be healthy before starting
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
php:
|
||||
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:
|
||||
@@ -366,11 +288,9 @@ services:
|
||||
|
||||
# Wait for dependencies to be healthy before starting
|
||||
depends_on:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
php:
|
||||
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:
|
||||
|
||||
Reference in New Issue
Block a user