Plan: Compose File Best Practices
Status
State: Active Started: 2026-05-14
Context
Sepia's compose files are functional but inconsistent. After infrastructure hardening (healthchecks, resource limits, cap_drop), the remaining medium/low items improve debuggability, startup reliability, and operational clarity.
Current state:
- Labels: No service has any labels (no categorization, no backup markers)
- container_name: Some services set it, some don't — creates auto-generated names that drift
- compose.override.yaml: Doesn't exist — all overrides are in the individual files
- depends_on: Only dsmr → {dsmrdb, influxdb} and seafile-server → {seafile-mysql, seafile-redis} exist; none use condition: service_healthy
- No service groups/comments: The main compose.yaml has section comments but individual files lack category metadata
Shuttle has this same plan as active/compose-best-practices.md — these are the post-hardening polish steps.
Goals
- [ ] Add standardized labels to all 14 services
- [ ] Ensure consistent
container_nameacross all services - [ ] Add
depends_onwithcondition: service_healthychains - [ ] Create startup dependency graph
Steps
Step 1: Add Standardized Labels
Apply a consistent label scheme across all containers:
labels:
"sepia.service": "<name>"
"sepia.group": "<category>"
"sepia.backup": "true|false"
Proposed grouping:
| Category | Services | Backup |
|---|---|---|
ingress |
caddy | false |
networking |
dns-ad-blocker | false |
backup |
borgmatic | false |
storage |
seafile-server, seafile-mysql, seafile-redis | true |
sensors |
esphome | true |
database |
influxdb, timescaledb, dsmrdb | true |
monitoring |
grafana, collectd | false |
automation |
homeassistant | true |
energy |
dsmr | true |
docs |
docs | false |
Add to each compose.<service>.yaml under the service definition.
- Verification:
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Labels}}'shows labels
Step 2: Standardize container_name
Audit which services are missing container_name:
| Compose File | Current | Action |
|---|---|---|
| compose.caddy.yaml | Not set (caddy is the image name) | Add container_name: caddy if not present |
| compose.borgmatic.yaml | container_name: borgmatic ✓ |
Already set |
| compose.collectd.yaml | container_name: collectd ✓ |
Already set |
| compose.dns-ad-blocker.yaml | Not set | Add container_name: dns-ad-blocker (or skip if migrating to blocky) |
| compose.docs.yaml | Not set (docs is the image name) | Add container_name: docs |
| compose.dsmr.yaml | Not set (dsmr service, dsmrdb service) | Add container_name: dsmr, container_name: dsmrdb |
| compose.grafana.yaml | container_name: grafana ✓ |
Already set |
| compose.homeassistant.yaml | container_name: homeassistant ✓ |
Already set |
| compose.influxdb.yaml | container_name: influxdb ✓ |
Already set |
| compose.seafile.yaml | seafile-mysql ✓, seafile-redis ✓, seafile-server ✓ | Already set |
| compose.timescaledb.yaml | Not set | Add container_name: timescaledb |
| compose.esphome.yaml | container_name: esphome ✓ |
Already set |
- Verification: All containers show consistent names in
docker ps
Step 3: Add depends_on with Health Conditions
Update all depends_on to use condition: service_healthy once healthchecks are in place (from hardening plan):
Target dependency graph:
# dsmr → dsmrdb (healthy) → depends on nothing
# → influxdb (healthy) → depends on nothing
# seafile-server → seafile-mysql (healthy)
# → seafile-redis (healthy)
# grafana → influxdb (healthy)
# → timescaledb (healthy)
# caddy → seafile-server (healthy)
# → grafana (healthy)
# → homeassistant (healthy)
# → dsmr (healthy)
Example format:
depends_on:
dsmrdb:
condition: service_healthy
influxdb:
condition: service_healthy
- Verification: On restart,
docker compose upwaits for dependencies to pass healthchecks before starting dependent services
Step 4: Create compose.override.yaml (optional)
If needed for environment-specific overrides (e.g., dev vs prod), create compose.override.yaml. Otherwise document that sepia doesn't need one.
- Verification:
docker compose configshows the merged result correctly
Rollback
All changes are in compose files tracked by git. git checkout -- compose.*.yaml reverts.
Related
- REFERENCE/services.md (update with labels/group info)
- PLANS/active/infrastructure-hardening.md (adds healthchecks needed for depends_on)
Created: 2026-05-14