OpsSquad.ai
Blog/DevOps/·39 min read
DevOps

Docker Interview Questions: Master Your Next DevOps Role

Ace your Docker interviews with essential questions on images, containers, networking, volumes, and security. Learn manual troubleshooting and automate with OpsSqad.

Share
Docker Interview Questions: Master Your Next DevOps Role

Master Your Docker Interview: Essential Questions and Real-World Solutions

Docker interviews are a crucial step for many DevOps, SRE, and developer roles. Beyond memorizing definitions, interviewers want to see your practical understanding of how Docker works, how to troubleshoot common issues, and how to leverage its power effectively. This guide dives deep into the most frequently asked Docker interview questions, providing clear explanations, practical commands, and scenario-based problem-solving to help you ace your next interview.

TL;DR: This comprehensive guide covers 40+ essential Docker interview questions across fundamentals, networking, volumes, orchestration, and security. You'll learn not just what Docker is, but how to debug containers, optimize images, manage multi-container applications, and troubleshoot production issues. Each section includes working commands, real-world scenarios, and practical tips from production environments.

1. Docker Fundamentals: The Core Concepts You Need to Know

This section lays the groundwork, ensuring you have a solid grasp of Docker's fundamental building blocks. Understanding these concepts is paramount before delving into more complex topics.

What is Docker?

Problem: Interviewers want to know if you understand Docker's purpose and value proposition.

Explanation: Docker is an open-source platform that automates the deployment, scaling, and management of applications using containerization. It allows developers to package an application with all its dependencies into a standardized unit for software development. At its core, Docker solves the "works on my machine" problem by ensuring consistency across development, testing, and production environments.

Key Benefits:

  • Consistency across environments: The same container runs identically on your laptop, staging server, and production cluster
  • Faster deployment: Containers start in seconds compared to minutes for VMs
  • Resource efficiency: Multiple containers share the host OS kernel, using far less memory and CPU than equivalent VMs
  • Isolation: Each container runs in its own isolated process space with dedicated filesystem and network stack

In production environments, Docker enables microservices architectures where each service runs in its own container, making it easier to scale individual components, roll back failed deployments, and maintain complex applications.

What is a Docker Image?

Problem: Differentiating between images and containers is a common interview point.

Explanation: A Docker image is a read-only template that contains the instructions for creating a Docker container. It's a snapshot of a filesystem and metadata, including the application, libraries, dependencies, and environment variables. Images are built in layers, with each instruction in a Dockerfile creating a new layer. This layered architecture enables efficient storage and fast distribution because layers are cached and reused.

Analogy: Think of it as a blueprint or a recipe. The image defines what the container will contain, but it's not running anything yet.

Commands:

# List local Docker images
docker images
 
# Example output:
# REPOSITORY          TAG       IMAGE ID       CREATED         SIZE
# nginx               latest    605c77e624dd   2 weeks ago     141MB
# ubuntu              20.04     ba6acccedd29   3 weeks ago     72.8MB
# Download an image from a registry
docker pull nginx:1.21-alpine
 
# Build an image from a Dockerfile in the current directory
docker build -t myapp:v1.0 .
 
# Tag an existing image for pushing to a registry
docker tag myapp:v1.0 myregistry.com/myapp:v1.0

Note: Image tags are crucial for version management. Always use specific version tags in production rather than latest to ensure reproducible deployments.

What is a Docker Container?

Problem: Understanding the runtime instance of an image.

Explanation: A Docker container is a runnable instance of a Docker image. It's a lightweight, isolated process that runs on the host operating system's kernel. When you run a container, Docker creates a writable layer on top of the read-only image layers, allowing the container to modify files without affecting the underlying image. Multiple containers can run from the same image simultaneously, each with its own writable layer and isolated state.

Analogy: The actual running application built from the blueprint. If the image is the recipe, the container is the cake you baked from it.

Commands:

# Create and start a container from an image
docker run -d --name webserver -p 8080:80 nginx:latest
 
# List running containers
docker ps
 
# Example output:
# CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                  NAMES
# a3f5c2d1e4b6   nginx:latest   "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   0.0.0.0:8080->80/tcp   webserver
# List all containers (running and stopped)
docker ps -a
 
# Stop a running container gracefully (sends SIGTERM, waits 10 seconds, then SIGKILL)
docker stop webserver
 
# Start a stopped container
docker start webserver
 
# Remove a stopped container
docker rm webserver
 
# Force remove a running container
docker rm -f webserver

Warning: Containers are ephemeral by design. Any data written to the container's writable layer is lost when the container is removed. Always use volumes for persistent data.

How is Docker Different from a Virtual Machine (VM)?

Problem: A classic comparison question to test your understanding of virtualization vs. containerization.

Explanation:

Virtual Machines virtualize the hardware layer. Each VM runs a full guest operating system on top of a hypervisor (like VMware ESXi, KVM, or Hyper-V). This means every VM includes a complete OS with its own kernel, system libraries, and binaries. A host running three VMs might have three complete Linux installations, each consuming 1-2GB of RAM just for the OS.

Docker containers virtualize the operating system level. Containers share the host OS kernel, making them much lighter and faster to start. They package only the application and its dependencies, not an entire operating system. This architectural difference has profound implications:

Key Differences:

AspectVirtual MachinesDocker Containers
OS DependencyEach VM runs its own OSShare host OS kernel
Startup TimeMinutesSeconds
Resource OverheadGBs of RAM, significant CPUMBs of RAM, minimal CPU
Isolation LevelComplete hardware-level isolationProcess-level isolation
Density10-20 VMs per host100-1000 containers per host
PortabilityLarge image files (GBs)Small image files (MBs)

Similarities: Both provide isolation, allow running multiple applications on a single host, enable resource limits (CPU, memory), and support snapshots and versioning.

In practice, many organizations use both: VMs for strong isolation boundaries between tenants or security zones, and containers for application deployment within those VMs.

Does a Docker Container Package the Entire OS?

Problem: Clarifying the misconception about container contents.

Explanation: No, a Docker container does not package the entire operating system. It packages the application and its dependencies, including libraries and binaries, but it shares the host's kernel. This is what makes containers so lightweight compared to VMs.

When you see a Dockerfile starting with FROM ubuntu:20.04, it's not including the Linux kernel. It's including the Ubuntu userland tools and libraries—things like bash, apt, and system libraries. The container uses the host's kernel for all system calls.

This has an important implication: you cannot run a Windows container on a Linux host (without virtualization) because they require different kernels. However, you can run different Linux distributions (Ubuntu, Alpine, CentOS) as containers on the same Linux host because they all use the Linux kernel.

2. Dockerfiles and Docker Compose: Building and Orchestrating Applications

This section focuses on how to define, build, and manage multi-container applications.

What is a Dockerfile?

Problem: Understanding the recipe for building Docker images.

Explanation: A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. It's the primary way to automate image creation, ensuring reproducible builds across different environments. Each instruction in a Dockerfile creates a new layer in the image, and Docker caches these layers to speed up subsequent builds.

Key Instructions:

  • FROM: Specifies the base image
  • RUN: Executes commands during build (installing packages, creating directories)
  • COPY: Copies files from host to image
  • ADD: Like COPY but with additional features (auto-extraction of archives, URL support)
  • WORKDIR: Sets the working directory for subsequent instructions
  • EXPOSE: Documents which ports the container will listen on
  • ENV: Sets environment variables
  • CMD: Provides default command to run when container starts
  • ENTRYPOINT: Configures container to run as an executable

Example Dockerfile:

FROM ubuntu:20.04
LABEL maintainer="[email protected]"
LABEL version="1.0"
 
# Install nginx and clean up apt cache in same layer to reduce size
RUN apt-get update && \
    apt-get install -y nginx && \
    rm -rf /var/lib/apt/lists/*
 
# Copy application files
COPY ./html /var/www/html
COPY ./nginx.conf /etc/nginx/nginx.conf
 
# Set working directory
WORKDIR /var/www/html
 
# Expose port 80 for documentation
EXPOSE 80
 
# Run nginx in foreground
CMD ["nginx", "-g", "daemon off;"]

Best Practice: Combine multiple RUN commands with && to reduce the number of layers. Each layer adds to the final image size, even if you delete files in a later layer.

What is the Purpose of the .dockerignore File?

Problem: Preventing unnecessary files from being copied into the build context, leading to smaller images and faster builds.

Explanation: Similar to .gitignore, the .dockerignore file specifies intentionally undocumented files and directories that should be excluded from the build context sent to the Docker daemon. When you run docker build, Docker sends the entire directory context to the daemon. Without a .dockerignore file, this could include large files like node_modules, .git history, or log files that don't belong in your image.

Example .dockerignore:

# Dependencies
node_modules
vendor

# Version control
.git
.gitignore

# IDE files
.vscode
.idea
*.swp

# Logs and temporary files
*.log
*.tmp
temp/

# Docker files themselves
Dockerfile
docker-compose.yml
.dockerignore

# Documentation
README.md
docs/

# CI/CD
.github
.gitlab-ci.yml

Impact: A properly configured .dockerignore can reduce build context from hundreds of MBs to just a few MBs, dramatically speeding up builds, especially in CI/CD pipelines where the build context must be uploaded to a remote Docker daemon.

How is ENTRYPOINT Different from RUN in Dockerfile?

Problem: Understanding the execution phases and purposes of these instructions.

Explanation:

RUN executes commands during the image build process. It's used for installing packages, creating directories, downloading files, and any other setup needed to prepare the image. Each RUN instruction creates a new layer in the image. These commands run once during build and their results are baked into the image.

# Runs during build, result is saved in image layer
RUN apt-get update && apt-get install -y python3
RUN pip install flask

ENTRYPOINT configures a container that will run as an executable. It defines the command that will be executed when the container starts. Unlike RUN, this doesn't execute during build—it defines what happens at runtime.

# Runs every time container starts
ENTRYPOINT ["python3", "app.py"]

Advanced Usage: ENTRYPOINT and CMD work together. ENTRYPOINT sets the main command, and CMD provides default arguments that can be overridden:

ENTRYPOINT ["python3"]
CMD ["app.py"]

With this configuration:

  • docker run myimage runs python3 app.py
  • docker run myimage test.py runs python3 test.py

Use Case: Use RUN for build-time setup and ENTRYPOINT for the main application process. If you need a container that always runs a specific executable but allows argument customization, use ENTRYPOINT.

What is the Purpose of the EXPOSE Command in Dockerfile?

Problem: Documenting network ports.

Explanation: The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. It's primarily documentation—it tells users of your image which ports the application uses. However, it does not automatically publish the ports to the host. You must use -p or -P with docker run to actually map ports.

# Document that this container uses ports 80 and 443
EXPOSE 80 443
# Publish all exposed ports to random host ports
docker run -P myimage
 
# Explicitly map port 80 in container to port 8080 on host
docker run -p 8080:80 myimage

Note: EXPOSE is optional but highly recommended for clarity. It helps with documentation and works with docker run -P to automatically publish all exposed ports.

Why is the Build Cache Important in Docker?

Problem: Optimizing build times and reducing resource usage.

Explanation: Docker caches the results of each instruction in the Dockerfile. When you rebuild an image, Docker checks if the instruction and its context have changed. If not, it uses the cached layer, significantly speeding up the build process. This cache mechanism is critical for developer productivity and CI/CD performance.

How Cache Works:

  1. Docker processes Dockerfile instructions in order
  2. For each instruction, it checks if a cached layer exists
  3. For COPY and ADD, it compares file checksums
  4. For RUN, it checks if the exact command was run before
  5. If cache is valid, it reuses the layer; otherwise, it rebuilds and invalidates all subsequent cache

Best Practice - Order Instructions by Change Frequency:

# Bad: Application code changes frequently, invalidating all cache
FROM node:16
COPY . /app
RUN npm install
CMD ["node", "server.js"]
 
# Good: Dependencies change rarely, application code changes frequently
FROM node:16
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "server.js"]

In the optimized version, changing your application code doesn't invalidate the npm install cache because package.json hasn't changed.

Warning: Cache can cause issues if you're installing packages with apt-get or yum without version pinning. Use --no-cache flag to force a fresh build: docker build --no-cache -t myimage .

What is Docker Compose and How is it Different from a Dockerfile?

Problem: Understanding multi-container application management.

Explanation:

Dockerfile defines how to build a single Docker image. It's a build-time configuration that creates an image template.

Docker Compose is a tool for defining and running multi-container Docker applications. It uses a YAML file (docker-compose.yml) to configure application services, networks, and volumes. It's a runtime orchestration tool.

Key Difference: Dockerfile builds one image; Docker Compose orchestrates multiple containers derived from different images (or the same image multiple times).

Example docker-compose.yml:

version: '3.8'
 
services:
  web:
    build: ./web
    ports:
      - "8080:80"
    environment:
      - DATABASE_URL=postgresql://db:5432/myapp
    depends_on:
      - db
    networks:
      - app-network
 
  db:
    image: postgres:13
    environment:
      - POSTGRES_PASSWORD=secretpassword
      - POSTGRES_DB=myapp
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - app-network
 
networks:
  app-network:
    driver: bridge
 
volumes:
  postgres-data:

Commands:

# Create and start all services
docker-compose up -d
 
# View logs from all services
docker-compose logs -f
 
# List containers for the current Compose project
docker-compose ps
 
# Stop and remove containers, networks, and volumes
docker-compose down
 
# Rebuild services
docker-compose build
 
# Scale a service to multiple instances
docker-compose up -d --scale web=3

How to Declare Default Environment Variables in Docker Compose?

Problem: Providing configuration to services.

Explanation: Use the environment key within a service definition in docker-compose.yml. You can also use an .env file for values that should be kept out of version control.

Method 1: Inline Environment Variables

services:
  web:
    image: nginx
    environment:
      - NGINX_PORT=8080
      - LOG_LEVEL=info
      - ENVIRONMENT=production

Method 2: Using .env File

Create a .env file in the same directory as docker-compose.yml:

DATABASE_PASSWORD=secretpassword
API_KEY=abc123xyz

Reference in docker-compose.yml:

services:
  app:
    image: myapp:latest
    environment:
      - DB_PASSWORD=${DATABASE_PASSWORD}
      - API_KEY=${API_KEY}

Method 3: External env_file

services:
  app:
    image: myapp:latest
    env_file:
      - ./config/app.env
      - ./config/secrets.env

Best Practice: Never commit sensitive values like passwords or API keys to version control. Use .env files and add them to .gitignore.

Can You List Out Ways to Share Compose Configurations Between Files and Projects?

Problem: Reusability and modularity in complex setups.

Explanation:

1. Multiple Compose Files with Override:

# Base configuration
docker-compose.yml
 
# Development overrides
docker-compose.override.yml
 
# Production overrides
docker-compose.prod.yml
 
# Use specific override
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

2. Environment Variables:

services:
  web:
    image: nginx:${NGINX_VERSION:-latest}
    ports:
      - "${WEB_PORT:-8080}:80"

3. YAML Anchors and Aliases:

x-common-variables: &common-vars
  LOG_LEVEL: info
  ENVIRONMENT: production
 
services:
  web:
    environment:
      <<: *common-vars
      SERVICE_NAME: web
  
  api:
    environment:
      <<: *common-vars
      SERVICE_NAME: api

4. Extends (Deprecated but still used):

# common-services.yml
services:
  base-service:
    image: ubuntu:20.04
    environment:
      - TZ=UTC
 
# docker-compose.yml
services:
  web:
    extends:
      file: common-services.yml
      service: base-service

5. Include Directive (Compose v2.2+):

include:
  - ./compose/database.yml
  - ./compose/cache.yml
 
services:
  web:
    build: .
    depends_on:
      - db
      - redis

What's the Difference Between up, run, and start in Docker Compose?

Problem: Understanding the lifecycle commands.

Explanation:

docker-compose up creates and starts containers for all services defined in docker-compose.yml. If containers exist, it will start them. If they don't exist, it will create and start them. It also creates networks and volumes. This is the primary command for launching your entire application stack.

# Start all services in foreground
docker-compose up
 
# Start all services in background (detached mode)
docker-compose up -d
 
# Recreate containers even if config hasn't changed
docker-compose up -d --force-recreate

docker-compose run runs a one-off command in a new container for a specific service. It creates a new container each time it's run and does not link it into the existing Compose network by default. Useful for tasks like database migrations, running tests, or executing scripts.

# Run database migration
docker-compose run web python manage.py migrate
 
# Run interactive shell in a new container
docker-compose run --rm web bash
 
# Run command with service dependencies started
docker-compose run --service-ports web npm test

docker-compose start starts existing containers for services that were previously created and stopped. It doesn't create new containers or networks. Use this after docker-compose stop to resume your application.

# Stop services without removing containers
docker-compose stop
 
# Start the stopped services
docker-compose start

Practical Example:

  • Use up when first launching your app or after changing docker-compose.yml
  • Use run for one-time administrative tasks
  • Use start/stop for quick pause/resume of your application

3. Docker Networking: Connecting Your Containers

This section tackles the complexities of how containers communicate with each other and the outside world.

Explain Docker Networking and Different Network Types (Bridge, Overlay, Macvlan).

Problem: Understanding how containers get IP addresses and communicate.

Explanation: Docker provides several network drivers to manage container communication, each designed for different use cases:

Bridge Network (Default): Containers on the same bridge network can communicate with each other. Docker creates a virtual bridge (docker0 by default) on the host. Containers get IP addresses from a subnet managed by Docker (typically 172.17.0.0/16). Traffic to/from external networks is NATted through the host's IP address.

# Default bridge network
docker network ls
# NETWORK ID     NAME      DRIVER    SCOPE
# abc123def456   bridge    bridge    local

Use Case: Single-host deployments where containers need to communicate with each other and the outside world.

Overlay Network: Used for multi-host networking, typically in Swarm or Kubernetes environments. It allows containers on different hosts to communicate as if they were on the same network. Docker creates a virtual network that spans multiple hosts using VXLAN encapsulation.

# Create overlay network (requires Swarm mode)
docker network create -d overlay my-overlay-network

Use Case: Multi-host container orchestration, microservices spanning multiple servers.

Macvlan Network: Assigns a MAC address to a container, making it appear as a physical device on the network. This allows containers to have their own IP addresses on your physical network, directly accessible without NAT.

docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  -o parent=eth0 macvlan-net

Use Case: Legacy applications that expect to be directly on the physical network, or when you need containers to be first-class citizens on your LAN.

Host Network: Containers share the host's network namespace. No isolation, container uses host's IP directly.

None Network: Disables networking for the container completely.

How is the Bridge Network Different from a Traditional Linux Bridge?

Problem: Understanding Docker's abstraction.

Explanation: Docker's bridge network is a software bridge managed by Docker that uses Linux bridge concepts under the hood. While a traditional Linux bridge (brctl) is a low-level networking construct that simply forwards packets between interfaces, Docker's bridge network provides additional features:

Docker Bridge Enhancements:

  • Automatic IP address management (IPAM) with DHCP-like functionality
  • Built-in DNS resolution between containers using container names
  • Automatic iptables rules for NAT and port forwarding
  • Network isolation between different bridge networks
  • Easy management through Docker CLI

When you create a user-defined bridge network, Docker creates a Linux bridge, configures IP addressing, sets up iptables rules, and manages a DNS server for name resolution—all automatically.

# View the underlying Linux bridge
ip link show docker0
 
# View iptables rules Docker created
sudo iptables -t nat -L -n

How to Create and Delete User-Defined Bridge Networks?

Problem: Gaining control over container networking.

Explanation: User-defined bridge networks offer better isolation and name resolution than the default bridge network. Containers on user-defined networks can resolve each other by container name, whereas the default bridge requires using IP addresses or legacy --link flags.

Commands:

# Create a new bridge network with default settings
docker network create my-app-network
 
# Create with custom subnet and gateway
docker network create \
  --driver bridge \
  --subnet=172.28.0.0/16 \
  --gateway=172.28.0.1 \
  my-custom-network
 
# List available networks
docker network ls
 
# Inspect network details
docker network inspect my-app-network
 
# Remove a network (no containers can be connected)
docker network rm my-app-network
 
# Remove all unused networks
docker network prune

Example Output:

docker network create my-app-network
# 7f3b2a1c9d8e5f4a3b2c1d0e9f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0
 
docker network ls
# NETWORK ID     NAME             DRIVER    SCOPE
# 7f3b2a1c9d8e   my-app-network   bridge    local
# abc123def456   bridge           bridge    local
# 789xyz456abc   host             host      local

How to Connect a Container to a User-Defined Bridge Network?

Problem: Assigning containers to specific networks.

Explanation: You can connect containers to networks during creation with docker run or attach existing containers to networks with docker network connect.

During Container Creation:

# Create container on specific network
docker run -d --name web1 --network my-app-network nginx
 
# Create container on multiple networks
docker run -d --name web2 \
  --network my-app-network \
  nginx
 
# Verify connectivity (containers can ping each other by name)
docker exec web1 ping web2

Connect Existing Container:

# Connect running container to additional network
docker network connect my-app-network existing-container
 
# Connect with specific IP address
docker network connect --ip 172.28.0.100 my-app-network existing-container
 
# Disconnect from network
docker network disconnect my-app-network existing-container

Practical Example - Multi-tier Application:

# Create networks for different tiers
docker network create frontend-network
docker network create backend-network
 
# Web server on frontend network
docker run -d --name web --network frontend-network nginx
 
# Application server on both networks
docker run -d --name app --network backend-network myapp:latest
docker network connect frontend-network app
 
# Database only on backend network
docker run -d --name db --network backend-network postgres:13

This setup ensures the database is not directly accessible from the frontend network, improving security.

Does Docker Support IPv6?

Problem: Staying current with networking standards.

Explanation: Yes, Docker supports IPv6, but it's not enabled by default. You must configure IPv6 support for both the Docker daemon and individual networks.

Enable IPv6 for Docker Daemon:

Edit /etc/docker/daemon.json:

{
  "ipv6": true,
  "fixed-cidr-v6": "2001:db8:1::/64"
}

Restart Docker:

sudo systemctl restart docker

Create IPv6-enabled Network:

docker network create --ipv6 \
  --subnet=2001:db8:1::/64 \
  my-ipv6-network

Docker Compose with IPv6:

version: '3.8'
 
services:
  web:
    image: nginx
    networks:
      - ipv6-network
 
networks:
  ipv6-network:
    enable_ipv6: true
    ipam:
      config:
        - subnet: 2001:db8:1::/64

How Shall You Disable the Networking Stack on a Container?

Problem: Isolating containers completely from the network.

Explanation: Use the --network none option with docker run. This is useful for containers that perform batch processing, data transformation, or other tasks that don't require network access. It provides an additional security layer by eliminating network-based attack vectors.

# Run container without networking
docker run --network none ubuntu:20.04 bash -c "ip addr show"
 
# Output will show only loopback interface
# 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536
#     inet 127.0.0.1/8 scope host lo

Use Case: Processing sensitive data where network access should be completely disabled, or running untrusted code in maximum isolation.

How Can One Create a Macvlan Network for a Docker Container?

Problem: Integrating containers into physical networks.

Explanation: Macvlan networks allow a container to appear as a physical device on your network. This is useful when you need containers to have their own IP addresses on your LAN, be discoverable by network scanning tools, or integrate with existing network infrastructure that expects physical devices.

Prerequisites:

  • Your network switch must allow promiscuous mode
  • You need available IP addresses in your subnet
  • The parent network interface must support Macvlan

Create Macvlan Network:

# Create Macvlan network on eth0 interface
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  --ip-range=192.168.1.192/27 \
  -o parent=eth0 macvlan-net

Run Container with Macvlan:

# Container gets IP from the specified range
docker run -d --name web \
  --network macvlan-net \
  --ip 192.168.1.200 \
  nginx
 
# Verify container has physical network IP
docker exec web ip addr show eth0

Warning: The host cannot communicate directly with Macvlan containers by default due to Linux kernel restrictions. You need to create a Macvlan interface on the host itself for host-to-container communication.

Is it Possible to Exclude IP Addresses from Being Used in a Macvlan Network?

Problem: Fine-grained IP address management.

Explanation: Yes, you can control which IP addresses Docker assigns by using the --ip-range parameter when creating the network. This allows you to reserve certain IPs for static assignment or other devices.

# Reserve 192.168.1.1-191 for other devices
# Docker will only use 192.168.1.192-223 for containers
docker network create -d macvlan \
  --subnet=192.168.1.0/24 \
  --gateway=192.168.1.1 \
  --ip-range=192.168.1.192/27 \
  -o parent=eth0 limited-macvlan

The --ip-range parameter accepts CIDR notation. In this example, /27 gives you 32 addresses (192.168.1.192 through 192.168.1.223), reserving the rest of the subnet.

Manual IP Assignment:

# Assign specific IP within the allowed range
docker run -d --network limited-macvlan --ip 192.168.1.200 nginx
 
# Docker will prevent assignment outside the range
docker run -d --network limited-macvlan --ip 192.168.1.50 nginx
# Error: IP address is not in the configured subnet or ip-range

4. Docker Volumes and Data Management: Persistence and State

This section addresses how to handle persistent data for your containerized applications.

How Do Docker Volumes and Bind Mounts Work?

Problem: Ensuring data survives container restarts or removals.

Explanation:

Volumes are the preferred mechanism for persisting data. They are managed by Docker, stored in a dedicated area on the host filesystem (/var/lib/docker/volumes/ on Linux), and are independent of the container's lifecycle. Docker handles permissions, backup, and migration. Volumes work on all platforms (Linux, Windows, macOS) and can use volume drivers to store data on remote hosts or cloud providers.

# Create a named volume
docker volume create mydata
 
# Use volume with container
docker run -d -v mydata:/app/data nginx
 
# List volumes
docker volume ls
 
# Inspect volume details
docker volume inspect mydata

Bind Mounts mount a file or directory from the host machine into a container. The data resides directly on the host's filesystem at a path you specify. Useful for development when you want to share code directly or for configuration files. However, they're less portable and depend on the host's directory structure.

# Mount host directory into container
docker run -d -v /host/path:/container/path nginx
 
# Mount current directory (useful for development)
docker run -d -v $(pwd):/app node:16 npm run dev

Key Differences:

FeatureVolumesBind Mounts
ManagementDocker-managedUser-managed
Location/var/lib/docker/volumes/Anywhere on host
PortabilityHigh (Docker handles paths)Low (host-dependent)
BackupEasy with Docker commandsManual process
PerformanceOptimized by DockerDirect filesystem access
Use CaseProduction dataDevelopment, config files

Do You Lose Data When a Container Exits?

Problem: Understanding data persistence.

Explanation: It depends on where the data is stored. Data written to the container's writable layer is lost when the container is removed (but not when it's just stopped). Data written to volumes or bind mounts persists beyond the container's lifecycle.

Scenario 1: No Volume (Data Lost)

# Create container and write data
docker run --name temp ubuntu bash -c "echo 'important data' > /data.txt"
 
# Remove container
docker rm temp
 
# Data is lost forever

Scenario 2: With Volume (Data Persists)

# Create container with volume
docker run --name persistent -v mydata:/data ubuntu bash -c "echo 'important data' > /data/file.txt"
 
# Remove container
docker rm persistent
 
# Data still exists in volume
docker run --rm -v mydata:/data ubuntu cat /data/file.txt
# Output: important data

Best Practice: Always use volumes for any data that needs to persist: databases, user uploads, logs, application state, configuration that changes at runtime.

Can You Explain Different Volume Mount Types Available in Docker?

Problem: Differentiating between volume mounting options.

Explanation:

1. Named Volumes:

# Create volume explicitly
docker volume create app-data
 
# Use in container
docker run -v app-data:/app/data nginx

Advantages: Easy to reference, managed by Docker, can be shared between containers, easy to backup.

2. Anonymous Volumes:

# Docker creates volume with random ID
docker run -v /app/data nginx
 
# List shows anonymous volume
docker volume ls
# DRIVER    VOLUME NAME
# local     a3f5c2d1e4b6...

Advantages: Quick for testing. Disadvantages: Hard to manage, difficult to identify, orphaned volumes accumulate.

3. Bind Mounts:

# Mount specific host path
docker run -v /home/user/config:/etc/app/config nginx
 
# Use absolute or relative paths
docker run -v $(pwd)/src:/app/src node:16

Advantages: Direct access to host files, instant updates. Disadvantages: Host-dependent, permission issues, less portable.

4. tmpfs Mounts (Linux only):

# Mount temporary filesystem in memory
docker run --tmpfs /app/cache:rw,size=100m nginx

Advantages: Fast (in-memory), secure (never written to disk), automatic cleanup. Use Case: Temporary files, sensitive data that shouldn't touch disk.

How to Share Data Among Docker Hosts?

Problem: Enabling data access across multiple machines.

Explanation: This requires distributed storage solutions that multiple Docker hosts can access simultaneously. Docker supports volume plugins that enable this functionality.

Common Solutions:

1. NFS (Network File System):

# Create NFS volume
docker volume create \
  --driver local \
  --opt type=nfs \
  --opt o=addr=192.168.1.100,rw \
  --opt device=:/path/to/share \
  nfs-volume
 
# Use across multiple hosts
docker run -v nfs-volume:/data nginx

2. Cloud Storage Drivers:

# AWS EFS
docker volume create \
  --driver rexray/efs \
  --opt volumetype=gp2 \
  --opt size=100 \
  efs-volume
 
# GlusterFS
docker volume create \
  --driver glusterfs \
  --opt voluri="server1:volume" \
  gluster-volume

3. Docker Swarm with Volume Drivers:

In Swarm mode, services can use volume drivers that automatically handle multi-host scenarios:

version: '3.8'
 
services:
  app:
    image: myapp
    volumes:
      - shared-data:/data
    deploy:
      replicas: 3
 
volumes:
  shared-data:
    driver: rexray/s3fs

4. Third-party Solutions:

  • Portworx
  • StorageOS
  • Ceph RBD
  • Convoy

How to Backup, Restore, or Migrate Data Volumes Under Docker Container?

Problem: Data lifecycle management.

Explanation: Since volumes are just directories on the host, you can use standard backup tools, but Docker provides a convenient pattern using temporary containers.

Backup Volume:

# Backup volume to tar archive
docker run --rm \
  -v mydata:/volume-data \
  -v $(pwd):/backup \
  ubuntu tar czf /backup/mydata-backup-$(date +%Y%m%d).tar.gz -C /volume-data .
 
# Verify backup
ls -lh mydata-backup-*.tar.gz

Restore Volume:

# Create new volume
docker volume create mydata-restored
 
# Restore from backup
docker run --rm \
  -v mydata-restored:/volume-data \
  -v $(pwd):/backup \
  ubuntu tar xzf /backup/mydata-backup-20240115.tar.gz -C /volume-data
 
# Verify restoration
docker run --rm -v mydata-restored:/data ubuntu ls -la /data

Migrate Volume to Another Host:

# On source host: backup to file
docker run --rm -v mydata:/data -v $(pwd):/backup ubuntu tar czf /backup/migrate.tar.gz -C /data .
 
# Transfer file to destination host
scp migrate.tar.gz user@destination-host:/tmp/
 
# On destination host: restore
docker volume create mydata
docker run --rm -v mydata:/data -v /tmp:/backup ubuntu tar xzf /backup/migrate.tar.gz -C /data

Production-Grade Backup Strategy:

# Automated backup script
#!/bin/bash
VOLUME_NAME="production-db"
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d-%H%M%S)
 
docker run --rm \
  -v ${VOLUME_NAME}:/source:ro \
  -v ${BACKUP_DIR}:/backup \
  ubuntu tar czf /backup/${VOLUME_NAME}-${DATE}.tar.gz -C /source .
 
# Keep only last 7 days of backups
find ${BACKUP_DIR} -name "${VOLUME_NAME}-*.tar.gz" -mtime +7 -delete

What is the --memory-swap Flag?

Problem: Understanding memory resource constraints.

Explanation: This flag controls the amount of swap memory a container can use. It's set in combination with --memory to limit total memory (RAM + swap) available to a container.

Syntax:

docker run --memory <RAM limit> --memory-swap <Total limit> image

Behavior:

# Container can use 1GB RAM and 1GB swap (2GB total)
docker run --memory=1g --memory-swap=2g nginx
 
# Container can use 1GB RAM and unlimited swap
docker run --memory=1g --memory-swap=-1 nginx
 
# Container can use 1GB RAM and NO swap
docker run --memory=1g --memory-swap=1g nginx
 
# If --memory-swap not specified, it defaults to 2x --memory
docker run --memory=1g nginx
# Equivalent to: --memory=1g --memory-swap=2g

Important Notes:

  • --memory-swap must be greater than or equal to --memory
  • Setting --memory-swap to the same value as --memory disables swap
  • Setting --memory-swap to -1 enables unlimited swap
  • Swap usage can severely degrade performance; use carefully

Monitoring Memory Usage:

# View container memory stats
docker stats container_name
 
# Output:
# CONTAINER ID   NAME      CPU %     MEM USAGE / LIMIT     MEM %
# a3f5c2d1e4b6   nginx     0.01%     50MiB / 1GiB         4.88%

5. How OpsSqad's Docker Squad Automates Container Management

Managing Docker environments manually—especially in production—involves repetitive commands, context switching between servers, and potential for human error. Whether you're debugging a failing container, optimizing image sizes, or investigating network issues, you're constantly SSH-ing into servers, running diagnostic commands, and piecing together information from multiple sources.

The Manual Pain: Imagine a container failing health checks in production. Your typical workflow:

  1. SSH into the production server
  2. Run docker ps to find the container
  3. Check logs with docker logs container_id
  4. Inspect the container with docker inspect
  5. Check network connectivity with docker network inspect
  6. Review resource usage with docker stats
  7. Possibly exec into the container to run diagnostics
  8. Document findings and remediation steps

This process takes 10-15 minutes and requires remembering exact command syntax, container IDs, and network names.

How OpsSqad Solves This: OpsSqad's Docker Squad provides AI-powered container management through natural language chat. Instead of memorizing commands and SSH-ing into servers, you describe the problem and let specialized AI agents handle the investigation and remediation.

The Complete Setup (3 minutes):

Step 1: Create Account and Node

  • Sign up at app.opssqad.ai
  • Navigate to Nodes → Create Node
  • Give it a descriptive name like "production-web-01"
  • Copy the unique Node ID and token from the dashboard

Step 2: Deploy the OpsSqad Agent SSH to your Docker host and run:

# Download and install OpsSqad agent
curl -fsSL https://install.opssqad.ai/install.sh | bash
 
# Register node with your credentials from dashboard
opssqad node install --node-id=node_abc123xyz --token=tok_xyz789abc
 
# Start the agent (establishes reverse TCP connection)
opssqad node start

The agent establishes a reverse TCP connection to OpsSqad cloud, meaning no inbound firewall rules or VPN setup required. Your infrastructure remains secure behind your firewall while agents can execute commands through the outbound connection.

Step 3: Browse Squad Marketplace

  • In the OpsSqad dashboard, navigate to Squad Marketplace
  • Find "Docker Troubleshooting Squad"
  • Click Deploy (creates your private instance with all specialized agents)

Step 4: Link Agents to Nodes

  • Open your deployed Docker Squad
  • Go to Agents tab
  • Grant each agent access to your production-web-01 node
  • This whitelists which commands each agent can execute

Step 5: Start Debugging Navigate to chat.opssqad.ai and select your Docker Squad.

Real-World Example - Container Health Check Failure:

You: "Container nginx-web is failing health checks. What's wrong?"

Docker Diagnostics Agent: "Running diagnostics on nginx-web container..."

[Executes on your server through reverse TCP connection:]
docker ps -a --filter name=nginx-web
docker inspect nginx-web
docker logs --tail 100 nginx-web

Docker Diagnostics Agent: "Found the issue:
- Container is in restarting loop (crashed 15 times in last 10 minutes)
- Health check: curl localhost:80/health failing with connection refused
- Logs show: 'nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)'

Port 80 is already bound by another process. Would you like me to identify what's using port 80?"

You: "Yes, and show me how to fix it"

Docker Diagnostics Agent: [Executes: docker ps | grep :80]

"Another nginx container 'nginx-old' is bound to port 80. 

Recommended fix:
1. Stop the old container: docker stop nginx-old
2. Remove it: docker rm nginx-old  
3. Restart the failing container: docker restart nginx-web

Should I execute these steps?"

You: "Yes, proceed"

Docker Remediation Agent: [Executes whitelisted commands with sandboxed execution]

"✓ Stopped nginx-old
✓ Removed nginx-old
✓ Restarted nginx-web
✓ Health check now passing (verified with docker inspect)

Container is now healthy. Logged all actions to audit trail."

Security Model:

  • Command Whitelisting: Only pre-approved Docker commands can execute
  • Sandboxed Execution: Each command runs in isolated context with resource limits
  • Audit Logging: Every command, output, and decision is logged immutably
  • Role-Based Access: Different team members can have different Squad access levels

Architecture Benefits:

  • Reverse TCP: No inbound firewall rules needed, works from anywhere
  • No VPN Required: Agents connect outbound to OpsSqad cloud
  • Multi-Server Management: One Squad can manage agents across dozens of servers
  • Team Collaboration: Entire team sees the same chat history and can learn from past issues

Time Savings:

  • Manual troubleshooting: 15 minutes of SSH, commands, and documentation
  • OpsSqad Docker Squad: 90 seconds from question to resolution
  • The Squad remembers your infrastructure, so future similar issues resolve even faster

For teams managing multiple Docker hosts, microservices architectures, or complex container orchestration, OpsSqad transforms reactive firefighting into proactive, conversational infrastructure management.

6. Docker Security and Best Practices

Security in containerized environments requires a multi-layered approach. Containers share the host kernel, so vulnerabilities can have broader impact than in VM environments.

How to Manage Sensitive Data in Docker?

Problem: Preventing credentials and secrets from being exposed in images or logs.

Explanation: Never hardcode secrets in Dockerfiles or environment variables. Use Docker secrets (in Swarm mode) or external secret management tools.

Bad Practice:

# Never do this!
ENV DATABASE_PASSWORD=supersecret123
ENV API_KEY=abc123xyz789

Good Practices:

1. Docker Secrets (Swarm Mode):

# Create secret from file
echo "db_password_here" | docker secret create db_password -
 
# Use in service
docker service create \
  --name myapp \
  --secret db_password \
  myimage
 
# Access in container at /run/secrets/db_password

2. Environment Variables at Runtime:

# Pass secrets at runtime, not build time
docker run -e DATABASE_PASSWORD=$(cat /secure/db_pass) myapp

3. External Secret Managers:

# docker-compose.yml with HashiCorp Vault
services:
  app:
    image: myapp
    environment:
      - VAULT_ADDR=https://vault.example.com
      - VAULT_TOKEN=${VAULT_TOKEN}

4. Build-time Secrets (BuildKit):

# Dockerfile
RUN --mount=type=secret,id=npmrc \
    npm config set //registry.npmjs.org/:_authToken=$(cat /run/secrets/npmrc)
 
# Build with secret
docker build --secret id=npmrc,src=$HOME/.npmrc .

How to Reduce Docker Image Size?

Problem: Large images slow down deployments, consume storage, and increase attack surface.

Strategies:

1. Use Smaller Base Images:

# Bad: 140MB
FROM ubuntu:20.04
 
# Better: 72MB  
FROM debian:bullseye-slim
 
# Best: 5MB
FROM alpine:3.17

2. Multi-stage Builds:

# Build stage
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
 
# Production stage
FROM node:16-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/server.js"]
 
# Result: 150MB instead of 900MB

3. Combine RUN Commands:

# Bad: Creates multiple layers
RUN apt-get update
RUN apt-get install -y nginx
RUN rm -rf /var/lib/apt/lists/*
 
# Good: Single layer
RUN apt-get update && \
    apt-get install -y nginx && \
    rm -rf /var/lib/apt/lists/*

4. Use .dockerignore:

node_modules
.git
*.log
tests/
documentation/

5. Remove Build Dependencies:

RUN apk add --no-cache --virtual .build-deps \
    gcc \
    musl-dev \
    && pip install -r requirements.txt \
    && apk del .build-deps

What are Docker Health Checks?

Problem: Knowing when a container is truly ready to serve traffic.

Explanation: Health checks allow Docker to test whether a container is functioning correctly. A container might be running but unable to serve requests (database connection failed, application crashed, etc.).

Dockerfile Health Check:

FROM nginx:alpine
 
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --quiet --tries=1 --spider http://localhost:80/health || exit 1

Docker Compose Health Check:

services:
  web:
    image: nginx
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
  
  db:
    image: postgres:13
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

Check Health Status:

docker ps
# CONTAINER ID   STATUS
# a3f5c2d1e4b6   Up 2 minutes (healthy)
 
docker inspect --format='' container_name
# healthy

What are Best Practices for Docker Security?

Problem: Securing containerized applications against common threats.

Best Practices:

1. Run as Non-Root User:

FROM node:16-alpine
 
# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001
 
USER nodejs
 
WORKDIR /app
COPY --chown=nodejs:nodejs . .
CMD ["node", "server.js"]

2. Scan Images for Vulnerabilities:

# Use Docker Scout
docker scout cve myimage:latest
 
# Use Trivy
trivy image myimage:latest
 
# Use Snyk
snyk container test myimage:latest

3. Limit Container Capabilities:

# Drop all capabilities, add only what's needed
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx

4. Use Read-Only Filesystem:

docker run --read-only --tmpfs /tmp myapp

5. Set Resource Limits:

docker run \
  --memory=512m \
  --memory-swap=512m \
  --cpus=1.0 \
  --pids-limit=100 \
  myapp

6. Enable Docker Content Trust:

export DOCKER_CONTENT_TRUST=1
docker pull nginx:latest
# Will only pull signed images

7. Regular Updates:

# Rebuild images regularly to get security patches
docker build --no-cache -t myapp:latest .

7. Advanced Docker Interview Questions

Can You Run Multiple Processes in a Docker Container?

Problem: Understanding container process management.

Explanation: Yes, but it's generally discouraged. Docker containers are designed to run a single process (the PID 1 process). However, you can run multiple processes using a process supervisor like supervisord, tini, or s6.

Why Single Process is Preferred:

  • Simpler logging and monitoring
  • Clearer health checks
  • Easier to scale individual components
  • Better aligns with microservices architecture

When Multiple Processes Make Sense:

  • Legacy applications tightly coupled with background workers
  • Applications requiring sidecar processes (log forwarders, monitoring agents)
  • Development environments

Example with supervisord:

FROM ubuntu:20.04
 
RUN apt-get update && apt-get install -y \
    nginx \
    supervisor
 
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
 
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
# supervisord.conf
[supervisord]
nodaemon=true
 
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
 
[program:app]
command=/usr/bin/python3 /app/worker.py
autostart=true
autorestart=true

Better Alternative - Docker Compose:

services:
  web:
    image: nginx
  
  worker:
    image: myapp:worker

What are Dangling Images and How to Remove Them?

Problem: Reclaiming disk space from unused images.

Explanation: Dangling images are layers that have no relationship to any tagged images. They appear when you rebuild an image with the same tag—the old layers become dangling. They show as <none>:<none> in docker images.

# List dangling images
docker images -f "dangling=true"
 
# Remove dangling images
docker image prune
 
# Remove all unused images (dangling and unreferenced)
docker image prune -a
 
# Remove with confirmation bypass
docker image prune -a -f

Complete Cleanup:

# Remove all unused resources (containers, networks, images, volumes)
docker system prune -a --volumes
 
# Show what would be removed without actually removing
docker system df

How to Configure the Docker Daemon?

Problem: Customizing Docker's behavior at the system level.

Explanation: The Docker daemon is configured via /etc/docker/daemon.json on Linux. This file controls logging, storage drivers, registry mirrors, and more.

Example Configuration:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "storage-driver": "overlay2",
  "default-address-pools": [
    {
      "base": "172.30.0.0/16",
      "size": 24
    }
  ],
  "dns": ["8.8.8.8", "8.8.4.4"],
  "insecure-registries": ["myregistry.local:5000"],
  "registry-mirrors": ["https://mirror.gcr.io"],
  "live-restore": true,
  "userland-proxy": false
}

Apply Configuration:

# Edit configuration
sudo nano /etc/docker/daemon.json
 
# Restart Docker daemon
sudo systemctl restart docker
 
# Verify configuration
docker info

Common Options:

  • log-driver: Controls how logs are stored (json-file, syslog, journald, etc.)
  • storage-driver: Backend for image and container storage (overlay2, aufs, devicemapper)
  • live-restore: Keep containers running during daemon downtime
  • default-address-pools: Custom IP ranges for networks

How to Push Docker Images to Docker Hub?

Problem: Sharing images or deploying to production.

Explanation: Docker Hub is the default public registry for Docker images. You need to tag images with your username and authenticate before pushing.

Complete Workflow:

# 1. Login to Docker Hub
docker login
# Username: yourusername
# Password: 
# Login Succeeded
 
# 2. Tag your image with your username
docker tag myapp:latest yourusername/myapp:latest
docker tag myapp:latest yourusername/myapp:v1.0
 
# 3. Push to Docker Hub
docker push yourusername/myapp:latest
docker push yourusername/myapp:v1.0
 
# 4. Verify on Docker Hub
# Visit: https://hub.docker.com/r/yourusername/myapp
 
# 5. Others can now pull your image
docker pull yourusername/myapp:latest

Private Repositories:

# Create private repository on Docker Hub first
# Then push as normal
docker push yourusername/private-app:latest

Best Practices:

  • Use semantic versioning for tags (v1.0.0, v1.0.1)
  • Always push both specific version and latest
  • Include README.md in repository for documentation
  • Use automated builds connected to GitHub/GitLab

Conclusion

Mastering Docker interview questions requires understanding both theoretical concepts and practical application. From fundamental concepts like images and containers to advanced topics like networking, volumes, and security, this guide has covered the essential knowledge you need to confidently answer Docker interview questions. Remember that interviewers value practical experience—being able to troubleshoot real issues, optimize Dockerfiles, and explain architectural decisions demonstrates deeper expertise than memorizing definitions.

The key to success in Docker interviews is hands-on practice. Build multi-container applications with Docker Compose, experiment with different network drivers, practice debugging failing containers, and optimize your images for production. The scenarios and commands in this guide provide a solid foundation, but real-world experience solidifies that knowledge.

If you want to automate this entire workflow and manage Docker environments through conversational AI, OpsSqad's Docker Squad can transform how your team handles container operations. From troubleshooting failing containers to optimizing resource usage, AI agents execute the commands you've learned in this guide through natural language chat. Create your free account at https://app.opssqad.ai and deploy your first Squad in under 3 minutes—no credit card required.