Quick Answer
# Build an image from the Dockerfile in the current directory
docker build -t myapp:latest .
# Specify a Dockerfile path explicitly
docker build -t myapp:latest -f ./docker/Dockerfile .
What You’re Trying to Do
You’ve written a Dockerfile and now want to build a Docker image from it. The docker build command is what you need — it reads your Dockerfile and produces an image you can run as a container.
This guide covers everything from the basics to advanced techniques like multi-stage builds and cache control.
Environment
- Docker Engine 24.x or later
- OS: Ubuntu 22.04 / macOS / Windows (WSL2)
Solution
Basic Build
Start with a simple Dockerfile:
# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]
Run the build command:
# The trailing dot (.) sets the build context to the current directory
docker build -t myapp:latest .
Tagging Images
# Name and tag with -t
docker build -t myapp:1.0.0 .
# Apply multiple tags in one build
docker build -t myapp:latest -t myapp:1.0.0 .
# Full registry path
docker build -t ghcr.io/yourname/myapp:latest .
Specifying a Custom Dockerfile Path
# -f points to the Dockerfile
docker build -t myapp:latest -f ./docker/Dockerfile .
# Use a different directory as build context
docker build -t myapp:latest -f Dockerfile /path/to/context
Passing Build Arguments
# Define ARG in Dockerfile
ARG NODE_ENV=production
ENV NODE_ENV=$NODE_ENV
# Inject a value at build time with --build-arg
docker build --build-arg NODE_ENV=development -t myapp:dev .
Disabling the Cache for a Clean Build
# --no-cache rebuilds every layer from scratch
docker build --no-cache -t myapp:latest .
Multi-Stage Builds for Smaller Images
# Dockerfile (multi-stage)
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]
# Build normally — only the final stage becomes the image
docker build -t myapp:slim .
# Stop at a specific stage
docker build --target builder -t myapp:builder .
Verifying the Built Image
# List images
docker images
# Inspect image metadata
docker inspect myapp:latest
# Check image size
docker images myapp
Common Errors
COPY failed: file not found
COPY failed: COPY instruction failed: failed to copy './src':
no such file or directory
Cause: The file doesn’t exist in the build context, or is excluded by .dockerignore.
Fix:
# Check what's in the build context
ls -la
# Review your .dockerignore
cat .dockerignore
failed to read dockerfile
failed to solve with frontend dockerfile.v0:
failed to read dockerfile: open Dockerfile: no such file or directory
Cause: No Dockerfile found in the current directory.
Fix:
ls Dockerfile
# Or point to it explicitly
docker build -f ./path/to/Dockerfile -t myapp .
pull access denied
pull access denied for baseimage, repository does not exist
or may require 'docker login'
Cause: The base image name is wrong, or you need to authenticate to a private registry.
Fix:
docker login
# Verify the image name
docker pull node:20-alpine
no space left on device
Cause: Build cache and accumulated images are filling the disk.
Fix:
# Remove unused build cache
docker builder prune
# Remove all unused images and containers
docker system prune -a
FAQ
Q: What does the dot (.) at the end of docker build mean?
It sets the build context — the directory Docker sends to the daemon. Only files within that directory can be referenced by COPY or ADD instructions.
Q: How do I speed up slow builds caused by a large build context?
Create a .dockerignore file to exclude unnecessary files. Ignoring node_modules, .git, and dist typically gives the biggest speedup.
# .dockerignore
node_modules
.git
dist
*.log
.env
Q: What happens if I skip the -t flag?
The image gets a <none> tag. You can add a tag later with docker tag, but it’s better practice to always use -t upfront.
Q: Why use multi-stage builds? They keep build-time tools (compilers, dev dependencies) out of the final image, dramatically reducing its size and attack surface.
Q: What’s the difference between docker build and docker buildx build?
docker buildx uses BuildKit and supports multi-platform builds (AMD64/ARM64), advanced caching, and more. For most projects docker build is sufficient.
Q: How can I maximize cache hits during builds?
Put rarely-changing layers first (e.g., COPY package*.json then RUN npm install) and frequently-changing source code last. Docker only invalidates cache from the first changed layer downward.
Related Articles
- docker exec: Enter a Running Container
- docker logs: View Container Logs
- Dockerfile Basics: Writing Your First Dockerfile
- docker-compose Basics
- How to Delete Docker Images and Containers