Docker Compose Tip #43: Read-only root filesystems

Making a container’s root filesystem read-only is one of the simplest and most effective hardening measures. If an attacker gets in, they can’t modify binaries or drop malicious files. Basic usage services: app: image: myapp read_only: true That’s it. The container’s filesystem is now immutable. But most applications need to write somewhere — logs, temp files, caches. That’s where tmpfs comes in. Read-only with tmpfs for writable directories Combine read_only with tmpfs to allow writes only where needed: ...

March 23, 2026 · 2 min · 336 words · Guillaume Lours

Docker Compose Tip #41: Container lifecycle hooks

Docker Compose supports lifecycle hooks that let you run commands at specific points in a container’s lifecycle, right after it starts and just before it stops. post_start hook Run a command inside the container right after it starts — perfect for initialization tasks like database migrations: services: api: image: myapp-api post_start: - command: /app/migrate.sh depends_on: postgres: condition: service_healthy Or warming up caches so the service is ready to handle traffic: ...

March 18, 2026 · 2 min · 306 words · Guillaume Lours

Docker Compose Tip #40: Using labels for service organization and monitoring

Labels are key-value metadata attached to containers. They cost nothing at runtime but unlock powerful filtering, organization, and tool integrations. Adding labels to services services: api: image: myapp-api labels: com.example.team: "backend" com.example.env: "production" com.example.version: "2.1.0" worker: image: myapp-worker labels: com.example.team: "backend" com.example.env: "production" com.example.role: "async-processing" You can also use the list syntax: services: api: image: myapp-api labels: - "com.example.team=backend" - "com.example.env=production" Filtering with labels Labels become powerful with docker compose ps: ...

March 16, 2026 · 2 min · 258 words · Guillaume Lours

Docker Compose Tip #38: When to use include vs extends vs overrides

Now that you understand how include, extends, and override files work, how do you pick the right one? Here’s a practical guide. Use override files for environment-specific configuration Override files are the right choice when you need to adapt the same stack to different environments or developer setups: # compose.yml - base definition, committed to git services: app: image: myapp:${TAG:-latest} environment: NODE_ENV: production # compose.override.yml - local dev tweaks, optionally gitignored services: app: build: . # Build locally instead of pulling image environment: NODE_ENV: development volumes: - .:/app # Mount source for hot reload Good fit for: ...

March 11, 2026 · 2 min · 342 words · Guillaume Lours

Docker Compose Tip #37: Understanding include, extends, and override files

Docker Compose gives you three ways to split and reuse configurations. They look similar but work at different levels and serve different purposes. Override files: project-level merge Override files are merged with your main compose.yml at the project level. compose.override.yml is loaded automatically; additional files require the -f flag: # compose.override.yml is loaded automatically docker compose up # Explicit merge docker compose -f compose.yml -f compose.prod.yml up Mappings are merged (override wins), arrays are concatenated: ...

March 9, 2026 · 2 min · 335 words · Guillaume Lours