Docker Build Guide
This guide explains how to build Docker images for VMProber with support for multiple platforms and different base images.
Available Dockerfiles
Dockerfile (Alpine-based)
- Base image:
alpine:latest - Size: ~15-20 MB
- Features:
- Full shell and utilities (wget, etc.)
- Healthcheck support
- CA certificates included
- Timezone data
Dockerfile.scratch (Minimal)
- Base image:
scratch(empty) - Size: ~5-10 MB
- Features:
- Minimal size
- Only binary and CA certificates
- No shell or utilities
- No healthcheck (configure at orchestrator level)
Building Images
Using Makefile
# Build Alpine image for current platform
make -f Makefile.docker docker-build
# Build Alpine image for multiple platforms (amd64, arm64)
make -f Makefile.docker docker-build-alpine
# Build Scratch image for multiple platforms
make -f Makefile.docker docker-build-scratch
# Build all variants
make -f Makefile.docker docker-build-all
# Build with custom version
make -f Makefile.docker docker-build-alpine VERSION=1.0.0
# Build for specific platforms
make -f Makefile.docker docker-build-alpine PLATFORMS=linux/amd64,linux/arm64,linux/arm/v7
# Push to registry
make -f Makefile.docker docker-push REGISTRY=myregistry.io VERSION=1.0.0
Using Build Script
# Build Alpine image
./build-docker.sh --dockerfile Dockerfile --version 1.0.0
# Build Scratch image
./build-docker.sh --dockerfile Dockerfile.scratch --version 1.0.0
# Build for specific platforms
./build-docker.sh --platforms linux/amd64,linux/arm64
# Build and push to registry
./build-docker.sh --registry myregistry.io --push
# Build single platform
./build-docker.sh --single-platform linux/arm64
Using Docker Buildx Directly
# Create buildx builder (if not exists)
docker buildx create --name multiarch --use --bootstrap
# Build Alpine image
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg VERSION=1.0.0 \
--build-arg BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--build-arg GIT_COMMIT=$(git rev-parse --short HEAD) \
-t vmprober:1.0.0-alpine \
-f Dockerfile \
--load \
.
# Build Scratch image
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg VERSION=1.0.0 \
--build-arg BUILD_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--build-arg GIT_COMMIT=$(git rev-parse --short HEAD) \
-t vmprober:1.0.0-scratch \
-f Dockerfile.scratch \
--load \
.
Image Tags
Images are tagged with the following pattern:
{registry}/{image-name}:{version}-{variant}{registry}/{image-name}:latest-{variant}
Examples:
vmprober:1.0.0-alpinevmprober:latest-scratchmyregistry.io/vmprober:1.0.0-alpine
Supported Platforms
linux/amd64- Intel/AMD 64-bitlinux/arm64- ARM 64-bit (Apple Silicon, ARM servers)linux/arm/v7- ARM 32-bit (optional)
Running Images
Alpine Image
docker run -d \
--name vmprober \
-p 8429:8429 \
-v $(pwd)/config.yaml:/etc/vmprober/config.yaml \
vmprober:latest-alpine
Scratch Image
docker run -d \
--name vmprober \
-p 8429:8429 \
-v $(pwd)/config.yaml:/etc/vmprober/config.yaml \
vmprober:latest-scratch
Health Checks
Alpine Image
The Alpine image includes a built-in healthcheck:
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8429/health || exit 1
Scratch Image
The Scratch image does not include a healthcheck (no shell/tools available). Configure healthcheck at the orchestrator level:
Kubernetes:
livenessProbe:
httpGet:
path: /health
port: 8429
initialDelaySeconds: 5
periodSeconds: 30
Docker Compose:
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:8429/health"]
interval: 30s
timeout: 3s
retries: 3
Configuration
Both images expect configuration at /etc/vmprober/config.yaml. You can:
- Mount a config file:
docker run -v /path/to/config.yaml:/etc/vmprober/config.yaml vmprober:latest-alpine -
Use environment variables (if supported by the application)
- Override config path:
docker run vmprober:latest-alpine --config=/custom/path/config.yaml
WAL Directory
The WAL (Write-Ahead Log) directory is automatically created by the application at runtime. By default, it uses /var/lib/vmprober/wal. You can mount a volume:
docker run -v /host/wal:/var/lib/vmprober/wal vmprober:latest-alpine
Troubleshooting
Build fails with “platform not supported”
Ensure you have QEMU installed for cross-platform builds:
# macOS
brew install qemu
# Linux
sudo apt-get install qemu-user-static
Scratch image can’t connect to HTTPS endpoints
Ensure CA certificates are properly included. The scratch image includes CA certificates from the builder stage.
Healthcheck fails in scratch image
Use external healthcheck tools or configure healthcheck at the orchestrator level (Kubernetes, Docker Swarm, etc.).
CI/CD Integration
GitHub Actions Example
name: Build and Push Docker Images
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Registry
uses: docker/login-action@v2
with:
registry: $
username: $
password: $
- name: Build and Push Alpine
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: |
$/vmprober:$-alpine
$/vmprober:latest-alpine
build-args: |
VERSION=$
BUILD_TIME=$
GIT_COMMIT=$
- name: Build and Push Scratch
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile.scratch
platforms: linux/amd64,linux/arm64
push: true
tags: |
$/vmprober:$-scratch
$/vmprober:latest-scratch
build-args: |
VERSION=$
BUILD_TIME=$
GIT_COMMIT=$
Best Practices
- Use Alpine for development - easier debugging with shell access
- Use Scratch for production - minimal attack surface and size
- Always specify version tags - avoid using
latestin production - Build for your target platform - test on the same architecture
- Mount configs as volumes - don’t bake configs into images
- Use healthchecks - configure at orchestrator level for scratch images