Table of Contents
- What Is Docker Compose?
- Building a Local Backend Environment with the Docker Compose Specification
- Docker Compose Operational Patterns and Environment-Specific Configuration Strategy
Where Things Often Break in Operations
Many Compose issues are not syntax errors. They happen when operational standards are undefined. A typical case is “works locally but behaves differently in team environments,” or “the same file produces different results depending on run options.”
This post focuses on reproducibility and maintainability patterns from an operational perspective, not just basic file syntax.
Split Execution Scope with profiles
Running all services all the time wastes resources and makes root-cause tracing harder.
Use profiles to separate targets for development, testing, and operational helper services.
services:
app:
build: .
ports:
- "8080:8080"
mysql:
image: mysql:8.0
environment:
MYSQL_DATABASE: order
MYSQL_ROOT_PASSWORD: root_pw
profiles: ["local"]
redis:
image: redis:7
profiles: ["local"]
adminer:
image: adminer
ports:
- "18080:8080"
profiles: ["debug"]
# Activate only local profile
$ docker compose --profile local up -d
# Activate local + debug profiles
$ docker compose --profile local --profile debug up -d
In operations, teams often keep the default service set minimal and place debugging tools into separate profiles.
Multi-File Override Strategy
If all environment branches are placed in one compose.yaml, complexity grows quickly.
A common approach is common base file plus environment-specific override files.
# Common + local override
$ docker compose -f compose.yaml -f compose.local.yaml up -d
# Common + CI override
$ docker compose -f compose.yaml -f compose.ci.yaml up -d
Example of local-only overrides for ports and volumes:
# compose.local.yaml
services:
app:
ports:
- "8080:8080"
volumes:
- ./:/workspace
File merge order is critical. Later files override earlier settings. Fix file order in team scripts to reduce operational mistakes.
Clarify Environment Variable Precedence
Value conflicts in Compose often happen around environment variables.
Mixing .env, env_file, environment, and shell variables makes value origin hard to trace.
services:
app:
env_file:
- .env.app
environment:
APP_LOG_LEVEL: info
DB_HOST: mysql
REQUEST_TIMEOUT_MS: "1500"
Define team rules first.
- Values that vary by deployment environment: inject at runtime
- Shared service defaults:
env_file - Must-fixed values:
environment
For security operations, sensitive values are generally injected at runtime, not embedded in image builds.
Boundary Between Compose and Application Responsibility
depends_on and healthcheck help startup control, but they do not replace application-level failure handling.
In production, separate transient and permanent failures and restrict retry targets accordingly.
@Slf4j
@Service
public class OrderSyncService {
public void sync(String requestId, String orderId) {
try {
callExternal(orderId);
log.info("order-sync-success requestId={} orderId={}", requestId, orderId);
} catch (SocketTimeoutException | ConnectException e) {
// Transient error: candidate for limited retries
log.warn("order-sync-retryable requestId={} orderId={} message={}",
requestId, orderId, e.getMessage());
throw new RetryableOperationException(e);
} catch (IllegalArgumentException | AuthenticationException e) {
// Permanent error: fail fast
log.error("order-sync-non-retryable requestId={} orderId={} message={}",
requestId, orderId, e.getMessage());
throw new NonRetryableOperationException(e);
}
}
private void callExternal(String orderId) {
// Example implementation
}
}
Keep identifiers such as requestId and orderId in logs.
In message-driven systems, teams also record key, partition, and offset for traceability.
Pre-Run Operational Checklist
Common Compose operational checks:
- Whether each profile starts only required services
- Whether
-fmerge order matches team scripts - Whether variable sources (
.env,env_file,environment) conflict - Whether retries are limited to transient failures
- Whether volume strategy (named volume/bind mount) matches data retention policy
In practice, simplifying execution flow and documenting checkpoints usually improves stability more than adding settings.
Summary
The core of Compose operations is not using many features. It is separating execution scope, clarifying configuration precedence, and separating Compose concerns from application logic. When this baseline is in place, teams reduce environment mismatch and operational mistakes.