# Docker Build Failed: How to Debug and Fix Build Errors

Your Docker build just failed with an error message. It might be cryptic, or it might point to a specific line. Either way, you need to figure out what went wrong and fix it.

bash
ERROR: failed to solve: process "/bin/sh -c apt-get install -y python3" did not complete successfully

Let me walk you through diagnosing and fixing Docker build failures.

Step 1: Read the Error Message Carefully

The error message usually tells you exactly which step failed:

```bash # Build with full output docker build -t myimage:latest .

# The error shows: # => ERROR [stage-name 5/10] RUN apt-get install -y python3 # => failed to solve: process returned non-zero exit code: 100 ```

Key information to extract: - Which build stage failed - Which step number (e.g., 5/10) - The command that failed - The exit code (non-zero means error)

Step 2: Build with No Cache

Stale cache can cause strange issues:

```bash # Force rebuild without cache docker build --no-cache -t myimage:latest .

# This ensures you're getting fresh package lists # and not using cached layers ```

Step 3: Debug the Failing Layer

The most effective debugging technique is to run the failing container interactively:

```bash # Find the last successful layer ID docker build -t myimage:latest . 2>&1 | grep -A 5 "exporting"

# Run the intermediate image docker run -it <layer-id> /bin/sh

# Now you can run commands to see what's happening apt-get update apt-get install -y python3 # See the actual error ```

Better approach: Build to a specific stage:

```dockerfile # In your Dockerfile FROM ubuntu:22.04 AS base RUN apt-get update

FROM base AS debug # ... more steps ```

bash
# Build only to the debug stage
docker build --target debug -t debug-image .
docker run -it debug-image /bin/bash

Step 4: Common Build Errors and Fixes

Package Not Found

bash
E: Unable to locate package python-pip

Fix: Update package lists first:

dockerfile
RUN apt-get update && apt-get install -y python3-pip
# Or combine update and install

For Alpine:

dockerfile
RUN apk update && apk add py3-pip

Permission Denied

bash
/bin/sh: 1: cannot create /app/config: Permission denied

Fix: Ensure proper permissions:

dockerfile
RUN mkdir -p /app && chmod 755 /app
# Or run as root before switching users
USER root
RUN mkdir -p /app/config
USER appuser

Copy Failed

bash
COPY failed: file not found in build context

Fix: Check the file path and .dockerignore:

```bash # Check build context ls -la

# Check .dockerignore cat .dockerignore

# Is the file being excluded? ```

dockerfile
# Ensure paths are relative to build context
COPY ./app /app/
# NOT:
# COPY ../app /app/  (doesn't work - can't access outside context)

Command Not Found

bash
/bin/sh: 1: npm: not found

Fix: Install dependencies in the correct order:

```dockerfile # Wrong: npm install before node is installed RUN npm install RUN apt-get install -y nodejs

# Correct: install node first RUN apt-get update && apt-get install -y nodejs npm RUN npm install ```

Network Timeout

bash
ERROR: failed to fetch metadata: dial tcp: lookup registry-1.docker.io: connection refused

Fix: Check network connectivity:

```bash # Test connectivity ping -c 3 registry-1.docker.io

# Configure DNS if needed docker build --dns 8.8.8.8 -t myimage .

# Or in daemon.json { "dns": ["8.8.8.8", "8.8.4.4"] } ```

Out of Disk Space

bash
no space left on device

Fix: Clean up Docker resources:

```bash # Remove unused images docker image prune -a

# Full cleanup docker system prune -a --volumes

# Check disk usage docker system df ```

Step 5: Debugging Dockerfile Instructions

Use RUN echo statements to debug:

```dockerfile RUN echo "Current directory: $(pwd)" RUN echo "Files: $(ls -la)" RUN echo "Environment: $PATH" RUN echo "User: $(whoami)"

# Debug a failing command RUN command-that-fails || echo "Exit code: $?" ```

Step 6: Use Multi-Stage Builds Wisely

Break complex builds into stages:

```dockerfile # Build stage FROM node:18 AS builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build

# Production stage FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html ```

Debug each stage independently:

bash
docker build --target builder -t debug-builder .
docker run -it debug-builder /bin/bash

Step 7: Handle Build Arguments and Secrets

Passing Build Arguments

bash
# Build with arguments
docker build --build-arg VERSION=1.2.3 -t myimage .
dockerfile
ARG VERSION=latest
RUN echo "Building version: ${VERSION}"

Using Secrets in Builds

Never copy secrets into images. Use BuildKit secrets:

bash
# Enable BuildKit
DOCKER_BUILDKIT=1 docker build --secret id=mysecret,src=./secret.txt .
dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret

Step 8: Check Build Context

Large build contexts cause slow builds and unexpected failures:

```bash # Check build context size docker build -t test . 2>&1 | grep "Sending build context"

# Use .dockerignore to exclude unnecessary files echo "node_modules" >> .dockerignore echo ".git" >> .dockerignore echo "*.log" >> .dockerignore ```

Example .dockerignore:

bash
.git
.gitignore
node_modules
npm-debug.log
Dockerfile
docker-compose*.yml
.env*
*.md
test/

Step 9: Inspect Failed Build Layers

```bash # List all layers including intermediate docker images -a

# Inspect a specific layer docker inspect <image-id>

# Run a specific layer docker run -it <layer-id> /bin/sh

# Export layer to see contents docker save <image-id> | tar -x ```

Step 10: Use Docker Buildx for Advanced Debugging

```bash # Enable buildx docker buildx create --use

# Build with detailed progress docker buildx build --progress=plain -t myimage .

# Debug specific platform docker buildx build --platform linux/amd64 --progress=plain -t myimage . ```

Common Dockerfile Anti-Patterns to Avoid

```dockerfile # BAD: Multiple RUN commands create extra layers RUN apt-get update RUN apt-get install -y python3 RUN apt-get clean

# GOOD: Combine related commands RUN apt-get update && \ apt-get install -y python3 && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*

# BAD: COPY then RUN COPY . /app RUN npm install

# GOOD: Copy dependency files first for caching COPY package*.json /app/ RUN npm install COPY . /app/

# BAD: Using latest tag FROM ubuntu:latest

# GOOD: Pin version FROM ubuntu:22.04 ```

Quick Reference: Build Debugging Commands

TaskCommand
Build with outputdocker build --progress=plain -t img .
Build without cachedocker build --no-cache -t img .
Build to stagedocker build --target stage -t img .
Build with argumentsdocker build --build-arg VAR=val -t img .
Check disk spacedocker system df
Clean updocker system prune -a
List all imagesdocker images -a
Run intermediate imagedocker run -it <id> /bin/sh

Docker build failures are usually straightforward to fix once you identify the failing step and run it interactively to see the actual error.