Service Configuration
Service Configuration Files
# docker-compose.override.yml (development)
services:
php-fpm:
build:
context: ./docker/php
dockerfile: Dockerfile.dev
volumes:
- ./src:/var/www/html
- ./docker/php/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini
environment:
- PHP_IDE_CONFIG=serverName=docker
- XDEBUG_CONFIG=client_host=host.docker.internal
nginx:
volumes:
- ./docker/nginx/default.dev.conf:/etc/nginx/conf.d/default.conf
PHP Service Config
php-fpm:
build:
context: ./docker/php
dockerfile: Dockerfile
args:
PHP_VERSION: 8.2
INSTALL_XDEBUG: true
environment:
- PHP_MEMORY_LIMIT=2G
- PHP_MAX_EXECUTION_TIME=1800
- PHP_UPLOAD_MAX_FILESIZE=100M
- PHP_POST_MAX_SIZE=100M
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "php-fpm-healthcheck || exit 1"]
interval: 30s
timeout: 10s
retries: 3
Environment Variables
Environment Variable Management
# .env file
COMPOSE_PROJECT_NAME=magento2
# Database
MYSQL_ROOT_PASSWORD=root
MYSQL_DATABASE=magento
MYSQL_USER=magento
MYSQL_PASSWORD=magento
# Redis
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_CACHE_DB=0
REDIS_SESSION_DB=1
# OpenSearch
OPENSEARCH_HOST=opensearch
OPENSEARCH_PORT=9200
OPENSEARCH_INDEX_PREFIX=magento2
# Application
APP_ENV=development
APP_DEBUG=1
APP_URL=http://localhost
Environment in docker-compose.yml
services:
php-fpm:
env_file:
- .env
environment:
- MYSQL_HOST=${MYSQL_HOST:-mysql}
- REDIS_HOST=${REDIS_HOST:-redis}
- APP_ENV=${APP_ENV:-production}
nginx:
environment:
- PHP_FPM_HOST=php-fpm
- PHP_FPM_PORT=9000
Magento env.php
<?php
return [
'http_cache_hosts' => [
[
'http_cache_host' => 'varnish',
'port' => 80,
],
],
'db' => [
'connection' => [
'default' => [
'host' => getenv('MYSQL_HOST') ?: 'mysql',
'dbname' => getenv('MYSQL_DATABASE') ?: 'magento',
'username' => getenv('MYSQL_USER') ?: 'magento',
'password' => getenv('MYSQL_PASSWORD') ?: 'magento',
],
],
],
'cache' => [
'frontend' => [
'default' => [
'backend' => 'Cm_Cache_Backend_Redis',
'backend_options' => [
'server' => getenv('REDIS_HOST') ?: 'redis',
'port' => getenv('REDIS_PORT') ?: 6379,
'database' => getenv('REDIS_CACHE_DB') ?: 0,
],
],
],
],
'session' => [
'save' => 'redis',
'redis' => [
'host' => getenv('REDIS_HOST') ?: 'redis',
'port' => getenv('REDIS_PORT') ?: 6379,
'database' => getenv('REDIS_SESSION_DB') ?: 1,
],
],
];
Docker Networking
Network Configuration
networks:
magento-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
frontend:
driver: bridge
backend:
driver: bridge
internal: true # No external access
Service-to-Service Communication
services:
nginx:
networks:
- frontend
- backend
depends_on:
php-fpm:
condition: service_healthy
php-fpm:
networks:
- backend
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
mysql:
networks:
- backend
DNS Resolution
# Docker provides DNS resolution between containers
# Use service name as hostname
# From php-fpm container:
mysql -h mysql -u magento -p
redis-cli -h redis
# From nginx container:
fastcgi_pass php-fpm:9000
Performance Optimization
Resource Limits
services:
php-fpm:
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
cpus: '1.0'
memory: 1G
mysql:
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
cpus: '1.0'
memory: 1G
Caching Strategies
services:
redis:
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
opensearch:
environment:
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
- "OPENSEARCH_INITIAL_ADMIN_PASSWORD=Admin@123"
Volume Performance
services:
mysql:
volumes:
- mysql-data:/var/lib/mysql
- type: tmpfs
target: /tmp
tmpfs:
size: 100000000 # 100MB
Multi-Stage Builds
# Build stage
FROM php:8.2-fpm-alpine AS builder
RUN apk add --no-cache $PHPIZE_DEPS
RUN docker-php-ext-install pdo_mysql mbstring
# Production stage
FROM php:8.2-fpm-alpine
COPY --from=builder /usr/local/lib/php/extensions /usr/local/lib/php/extensions
COPY --from=builder /usr/local/etc/php/conf.d /usr/local/etc/php/conf.d
Health Check Scripts
#!/bin/bash
# docker/php/healthcheck.sh
# Check PHP-FPM
if ! php-fpm-healthcheck > /dev/null 2>&1; then
echo "PHP-FPM unhealthy"
exit 1
fi
# Check MySQL connection
if ! mysqladmin ping -h mysql -u root -p$MYSQL_ROOT_PASSWORD > /dev/null 2>&1; then
echo "MySQL unhealthy"
exit 1
fi
echo "All services healthy"
exit 0
Quiz
1. What is the purpose of docker-compose.override.yml?
2. How do containers communicate?
3. What are Docker resource limits?
Flashcards
Question
What is docker-compose.override.yml?
Click to reveal answer
Answer
Environment-specific overrides for docker-compose.yml
Question
How do containers find each other?
Click to reveal answer
Answer
DNS resolution using service names
Question
What are resource limits?
Click to reveal answer
Answer
CPU and memory constraints per container
Question
What is a Docker network?
Click to reveal answer
Answer
Isolated bridge for container communication
Revision Notes
Key Takeaways
- 1. docker-compose.override.yml customizes per environment
- 2. Environment variables manage configuration values
- 3. Docker networks enable inter-container communication
- 4. Resource limits prevent container resource exhaustion
- 5. Health checks monitor service availability
Interview Tips
- • Explain Docker networking modes
- • Discuss environment variable management
- • Describe resource limit configurations
- • Talk about service dependency management
Cheat Sheet
Services:
PHP-FPM → PHP processing
Nginx → HTTP serving
MySQL → Database
Redis → Cache/Session
OpenSearch → Search
Networking:
Service name = hostname
Bridge network for communication
Internal network for backend
Environment:
.env file → variable definitions
docker-compose.yml → reference vars
env_file → load from file