The most detailed free FDE + DevOps library: 140+ lessons, 70+ labs and 80 long-form articles, in English and Turkish. Start learning →

DevOps Foundations · Module 5: Container basics

Volumes, Networks and Configuration

Containers are disposable; their data, networks and config are the design. This lesson puts state, connectivity and settings in the right places so recreating a container loses nothing.

10 min reading

Objectives

  • Choose volumes versus bind mounts versus tmpfs by data lifetime
  • Connect containers on a user-defined network by name instead of IP
  • Separate config, secrets and code with the right mechanism each
  • Diagnose a connection-refused between containers as a network problem, not an app bug

Why this matters

A database container is recreated during an upgrade and a quarter of data vanishes, because the data lived in the container's writable layer instead of a volume. The container did exactly what containers do: it was replaced. State placement is the whole ballgame for stateful containers, and the decision happens at first run, not at the incident.

Concepts

Three storage choices with different lifetimes. Named volumes persist independently of any container and survive recreation, upgrade and removal; use them for data that must outlive the container. Bind mounts expose host paths for development and single-host fixtures; they tie the container to one machine and leak host permissions inward. tmpfs lives in memory for scratch data that must never hit disk. The rule: data you cannot regenerate goes in a named volume, and volume contents get backed up like any database, because a volume is not a backup until it is copied elsewhere.

Container networks replace IPs with names. On a user-defined network, containers resolve each other by name or alias through embedded DNS; on the default bridge they do not, which is why two containers that ping by IP fail by name until someone creates the network. Publish ports (-p) only for ingress from outside; container-to-container traffic stays on the internal network unpublished. Connection refused between containers almost always means wrong network, wrong name, or the target listening on localhost inside its own container, in that order.

Configuration has three channels by sensitivity. Environment variables carry non-secret settings and feature flags: visible, overridable, logged by accident. Files carry structured config mounted read-only. Secrets get the narrowest channel available: mounted files with tight modes, or the platform's secret store, never environment in shared logs and never baked into images where every layer preserves them forever. Lesson 4 of M04 (the fictional secret) applies at full force to images: anything committed to a layer ships to every registry copy.

Worked example

An app container cannot reach its database container. The split:

$ docker exec app getent hosts db (empty - no resolution) $ docker network inspect appnet --format='{{range .Containers}}{{.Name}} {{end}}' app cache $ docker exec app getent hosts cache 172.18.0.4

Expected reading: db is not on appnet at all while cache resolves fine, so the database container was started on the wrong network (or none). The app is innocent; fix the attachment (connect db to appnet, or recreate it there), verify name resolution from inside app, then test the port once. Lab L14 replays volume plus network faults together until this order is automatic.

The common wrong move

Baking environment-specific config and secrets into the image. The image then works in exactly one environment, cannot be promoted through stages, and leaks every secret to anyone with registry read access. Build one image, configure per environment at runtime; the image carries defaults, the environment carries truth.

Lab and next step

Lab L14 gives you broken volume and network setups and requires the layered fix with proof. Next, lesson 4 keeps containers honest in production: health, signals and limits.

Quick check

An optional 4-question self-check. Answers never leave your device, are not stored, and never count toward any assessment.

Lesson feedback

No published feedback yet.

Log in and complete the lesson to leave feedback.

Exercise

Create a user-defined network, attach two containers, and prove name resolution plus one TCP check between them. Then show the same check failing from a container outside the network, and explain why.

Pass criteria

Network created with both containers attached; name resolution and TCP check quoted; outsider failure demonstrated with the isolation reason stated.

Sources

Log in to track progressFree account: stores only your lesson progress and quiz results.