This project demonstrates the use of Docker Bake for building containerized applications with multiple configurations. Docker Bake is a feature of BuildKit that allows you to define complex build configurations using HCL, JSON, or YAML files.
For the easiest way to get started, use the quick-start script:
./quick-start.shThis script provides an interactive menu to:
- Run development environment with Docker Compose
- Run production environment with Docker Compose
- Build with Docker Bake
- Run locally without Docker
To clean up all Docker resources created by this project, use the cleanup script:
./cleanup.shThis script will:
- Stop and remove Docker containers
- Remove Docker images
- Clean up local node_modules
- Prune Docker build cache and dangling images
Lab7/
├── app/
│ ├── index.js # Simple Express.js application
│ ├── package.json # Node.js dependencies
│ └── run-local.sh # Script to run app locally
├── Dockerfile # Multi-stage Dockerfile
├── docker-compose.yml # Docker Compose configuration
├── docker-bake.hcl # HCL format Docker Bake file
├── docker-bake.json # JSON format Docker Bake file
├── docker-bake.yaml # YAML format Docker Bake file
├── .dockerignore # Files to exclude from Docker build
├── quick-start.sh # Interactive startup script
├── cleanup.sh # Cleanup script to remove Docker resources
└── README.md # This file
┌─────────────────────────────────────────────────────────┐
│ Docker Bake Process │
└───────────────┬─────────────────────────┬───────────────┘
│ │
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐
│ Development Build │ │ Production Build │
│ ┌─────────────────────┐ │ │ ┌─────────────────────┐ │
│ │ Base Image │ │ │ │ Base Image │ │
│ │ (node:18-alpine) │ │ │ │ (node:18-alpine) │ │
│ └──────────┬──────────┘ │ │ └──────────┬──────────┘ │
│ │ │ │ │ │
│ ▼ │ │ ▼ │
│ ┌─────────────────────┐ │ │ ┌─────────────────────┐ │
│ │ Development Image │ │ │ │ Production Build │ │
│ │ - All dependencies │ │ │ │ - Prune dev deps │ │
│ │ - Source code │ │ │ │ - Optimize │ │
│ └─────────────────────┘ │ │ └──────────┬──────────┘ │
└───────────────────────────┘ │ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Production Image │ │
│ │ - Minimal image │ │
│ │ - Only prod deps │ │
│ └─────────────────────┘ │
└───────────────────────────┘
Before you begin, make sure you have the following installed:
- Docker Engine - Version 19.03 or newer (with BuildKit enabled)
- Docker Buildx - Required for Docker Bake functionality
- Docker Compose - For running multi-container setups
To check if Docker is running:
docker infoTo enable BuildKit (if not already enabled):
# For Linux/macOS (add to your shell profile)
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1
# For Windows PowerShell
$env:DOCKER_BUILDKIT=1
$env:COMPOSE_DOCKER_CLI_BUILD=1This example showcases three different formats for Docker Bake files:
- HCL Format (docker-bake.hcl): The standard and most flexible format.
- JSON Format (docker-bake.json): Compatible with JSON tooling, good for programmatic generation.
- YAML Format (docker-bake.yaml): Human-readable alternative, good for YAML-based infrastructures.
A simple Node.js Express application that:
- Returns a JSON response with a message, environment information, and timestamp
- Uses different configurations for development, production, and test environments
Before using Docker Bake, you can try a simple build to ensure Docker is working properly:
docker build -t docker-bake-test --target development .
docker run -p 3000:3000 docker-bake-testVisit http://localhost:3000 in your browser to see the app running.
Build the development image:
# Using the HCL file
docker buildx bake -f docker-bake.hcl app-dev
# Using the JSON file
docker buildx bake -f docker-bake.json app-dev
# Using the YAML file
docker buildx bake -f docker-bake.yaml app-devBuild the production image:
docker buildx bake -f docker-bake.hcl app-prodBuild all targets:
docker buildx bake -f docker-bake.hcl allOverride variables when building:
docker buildx bake -f docker-bake.hcl --set VERSION=2.0.0 --set REGISTRY=mycompany app-prodRun the development image:
docker run -p 3000:3000 myregistry.io/docker-bake-example:devNote: This example uses Docker Compose V2. Use
docker compose(without hyphen) instead ofdocker-composecommand. In docker-compose.yml, theversionattribute is obsolete in Compose V2 and should be removed to avoid warnings.
Start the development environment:
docker compose up appStart the production environment:
docker compose up app-prodStart both environments:
docker compose up-
Docker daemon not running
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?Solution: Start the Docker Desktop application or the Docker service.
-
BuildKit not enabled
buildx not found: buildx is a Docker plugin. Try 'docker buildx'Solution: Make sure you have Docker Buildx installed and BuildKit is enabled.
-
Port already in use
Error starting userland proxy: listen tcp4 0.0.0.0:3000: bind: address already in useSolution: Change the port mapping in the docker-compose.yml file or when running the container.
-
Node modules issues If you encounter npm errors, try rebuilding the image with the
--no-cacheoption:docker build --no-cache -t docker-bake-test --target development .
- Parameterization: Define variables that can be overridden at build time
- Inheritance: Reuse and extend configuration across targets
- Grouping: Define groups of targets to build together
- Platform Support: Easily build for multiple platforms
- Integration: Works with Docker Compose and Docker BuildKit
- HCL: When you need the most flexibility and features
- JSON: When your tooling or CI/CD system works best with JSON
- YAML: When you prefer YAML syntax or have a YAML-based infrastructure
While Docker Compose focuses on defining and running multi-container applications, Docker Bake focuses on building images with complex configurations.
Docker Compose can use images built by Docker Bake to run your application in different environments.
- Cache Mounting: Improve build performance with cache mounts
- Secret Management: Use secrets securely in your builds
- CI/CD Integration: Integrate Docker Bake into your CI/CD pipelines
- Custom BuildKit Frontends: Extend Docker Bake with custom frontends
If you want to run the application locally without Docker:
cd app
npm install
npm run devThe application will be available at http://localhost:3000.
The following issues were identified and fixed during cross-checking:
-
Docker Compose V2 Compatibility:
- Updated all commands from
docker-composetodocker compose(without hyphen) - Removed the obsolete
version: "3.8"from docker-compose.yml
- Updated all commands from
-
npm Installation Improvements:
- Using
npm installinstead ofnpm ci --quietin the Dockerfile since we don't have a package-lock.json file
- Using
These changes ensure that the project runs smoothly with the latest versions of Docker and Docker Compose.