← Interview Questions
Docker60+ Questions · Beginner to Expert
Docker Interview Questions & Answers (2026)
60+ Docker questions with expert answers covering containers vs VMs, Dockerfiles, multi-stage builds, networking, volumes, Docker Compose, and container security best practices.
Beginner
Q: What is Docker and what problem does it solve?
Docker is an open-source platform for building, shipping, and running applications in containers. A container is a lightweight, standalone, executable package that includes everything needed to run an application: code, runtime, system libraries, environment variables, and configuration files.
**The problem Docker solves — "it works on my machine":**
Before containers, a developer would write code on their laptop, and it would work perfectly in their environment. Then operations would try to deploy it to a server with a different OS version, different library versions, or different environment variables — and it would fail. Hours of debugging would follow.
Docker packages the application and its entire environment together as an immutable image. The same image runs identically on a developer's laptop, a CI server, a staging environment, and production — eliminating environment inconsistency.
**Containers vs. Virtual Machines:**
- **VMs:** Virtualize the entire hardware stack. Each VM runs a full OS kernel. Heavy (GBs per VM), slow to start (minutes).
- **Containers:** Share the host OS kernel. Virtualize only at the process level using Linux namespaces and cgroups. Lightweight (MBs), fast to start (milliseconds).
**Docker core concepts:**
- **Image:** A read-only template for creating containers. Defined by a Dockerfile. Stored in registries (Docker Hub, ECR, GCR).
- **Container:** A running instance of an image. Stateful (but ephemeral by default).
- **Registry:** A storage and distribution system for Docker images.
- **Docker Engine:** The runtime that builds and runs containers.
Q: What is a Dockerfile and what are the most common instructions?
A Dockerfile is a text file containing a series of instructions that Docker uses to build a container image. Each instruction creates a new layer in the image.
**Common Dockerfile instructions:**
**FROM** — Specifies the base image. Every Dockerfile must start with FROM.
```dockerfile
FROM python:3.11-slim
```
**WORKDIR** — Sets the working directory for subsequent instructions.
```dockerfile
WORKDIR /app
```
**COPY / ADD** — Copies files from the build context into the image. Use COPY (not ADD) unless you need URL downloading or automatic tar extraction.
```dockerfile
COPY requirements.txt .
COPY . .
```
**RUN** — Executes a command during the build phase. Creates a new image layer.
```dockerfile
RUN pip install --no-cache-dir -r requirements.txt
```
**ENV** — Sets environment variables available during build and runtime.
```dockerfile
ENV PORT=8000 PYTHONUNBUFFERED=1
```
**EXPOSE** — Documents which port the container listens on (informational only — does not publish the port).
```dockerfile
EXPOSE 8000
```
**CMD** — Default command to run when the container starts. Can be overridden at runtime.
```dockerfile
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
```
**ENTRYPOINT** — Configures the container to run as an executable. Unlike CMD, it cannot be easily overridden. Use for wrapping scripts.
**USER** — Sets the user for subsequent instructions and the container runtime (use non-root for security).
```dockerfile
USER appuser
```
Intermediate
Q: What is a multi-stage Docker build and why is it important?
Multi-stage builds allow you to use multiple FROM statements in a single Dockerfile, using one stage to build the application and another (smaller) stage for the final runtime image.
**The problem without multi-stage builds:**
A Python or Node.js application needs build tools (compilers, npm, pip, build dependencies) to build, but the final running container only needs the compiled output. Without multi-stage builds, the final image contains all the build tooling — making images unnecessarily large (GBs instead of MBs) and increasing the attack surface.
**Multi-stage build example (Python FastAPI):**
```dockerfile
# Stage 1: Build dependencies
FROM python:3.11 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt
# Stage 2: Production runtime image
FROM python:3.11-slim AS runtime
WORKDIR /app
# Copy only the installed packages from builder
COPY --from=builder /root/.local /root/.local
# Copy application code
COPY . .
# Run as non-root user
RUN useradd -m appuser
USER appuser
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
```
**Benefits:**
- **Smaller images:** Only the runtime is included. A Go application that compiles to a 10MB binary can run in a scratch/distroless image instead of a 800MB golang builder image.
- **Security:** Build tools (compilers, pip, make) are not in the production image — smaller attack surface.
- **Layer caching:** Dependencies stage only rebuilds when requirements.txt changes; the code copy happens in a later, faster step.
**Distroless images (Google):** For maximum security and minimal size, the runtime stage can use a Google Distroless image — which contains only the runtime (Python, Java, Node.js) without package managers, shells, or other tools. Dramatically reduces vulnerabilities.
Q: Explain Docker networking modes.
Docker provides several network drivers, each suitable for different use cases.
**bridge (default):**
The default network mode. Docker creates a virtual bridge network (docker0) on the host. Containers connected to the same bridge network can communicate using container names as DNS. Containers are isolated from the host network by default.
```bash
docker run --network bridge nginx
```
**host:**
Removes network isolation — the container shares the host's network namespace. The container uses the host's IP and ports directly. Best performance, but no port isolation.
- Use for: performance-critical workloads (network-intensive databases), sidecar containers that need to bind to host ports.
```bash
docker run --network host nginx
```
**none:**
No networking. The container has a network namespace but no external connectivity. Used for completely isolated workloads.
**overlay:**
Connects containers across multiple Docker hosts (Docker Swarm). Allows containers on different machines to communicate as if on the same network. Uses VXLAN tunneling.
**macvlan:**
Assigns a MAC address to a container, making it appear as a physical device on the network. Containers get IPs on the physical network. Use for migrating legacy apps that need to be directly addressable on the physical LAN.
**Custom bridge networks:**
The recommended approach for multi-container applications. Unlike the default bridge network, custom bridge networks:
- Provide automatic DNS resolution between containers by name.
- Better isolation — only containers on the same custom network can communicate.
- Can be configured with specific subnets and gateways.
```bash
docker network create app-network
docker run --network app-network --name db postgres
docker run --network app-network --name api -e DB_HOST=db myapi
```
Advanced / Security
Q: What are Docker container security best practices?
Container security is a layered concern — you need to secure the image, the runtime, and the orchestration layer.
**Image security:**
1. **Use minimal base images:** `alpine`, `distroless`, or `scratch`. Fewer packages = fewer vulnerabilities. A Debian full image has 400+ potential CVEs; a distroless Python image has <20.
2. **Never run as root:** Add a non-root user in your Dockerfile:
```dockerfile
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
```
Running as root means a container escape vulnerability gives full host access.
3. **Scan images in CI:** Use Trivy, Snyk, or Grype to scan images for CVEs before pushing. Block critical CVE deployments with CI gates:
```bash
trivy image --exit-code 1 --severity CRITICAL myapp:latest
```
4. **Use image signing:** Sign images with Cosign (Sigstore) and verify signatures before deployment. Prevents tampered images from being deployed.
5. **Pin base image versions:** Use specific digests, not tags. `FROM python:3.11.4@sha256:abc123` is immutable; `FROM python:3.11` can change unexpectedly.
**Runtime security:**
6. **Read-only filesystem:** Mount the container filesystem as read-only where possible. Prevents malware from persisting files:
```yaml
securityContext:
readOnlyRootFilesystem: true
```
7. **Drop capabilities:** Containers inherit Linux capabilities. Drop all and add only what is needed:
```yaml
securityContext:
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
```
8. **Set resource limits:** Prevent a compromised container from consuming all host resources (CPU, memory):
```yaml
resources:
limits:
cpu: "500m"
memory: "256Mi"
```
9. **Use seccomp profiles:** Restrict which Linux system calls a container can make. Docker applies a default seccomp profile; more restrictive profiles provide stronger isolation.
10. **Network policies:** In Kubernetes, apply NetworkPolicies to restrict which services can communicate with each other — default deny all, allow only explicitly needed paths.
**Runtime threat detection:**
- **Falco:** Open-source runtime security tool that monitors container behavior using eBPF and alerts on suspicious activity (e.g., shell executed in a container, sensitive file read, unexpected network connection).
Also Prepare Your Resume
A great interview starts with getting the interview call.