# Code Reference — Docker

_11 pages_

---
# Docker (/docs/docker)



# Docker [#docker]

Images, Compose, containers.

Browse the sidebar for every cheat sheet in this section.

## Sections [#sections]

*All notes are listed in the sidebar.*


---

# Docker Compose (/docs/docker/compose)



# Docker Compose [#docker-compose]

*Docker · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Compose defines multi-service stacks in YAML: web, db, redis, networks, and volumes with one `docker compose up`.

## 🔧 Core concepts [#-core-concepts]

| Key                        | Role                         |
| -------------------------- | ---------------------------- |
| `services`                 | Containers to run            |
| `images` / `build`         | Prebuilt vs local Dockerfile |
| `ports`                    | `host:container` publish     |
| `environment` / `env_file` | Config                       |
| `volumes`                  | Persist or share data        |
| `networks`                 | Service DNS names            |
| `depends_on`               | Start order (not readiness)  |

| Command                  | Purpose        |
| ------------------------ | -------------- |
| `docker compose up -d`   | Start detached |
| `docker compose down`    | Stop + remove  |
| `docker compose logs -f` | Follow logs    |
| `docker compose ps`      | Status         |

## 💡 Examples [#-examples]

**Minimal stack:**

```yaml
services:
  web:
    build: .
    ports:
      - "9000:9000"
    environment:
      DATABASE_URL: postgres://postgres:postgres@db:5432/app
    depends_on:
      - db
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: postgres
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:
```

**Rebuild one service:**

```shellscript
docker compose up -d --build web
```

## ⚠️ Pitfalls [#️-pitfalls]

* `depends_on` does not wait for DB ready — use healthchecks + `condition: service_healthy`.
* Host `localhost` inside a container is the container itself — use service names (`db`).
* Old `docker-compose` (hyphen) CLI differs from `docker compose` plugin — prefer the plugin.

## 🔗 Related [#-related]

* [networks.md](/docs/docker/networks)
* [volumes.md](/docs/docker/volumes)
* [healthchecks.md](/docs/docker/healthchecks)
* [env\_secrets.md](/docs/docker/env-secrets)


---

# Dockerfile (/docs/docker/dockerfile)



# Dockerfile [#dockerfile]

*Docker · Reference cheat sheet*

***

## 📋 Overview [#-overview]

A Dockerfile is a sequence of instructions that build an image layer by layer. Order matters for cache efficiency.

## 🔧 Core concepts [#-core-concepts]

| Instruction          | Role                             |
| -------------------- | -------------------------------- |
| `FROM`               | Base image                       |
| `WORKDIR`            | Set working directory            |
| `COPY` / `ADD`       | Add files (`COPY` preferred)     |
| `RUN`                | Execute build commands           |
| `ENV` / `ARG`        | Runtime env / build args         |
| `EXPOSE`             | Document port (does not publish) |
| `USER`               | Switch user                      |
| `CMD` / `ENTRYPOINT` | Default process                  |

| Cache tip            | Practice                                |
| -------------------- | --------------------------------------- |
| Copy lockfiles first | Reuse `npm ci` / `pip` layers           |
| Fewer layers         | Combine related `RUN`s when it helps    |
| `.dockerignore`      | Exclude `node_modules`, `.git`, secrets |

## 💡 Examples [#-examples]

**Node app sketch:**

```dockerfile
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
USER node
EXPOSE 9000
CMD ["node", "server.js"]
```

**Build args:**

```dockerfile
ARG NODE_ENV=production
ENV NODE_ENV=$NODE_ENV
```

**`.dockerignore`:**

```
node_modules
.git
.env
Dockerfile*
```

## ⚠️ Pitfalls [#️-pitfalls]

* `ADD` auto-extracts archives and can fetch URLs — surprising; prefer `COPY`.
* Secrets in `RUN` lines leak into image history — use BuildKit secret mounts.
* `CMD` vs `ENTRYPOINT` confusion: know exec-form JSON arrays vs shell form.

## 🔗 Related [#-related]

* [multi\_stage.md](/docs/docker/multi-stage)
* [images\_tags.md](/docs/docker/images-tags)
* [env\_secrets.md](/docs/docker/env-secrets)
* [getting\_started.md](/docs/docker/getting-started)


---

# Env & Secrets (/docs/docker/env-secrets)



# Env & Secrets [#env--secrets]

*Docker · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Pass configuration with environment variables and inject secrets without baking them into image layers. Prefer runtime secrets over `Dockerfile ENV` for credentials.

## 🔧 Core concepts [#-core-concepts]

| Mechanism            | Use                                                   |
| -------------------- | ----------------------------------------------------- |
| `ENV`                | Non-secret defaults in image                          |
| `ARG`                | Build-time only (still visible in history if misused) |
| `-e` / `environment` | Runtime env                                           |
| `env_file`           | File of KEY=VAL                                       |
| BuildKit `--secret`  | Secret mounts during build                            |
| Orchestrator secrets | Swarm/K8s/Compose secrets                             |

## 💡 Examples [#-examples]

**Runtime env:**

```shellscript
docker run --rm -e DATABASE_URL="$DATABASE_URL" myapp:1.0.0
```

**Compose env\_file:**

```yaml
services:
  api:
    env_file:
      - .env
    environment:
      NODE_ENV: production
```

**BuildKit npm token (sketch):**

```dockerfile
# syntax=docker/dockerfile:1
RUN --mount=type=secret,id=npm,target=/root/.npmrc npm ci
```

```shellscript
docker build --secret id=npm,src=$HOME/.npmrc -t myapp .
```

## ⚠️ Pitfalls [#️-pitfalls]

* `ENV SECRET=...` in a Dockerfile is recoverable from image history.
* Committing `.env` with production credentials is a common breach path.
* `docker history` and layer caching can retain leaked build args.

## 🔗 Related [#-related]

* [dockerfile.md](/docs/docker/dockerfile)
* [compose.md](/docs/docker/compose)
* [multi\_stage.md](/docs/docker/multi-stage)
* [getting\_started.md](/docs/docker/getting-started)


---

# Getting Started with Docker (/docs/docker/getting-started)



# Getting Started with Docker [#getting-started-with-docker]

*Docker · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Docker packages apps and dependencies into images and runs them as containers. Use it for reproducible environments, local stacks, and deployment units.

## 🔧 Core concepts [#-core-concepts]

| Idea       | Meaning                                   |
| ---------- | ----------------------------------------- |
| Image      | Immutable filesystem + metadata template  |
| Container  | Running (or stopped) instance of an image |
| Dockerfile | Build recipe for an image                 |
| Registry   | Image store (Docker Hub, GHCR, …)         |
| Compose    | Multi-container app definition            |

| Command          | Purpose                  |
| ---------------- | ------------------------ |
| `docker version` | Client/server versions   |
| `docker pull`    | Download image           |
| `docker run`     | Create + start container |
| `docker ps`      | List running containers  |
| `docker build`   | Build from Dockerfile    |

## 💡 Examples [#-examples]

**Run nginx:**

```shellscript
docker run --rm -p 8080:80 nginx:alpine
```

**Build and run:**

```shellscript
docker build -t myapp:dev .
docker run --rm -p 9000:9000 myapp:dev
```

**Shell into a container:**

```shellscript
docker exec -it <container> sh
```

## ⚠️ Pitfalls [#️-pitfalls]

* Binding only to container localhost is fine; publishing ports needs `-p host:container`.
* Data in the writable container layer is lost when the container is removed — use volumes.
* Running as root inside images increases risk — prefer non-root users in production images.

## 🔗 Related [#-related]

* [dockerfile.md](/docs/docker/dockerfile)
* [compose.md](/docs/docker/compose)
* [images\_tags.md](/docs/docker/images-tags)
* [glossary.md](/docs/docker/glossary)


---

# Glossary (/docs/docker/glossary)



# Glossary [#glossary]

*Docker · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Alphabetical glossary of Docker image, container, and Compose terms.

## 🔧 Core concepts [#-core-concepts]

| Term            | Definition                                                   |
| --------------- | ------------------------------------------------------------ |
| Bind mount      | Host directory mounted into a container path.                |
| Bridge network  | Default single-host virtual network for containers.          |
| Build context   | Files sent to the daemon for `docker build`.                 |
| Compose         | YAML-driven multi-container application tool.                |
| Container       | Runnable instance of an image with its own filesystem layer. |
| Digest          | Content-addressed `sha256:` image identity.                  |
| EntryPoint      | Primary executable configuration for a container.            |
| Image           | Immutable layered snapshot used to create containers.        |
| Layer           | Filesystem diff produced by a Dockerfile instruction.        |
| Multi-stage     | Build pattern with multiple `FROM` stages.                   |
| Registry        | Remote store for images (Docker Hub, GHCR, ECR…).            |
| Tag             | Mutable human label for an image (`:1.2.0`, `:latest`).      |
| Volume          | Persistent Docker-managed storage mount.                     |
| `.dockerignore` | Excludes files from the build context.                       |

## 💡 Examples [#-examples]

**Name anatomy:**

```
ghcr.io/acme/api:1.4.0
└ registry ┘ └image┘ └tag┘
```

**Quick lifecycle:**

```shellscript
docker build -t demo:1 .
docker run --rm demo:1
```

## ⚠️ Pitfalls [#️-pitfalls]

* “Container stopped” still exists until removed — check `docker ps -a`.
* Tag ≠ immutable identity — digests do.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/docker/getting-started)
* [dockerfile.md](/docs/docker/dockerfile)
* [compose.md](/docs/docker/compose)
* [README.md](/docs/docker)


---

# Healthchecks (/docs/docker/healthchecks)



# Healthchecks [#healthchecks]

*Docker · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Healthchecks tell Docker/Compose whether a container is ready or healthy. Use them for restart policies and `depends_on` conditions.

## 🔧 Core concepts [#-core-concepts]

| Field          | Meaning                           |
| -------------- | --------------------------------- |
| `test`         | Command that exits 0 when healthy |
| `interval`     | Time between checks               |
| `timeout`      | Max time for one check            |
| `retries`      | Failures before unhealthy         |
| `start_period` | Grace period during boot          |

| Status      | Meaning              |
| ----------- | -------------------- |
| `starting`  | Within start\_period |
| `healthy`   | Checks passing       |
| `unhealthy` | Checks failing       |

## 💡 Examples [#-examples]

**Dockerfile HEALTHCHECK:**

```dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=20s --retries=3 \
  CMD wget -qO- http://127.0.0.1:9000/health || exit 1
```

**Compose healthcheck + depends\_on:**

```yaml
services:
  db:
    image: postgres:16-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 10
  api:
    build: .
    depends_on:
      db:
        condition: service_healthy
```

**Inspect:**

```shellscript
docker inspect --format='{{.State.Health.Status}}' <container>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Checking TCP port open ≠ app ready — hit a real `/health` when possible.
* Too-aggressive intervals spam logs and CPU.
* Healthcheck tools must exist in the image (`curl`/`wget` often missing on alpine/distroless).

## 🔗 Related [#-related]

* [compose.md](/docs/docker/compose)
* [dockerfile.md](/docs/docker/dockerfile)
* [networks.md](/docs/docker/networks)
* [getting\_started.md](/docs/docker/getting-started)


---

# Images & Tags (/docs/docker/images-tags)



# Images & Tags [#images--tags]

*Docker · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Images are addressed as `name:tag` (and digests). Tags are mutable labels — pin carefully for production reproducibility.

## 🔧 Core concepts [#-core-concepts]

| Reference           | Example              |
| ------------------- | -------------------- |
| Official short name | `nginx:alpine`       |
| Namespaced          | `grafana/grafana:11` |
| Digest pin          | `nginx@sha256:…`     |
| Local tag           | `myapp:dev`          |

| Command                             | Purpose          |
| ----------------------------------- | ---------------- |
| `docker images` / `docker image ls` | List             |
| `docker tag`                        | Add another name |
| `docker push` / `pull`              | Registry sync    |
| `docker rmi`                        | Remove image     |
| `docker image prune`                | Clean dangling   |

| Tag hygiene | Prefer                                  |
| ----------- | --------------------------------------- |
| Prod        | Digests or immutable tags (`1.2.3`)     |
| Base images | Distroless / alpine / slim thoughtfully |
| Avoid       | Floating `latest` in prod deploys       |

## 💡 Examples [#-examples]

**Tag and push:**

```shellscript
docker build -t ghcr.io/acme/api:1.4.0 .
docker push ghcr.io/acme/api:1.4.0
```

**Retag:**

```shellscript
docker tag myapp:dev myapp:1.4.0
```

**Remove dangling:**

```shellscript
docker image prune -f
```

## ⚠️ Pitfalls [#️-pitfalls]

* `latest` moves — yesterday’s deploy may not equal today’s pull.
* Deleting a tag on the registry does not delete all digests immediately.
* Huge images slow pulls — multi-stage builds and `.dockerignore` help.

## 🔗 Related [#-related]

* [dockerfile.md](/docs/docker/dockerfile)
* [multi\_stage.md](/docs/docker/multi-stage)
* [getting\_started.md](/docs/docker/getting-started)
* [compose.md](/docs/docker/compose)


---

# Multi-stage Builds (/docs/docker/multi-stage)



# Multi-stage Builds [#multi-stage-builds]

*Docker · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Multi-stage Dockerfiles use multiple `FROM` stages so build tools stay out of the final runtime image. Smaller, safer production images.

## 🔧 Core concepts [#-core-concepts]

| Pattern             | Role                              |
| ------------------- | --------------------------------- |
| `AS name`           | Name a stage                      |
| `COPY --from=stage` | Copy artifacts only               |
| Builder stage       | Compile, `npm ci`, tests optional |
| Runtime stage       | Minimal base + binary/dist        |

| Benefit          | Why                     |
| ---------------- | ----------------------- |
| Smaller image    | No compilers/toolchains |
| Fewer CVEs       | Less software surface   |
| Clear separation | Build vs run            |

## 💡 Examples [#-examples]

**Go binary:**

```dockerfile
FROM golang:1.22 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /out/app

FROM gcr.io/distroless/static
COPY --from=build /out/app /app
USER nonroot
ENTRYPOINT ["/app"]
```

**Node (deps → build → run):**

```dockerfile
FROM node:22-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app/dist ./dist
COPY --from=deps /app/node_modules ./node_modules
COPY package.json .
CMD ["node", "dist/server.js"]
```

## ⚠️ Pitfalls [#️-pitfalls]

* Copying entire `node_modules` from a build stage may include devDependencies — use production installs in the final stage.
* Forgetting `.dockerignore` still bloats build context even with multi-stage.
* Debugging is harder — keep a `debug` stage target when needed (`docker build --target`).

## 🔗 Related [#-related]

* [dockerfile.md](/docs/docker/dockerfile)
* [images\_tags.md](/docs/docker/images-tags)
* [env\_secrets.md](/docs/docker/env-secrets)
* [getting\_started.md](/docs/docker/getting-started)


---

# Networks (/docs/docker/networks)



# Networks [#networks]

*Docker · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Docker networks connect containers. Compose creates a default network so services resolve each other by service name as DNS.

## 🔧 Core concepts [#-core-concepts]

| Driver    | Use                              |
| --------- | -------------------------------- |
| `bridge`  | Default single-host network      |
| `host`    | Share host network stack (Linux) |
| `none`    | No networking                    |
| `overlay` | Swarm multi-host                 |

| Concept          | Detail                                 |
| ---------------- | -------------------------------------- |
| Service DNS      | `http://api:9000` from another service |
| Publish ports    | Expose to host via `-p`                |
| Internal network | No external connectivity               |

## 💡 Examples [#-examples]

**Inspect defaults:**

```shellscript
docker network ls
docker network inspect bridge
```

**User-defined bridge:**

```shellscript
docker network create appnet
docker run -d --name db --network appnet postgres:16-alpine
docker run -d --name api --network appnet -p 9000:9000 myapi
```

**Compose networks:**

```yaml
services:
  api:
    networks: [frontend, backend]
  db:
    networks: [backend]
networks:
  frontend:
  backend:
    internal: true
```

## ⚠️ Pitfalls [#️-pitfalls]

* Using host `localhost` to reach another container fails — use DNS name.
* Publishing every port widens attack surface — only publish what you need.
* `host` network mode breaks container isolation assumptions.

## 🔗 Related [#-related]

* [compose.md](/docs/docker/compose)
* [getting\_started.md](/docs/docker/getting-started)
* [healthchecks.md](/docs/docker/healthchecks)
* [volumes.md](/docs/docker/volumes)


---

# Volumes (/docs/docker/volumes)



# Volumes [#volumes]

*Docker · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Volumes persist data beyond a container’s lifecycle and share files between host and container. Prefer named volumes for databases; bind mounts for live code in development.

## 🔧 Core concepts [#-core-concepts]

| Type             | Behavior                         |
| ---------------- | -------------------------------- |
| Named volume     | Docker-managed storage           |
| Bind mount       | Host path mounted into container |
| Anonymous volume | Unnamed; easy to lose track of   |
| tmpfs            | In-memory mount                  |

| Flag                  | Example            |
| --------------------- | ------------------ |
| `-v name:/path`       | Named volume       |
| `-v /host:/container` | Bind mount         |
| `--mount`             | Explicit long form |

## 💡 Examples [#-examples]

**Named volume for Postgres:**

```shellscript
docker volume create pgdata
docker run -v pgdata:/var/lib/postgresql/data postgres:16
```

**Compose volume:**

```yaml
services:
  db:
    image: postgres:16-alpine
    volumes:
      - pgdata:/var/lib/postgresql/data
volumes:
  pgdata:
```

**Dev bind mount:**

```shellscript
docker run --rm -v "${PWD}:/app" -w /app node:22 npm test
```

## ⚠️ Pitfalls [#️-pitfalls]

* Bind-mounting over a path that had image data hides the image content.
* Permissions (UID/GID) on Linux bind mounts often break writes — match users.
* `docker compose down -v` deletes named volumes — destructive.

## 🔗 Related [#-related]

* [compose.md](/docs/docker/compose)
* [getting\_started.md](/docs/docker/getting-started)
* [env\_secrets.md](/docs/docker/env-secrets)
* [networks.md](/docs/docker/networks)

