This repository demonstrates the difference between single-stage and multi-stage Docker builds for a Next.js application. The comparison focuses on build size, security, and best practices.
The single-stage build uses a straightforward approach where all operations happen in a single Docker layer:
- Uses a single
node:18-alpinebase image - Installs dependencies and builds the application in the same layer
- Simpler configuration but results in larger image size
- Contains build tools and dependencies in the final image
The multi-stage build uses three distinct stages to optimize the final image:
- Dependencies Stage: Installs production dependencies
- Builder Stage: Builds the application
- Runner Stage: Creates a minimal production image
- Uses
node:18-alpineas the base image for all stages - Implements security best practices (non-root user)
- Only includes necessary production files
- Results in a significantly smaller final image
To run both builds and compare their sizes:
# Build & Run the containers
docker-compose up --buildThe applications will be available at:
- Single-stage build: http://localhost:3000
- Multi-stage build: http://localhost:3001
Before running the application, you need to set up your environment variables:
- Copy the
.env.samplefile to create your.envfile:
cp .env.sample .env- Update the values in the
.envfile with your specific configuration.
Note: Make sure to never commit your .env file to version control. The .env.sample file serves as a template showing which environment variables are required.
| Aspect | Single-Stage | Multi-Stage |
|---|---|---|
| Image Size | Larger | Smaller |
| Build Time | Faster | Slightly slower |
| Security | Basic | Enhanced (non-root user) |
| Build Tools | Included | Excluded |
| Dependencies | All included | Only production |
| Complexity | Simple | More complex |
The multi-stage build implements several Docker best practices:
- Separation of build and runtime environments
- Minimal production image
- Security hardening (non-root user)
- Proper handling of static files
- Environment variable configuration
- Proper port exposure
To compare the final image sizes:
docker images | grep frontendCurrent image sizes:
- Single-stage build: 1.22GB
- Multi-stage build: 192MB
The multi-stage build results in an image that's approximately 84% smaller than the single-stage build (1.22GB vs 192MB), as it excludes:
- Build tools
- Development dependencies
- Source code
- Build artifacts
- Node modules (only production dependencies)
Contributions are welcome! Please feel free to submit a Pull Request.
This template is licensed under the MIT License - see the LICENSE file for details.


