Interview Q&A All Levels Docker

Docker Interview Questions and Answers(2026) Part 01

All Interview questions related to Docker tool

April 7, 2026 16 min read DB
Level:

🟢 Basic

Ans: Docker is a containerization platform that allows us to package an application along with all its dependencies, libraries, and configurations into a single unit called a container.

The main reason we use Docker is to ensure that the application runs consistently across different environments like development, testing, staging and production without any issues like “it works on my machine but not on yours”.

It also helps in faster deployment, better resource utilization compared to virtual machines, and makes scaling applications easier because we can quickly spin up multiple containers when needed.

For example: if I build a Docker container for a Node.js app, I can run the same container on my local system, a testing server, or in production, and it will behave exactly the same everywhere.

Ans: The main difference between a Docker image and a Docker container is that an image is a template, while a container is a running instance of that template.

  • A Docker image is a read-only package that includes the application code, dependencies, libraries, and environment needed to run the application. It doesn’t change and is used to create containers.

  • A Docker container, on the other hand, is the actual running environment created from the image. It is live, can be started or stopped, and you can run multiple containers from the same image.

In simple terms, I think of a Docker image as a blueprint and a Docker container as the actual running application created from that blueprint.

ImageContainer
DefinitionRead-only blueprint/templateRunning instance of an image
StateStatic (immutable)Dynamic (can be started/stopped/deleted)
StorageStored on diskLives in memory + writable layer

Ans: A Dockerfile is a script or configuration file that contains a set of instructions to build a Docker image.

In a Dockerfile, we define things like the base image, application code, dependencies, environment variables, and the commands needed to run the application.

So instead of manually setting up everything, we just write a Dockerfile, and Docker automatically builds the image from it. This makes the process consistent, repeatable, and easy to automate.

Example of Dockerfile:

FROM node:18-alpine          # Base image
WORKDIR /app                 # Set working directory where all code build and run
COPY package*.json ./        # Copy application code files into image (/app) folder
RUN npm install              # Execute command to install applicaiton dependancies during build
COPY . .                     # Copy remaining source code into /app folder
EXPOSE 3000                  # Open 3000 Port in container to connect outside of docker container
ENV NODE_ENV=production      # Set environment variable 
CMD ["node", "server.js"]    # Default command to run

Ans: To build a Docker image, we use the Dockerfile and run the docker build command. This command reads the instructions from the Dockerfile and creates an image.

Step 1: Build Dokcer image

# Build image (tag it with -t)
docker build -t my-app:1.0 .

Step 2: Run Docker Container


# Run a docker container
docker run -d --name my-app-container  -p 8080:3000 my-app:1.0

# -d    = detached mode (Container running in background)
# -p    = host_port:container_port
# --name = assign a name to docker container

Ans: Docker Hub is the default public registry for Docker images. It hosts official images (like nginx, postgres, node) and allows users to publish their own images.

# Login to Docker Hub
docker login   # Enter Username and Password

# Tag your image for Docker Hub
docker tag my-app:1.0 yourusername/my-app:1.0

# Push to Docker Hub
docker push yourusername/my-app:1.0

# Pull someone else's image
docker pull yourusername/my-app:1.0

Ans: There are following components:

  1. Docker Engine: Also known as the Docker daemon, this is the core of Docker. It is a lightweight runtime and an efficient, scalable and secure containerization technology combined with a work flow for building and containerizing your applications.

  2. Docker CLI: The Docker command-line interface (CLI) is used to interact with Docker. It allows you to build, run, and manage Docker containers and images.

  3. Dockerfile: A Dockerfile is a text file that contains instructions for building a Docker image. It defines the environment in which the application will run, including the base image, dependencies, and runtime configuration.

  4. Docker Images: Images are read-only templates that contain the necessary operating system, application, and runtime components. They serve as the basis for containers. You can create your own images or use pre-built images from the Docker Hub or other registries.

  5. Docker Containers: Containers are instances of Docker images. They are lightweight and portable encapsulations of an environment in which to run applications. Containers are isolated from each other and from the host system. They can be started, stopped, and deleted, and their resources can be dynamically allocated.

  6. Docker Compose: Docker Compose is a tool for defining and running multi-container Docker applications. It uses a YAML file to define services, networks, and volumes

  7. Docker Swarm: Docker Swarm is a native clustering and orchestration tool for Docker. It allows you to create and manage a cluster of Docker nodes, and to deploy and manage services across the cluster.

  8. Docker Hub: Docker Hub is the official registry for Docker images. It allows you to find, store, and share Docker images.


🟡 Intermediate

Ans: Docker Compose is a tool for defining and running multi-container applications using a single YAML file (docker-compose.yml). It’s ideal for local development and testing.

version: "3.9"

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:pass@db:5432/mydb
    depends_on:
      - db

  db:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - pg_data:/var/lib/postgresql/data

volumes:
  pg_data:
docker compose up -d       # Start all services
docker compose down        # Stop and remove containers
docker compose logs -f     # Follow logs
docker compose ps          # Status of services

Ans: Docker volumes and bind mounts are both used to persist data outside the container, but the main difference is in how they are managed.

  • Docker volumes are managed by Docker itself. They are stored in a specific location on the host and are easier to manage, more secure, and work well across different environments. They are generally the preferred way to persist data in production.

  • Bind mounts, on the other hand, directly map a file or directory from the host machine into the container. This gives more control, but it also depends on the host’s file structure, so it’s less portable and can cause issues if the path doesn’t exist.

In short, volumes are Docker-managed and more portable, while bind mounts are host-managed and more flexible but less portable

VolumeBind Mount
Managed byDockerHost OS
Path/var/lib/docker/volumes/Any path on host
PortabilityHighLow
Use caseProduction, databasesLocal dev, live reload

Tip: Prefer volumes in production; use bind mounts in development for live code reload.

Ans: Docker networking allows containers to communicate with each other, as well as with the host machine and external networks.

By default, Docker creates a network so that containers can talk to each other using IP addresses or container names. It basically handles isolation and communication between containers.

  • Docker Network Types:
    • Bridge
    • Host
    • None
    • Overlay
DriverDescriptionUse Case
bridgeThis is the default network. Containers on the same bridge network can communicate with each other, and we can expose ports to access them from the host.Most containers
hostthe container shares the host’s network directly, so there’s no isolation. It’s faster, but less secure because the container uses the host’s ports.Performance-critical apps
noneIn this case, the container has no network access at all. It’s completely isolated.Fully isolated tasks
overlayThis is used in multi-host environments like Docker Swarm. It allows containers running on different machines to communicate with each other.Docker Swarm / Kubernetes

Ans: Multi-stage builds use multiple FROM statements in a single Dockerfile, allowing you to copy only the artifacts you need from earlier stages. This drastically reduces final image size.

# --- Stage 1: Build ---
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build          # Produces /app/dist

# --- Stage 2: Production ---
FROM node:18-alpine AS production
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist   # Only copy build output
EXPOSE 3000
CMD ["node", "dist/server.js"]

Result: The final image contains no dev dependencies, source code, or build tools — only what’s needed to run.

docker build --target production -t my-app:prod .

Ans: There are multiple ways to inject environment variables:

# 1. Inline with -e
docker run -e NODE_ENV=production -e PORT=3000 my-app

# 2. From a .env file
docker run --env-file .env my-app

# 3. In docker-compose.yml
# docker-compose.yml
services:
  app:
    image: my-app
    environment:
      NODE_ENV: production
      PORT: 3000
    env_file:
      - .env.production
# 4. Baked into the image (not recommended for secrets)
ENV NODE_ENV=production

⚠️ Never bake secrets (passwords, API keys) into images. Use .env files, Docker secrets, or a secrets manager like Vault.

Ans: Both copy files into the image, but ADD has extra functionality:

FeatureCOPYADD
syntaxCOPY <source> <destination>add
PurposeCopies files and directories from the host system into the Docker image.Copies files and directories from the host system as well as from remote urls into the Docker image
sourceSupports local files and directories.Supports local files and directories, URLs, and compressed files.
DestinationMust be a directory within the image.Can be a directory or a file within the image.
PermissionsPreserves the source file permissions.Applies default permissions of 600 (user: read/write) or 700 (directory) for files and 755 (user: read/write/execute) or 711 (directory) for directories.
Extracting compressed filesNAAutomatically extracts compressed files (e.g., *.tar, *.tar.gz, *.tgz, *.tar.bz2, *.tbz2, *.tar.xz, *.txz) during the copy process.
CachingDoes not cache remote URLs.Caches remote URLs to avoid re-downloading the files if the URLs haven’t changed.
MD5 HashNACompares the MD5 hash of the local file with the hash in the cache to determine if the file has changed and needs to be downloaded again.
featureSimple and straightforward.Supports more features, such as extracting compressed files, caching remote URLs, and comparing MD5 hashes.
RecommendationUse when copying local files and directories.Use when copying local files and directories, as well as URLs or compressed files, and when you want to take advantage of caching and MD5 hash checking.
# Preferred - explicit and predictable
COPY ./src /app/src
COPY package.json /app/

# Use ADD only when you need tar extraction
ADD app.tar.gz /app/

# Avoid ADD for URLs - use curl/wget in RUN instead
RUN curl -o /tmp/file.zip https://example.com/file.zip

Best practice: Always prefer COPY unless you specifically need ADD’s extra features.

Ans:

Note: You can use Container_id or Container_name to inspect and debug the logs

# Get a shell inside a running container
docker exec -it <container_id> /bin/sh     # Alpine/minimal images
docker exec -it <container_id> /bin/bash   # Debian/Ubuntu images

# View real-time logs
docker logs -f <container_id>
docker logs --tail 100 <container_id>

# Inspect container config, network, mounts
docker inspect <container_id>

# Resource usage (CPU, memory, I/O)
docker stats <container_id>

# Copy files out of a container
docker cp <container>:/app/logs/error.log ./error.log

# View processes inside container
docker top <container_id>

# View filesystem changes since container started
docker diff <container_id>

Ans:

# --- Containers ---
docker ps                     # List running containers
docker ps -a                  # List all containers (including stopped)
docker stop <name|id>         # Gracefully stop a container
docker kill <name|id>         # Force stop a container
docker rm <name|id>           # Remove a stopped container
docker rm -f <name|id>        # Force remove (even if running)

# --- Images ---
docker images                 # List all images
docker rmi <image_id>         # Remove an image
docker image prune            # Remove all unused images

# --- Cleanup everything ---
docker system prune -a        # Remove all unused containers, images, networks
Ans: No, Unless you delete the container, any data stored in this docker container will not loose.

Ans:

Step 01: Stop the Docker container

docker container stop <container_id or container_name>

Step 02: Remove the Docker container

docker rm <container_id or container_name>

Ans: Yes,containers can restart by themselves, but only if you configure them to do so. By default, a container does NOT auto-restart when it stops or crashes. You need a restart policy.

Docker provides built-in restart policies:

  1. no → (default) never restart
  2. always → always restart if stopped/crashed
  3. unless-stopped → restart unless you manually stop it
  4. on-failure → restart only if container exits with error

How to assign policy to Docker container:

docker run -d --restart=always nginx

Ans: No, you can’t remove a paused container directly. Docker won’t allow it because a paused container is still considered running (just frozen).

Correct way to remove a paused container:

UnpauseStopRemove


🔴 Advanced

Ans: Docker builds images in layers — each instruction in a Dockerfile creates one layer. Layers are cached and reused if the instruction and its context haven’t changed.

Cache invalidation rule: Once a layer changes, all subsequent layers are rebuilt.

# ❌ BAD - COPY . . early invalidates cache on every code change
FROM node:18-alpine
WORKDIR /app
COPY . .                    # Invalidated on ANY file change
RUN npm install             # Reinstalls everything each time!

# ✅ GOOD - Copy dependency files first, leverage caching
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./       # Only changes when deps change
RUN npm install             # Cached until package.json changes
COPY . .                    # App code changes don't bust npm cache
RUN npm run build

Other optimization tips:

  • Combine RUN commands with && to reduce layers
  • Use .dockerignore to exclude node_modules, .git, build artifacts
  • Order instructions from least-changing to most-changing
  • Use --mount=type=cache (BuildKit) for package manager caches
# BuildKit cache mount for faster builds
RUN --mount=type=cache,target=/root/.npm \
    npm ci

Ans: Both are container orchestration platforms, but they differ in complexity and capability:

FeatureDocker SwarmKubernetes
Setup complexitySimpleComplex
Learning curveLowHigh
ScalabilityModerateEnterprise-grade
Auto-healingBasicAdvanced
EcosystemDocker-nativeMassive (CNCF)
Use caseSmall/medium teamsLarge-scale production
# Initialize a Swarm cluster
docker swarm init --advertise-addr <manager-ip>

# Deploy a stack (like docker-compose for Swarm)
docker stack deploy -c docker-compose.yml myapp

# Scale a service
docker service scale myapp_web=5

# List services
docker service ls

# Rolling update
docker service update --image my-app:2.0 myapp_web

When to choose what:

  • Swarm → simpler apps, small teams, already using Docker Compose
  • Kubernetes → complex microservices, multi-cloud, large engineering teams

Ans: Never store secrets as environment variables in images or plain docker-compose.yml. Use proper secrets management:

Option 1: Docker Secrets (Swarm mode)

# Create a secret
echo "super_secret_password" | docker secret create db_password -

# Use in a service
docker service create \
  --name myapp \
  --secret db_password \
  my-app:latest

Inside the container, secrets are available at /run/secrets/db_password.

Option 2: Docker Compose secrets (for dev)

services:
  app:
    image: my-app
    secrets:
      - db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt  # Never commit this file!

Option 3: External secrets managers (production)

# HashiCorp Vault, AWS Secrets Manager, Azure Key Vault
# Inject at runtime via init containers or sidecar patterns

Best practices:

  • Add secret files to .gitignore
  • Rotate secrets regularly
  • Use least-privilege access
  • Audit secret access in production

Ans:

# 1. Use minimal base images
FROM alpine:3.19                     # Small attack surface
FROM gcr.io/distroless/nodejs:18     # Distroless (no shell!)

# 2. Run as non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

# 3. Drop Linux capabilities
# In docker-compose.yml:
# cap_drop: [ALL]
# cap_add: [NET_BIND_SERVICE]

# 4. Read-only filesystem
# docker run --read-only --tmpfs /tmp my-app

# 5. Avoid storing secrets in ENV or layers
# Use Docker secrets or external vaults

# 6. Pin base image versions
FROM node:18.19.0-alpine3.19         # Pinned, not :latest
# Scan image for vulnerabilities
docker scout cves my-app:latest
# or
trivy image my-app:latest

# Run with security options
docker run \
  --read-only \
  --no-new-privileges \
  --cap-drop ALL \
  --security-opt seccomp=default \
  my-app:latest

Ans: Docker is not a VM — it uses Linux kernel features to create isolated processes:

Namespaces — provide isolation of system resources:

NamespaceIsolates
pidProcess IDs (container can’t see host processes)
netNetwork interfaces, IP tables, ports
mntFilesystem mount points
utsHostname and domain name
ipcInter-process communication
userUser and group IDs

Control Groups (cgroups) — limit and account for resource usage:

# Limit container to 512MB RAM and 1 CPU
docker run \
  --memory="512m" \
  --memory-swap="512m" \
  --cpus="1.0" \
  my-app

# View cgroup info for a container
cat /sys/fs/cgroup/memory/docker/<container-id>/memory.limit_in_bytes

Union Filesystem (OverlayFS) — layers images efficiently:

  • Each Dockerfile instruction creates a new read-only layer
  • Running container gets a thin writable layer on top
  • Layers are shared between containers using the same image → saves disk space
# See the layers of an image
docker history my-app:latest

# Inspect overlay filesystem
docker inspect my-app | grep -A5 GraphDriver

Ans: Zero-downtime deployments require a strategy to transition traffic from old containers to new ones without service interruption.

Strategy 1: Docker Swarm rolling update

docker service update \
  --image my-app:2.0 \
  --update-parallelism 1 \
  --update-delay 10s \
  --update-failure-action rollback \
  myapp_web

Strategy 2: Blue-Green with Nginx + Compose

# docker-compose.blue-green.yml
services:
  app-blue:
    image: my-app:1.0
    networks: [proxy]

  app-green:
    image: my-app:2.0
    networks: [proxy]

  nginx:
    image: nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - "80:80"
    networks: [proxy]
# 1. Start green alongside blue
docker compose up -d app-green

# 2. Health check green
curl http://localhost/health

# 3. Switch Nginx upstream to green (update config + reload)
docker exec nginx nginx -s reload

# 4. Remove blue after confirming green is stable
docker compose stop app-blue

Strategy 3: Kubernetes (Deployment rollout)

kubectl set image deployment/my-app my-app=my-app:2.0
kubectl rollout status deployment/my-app
kubectl rollout undo deployment/my-app   # Rollback if needed

Ans: Both define the command that runs when a container starts, but they behave differently:

CMDENTRYPOINT
SyntaxCMD [“executable”,“param1”,“param2”]ENTRYPOINT [“executable”,“param1”,“param2”]
PurposeDefault arguments (can be overridden)Fixed executable (cannot be overridden easily)
OverrideAny CMD in the Dockerfile is overridden by docker run arguments.ENTRYPOINT is not overridden by docker run arguments.
DefaultIf no CMD is specified in the Dockerfile, it uses the default one from the base image.If no ENTRYPOINT is specified in the Dockerfile, it uses the default one from the base image.
Multiple commandsOnly one CMD instruction can be used.Multiple ENTRYPOINT instructions can be used.
# CMD - easily overridden
CMD ["node", "server.js"]

# ENTRYPOINT - fixed executable
ENTRYPOINT ["node"]
CMD ["server.js"]   # default arg, can be overridden

# Run: docker run my-app debug.js
# → executes: node debug.js

Best practice: Use ENTRYPOINT for the main executable and CMD for default arguments.

Add More Questions to This Guide

Know questions that should be here? Share them and help the community!

Open Google Form