The .dockerignore File
The problem
COPY . . copies everything in the project directory into the image. This includes files you do not want: node_modules (500 MB of local dependencies), .git (your entire commit history), app.db (your local database), .env (your secrets).
The .dockerignore file
Like .gitignore but for Docker. Files listed here are excluded from the build context — Docker does not even send them to the build engine.
# .dockerignore
node_modules
dist
.git
.gitignore
.env
.env.*
*.db
*.db-wal
*.db-shm
uploads/
Dockerfile
docker-compose.yml
README.md
tests/ What to exclude and why
node_modules — The biggest win. Docker installs dependencies inside the container (via npm ci). Your local node_modules are for your OS, not the container’s OS. Copying them wastes time and causes errors.
dist — The build output. The multi-stage build generates this inside the container. Your local build might be stale or compiled for a different platform.
.git — Your commit history, branches, and metadata. Not needed in the container. Can be 100 MB+ for large repositories.
.env — Your local secrets. These should never be baked into an image. Environment variables are passed at runtime (covered in the next lesson).
*.db — Your local SQLite database. The production database is separate (either a fresh file in a volume or a remote database).
uploads/ — Local uploaded files. Production files live in a volume or cloud storage.
Dockerfile, docker-compose.yml — Build configuration. Not needed inside the running container.
tests/ — Test files. Not needed in production.
The speed difference
Without .dockerignore, COPY . . sends everything to the Docker build engine. A project with a 500 MB node_modules sends 500 MB on every build.
With .dockerignore, COPY . . only sends your source code (~1 MB). The build starts instantly.
# Without .dockerignore
Sending build context to Docker daemon 523.4MB ← slow
# With .dockerignore
Sending build context to Docker daemon 1.2MB ← fast Verify what is excluded
Check what Docker will send to the build context:
# List files that would be sent (respecting .dockerignore)
# There is no built-in command, but you can check:
docker build --no-cache -t test . 2>&1 | head -5
# Look at the "Sending build context" line Exercises
Exercise 1: Create the .dockerignore file. Build the image. Note the “Sending build context” size.
Exercise 2: Remove .dockerignore and build again. Note the size difference. (If you have node_modules, it will be dramatic.)
Exercise 3: Intentionally leave .env out of .dockerignore. Build the image. Run a container and check if the .env file is inside: docker run myapp cat .env. If it is, your secrets are baked into the image. Add it back to .dockerignore.
Why should node_modules be in .dockerignore?