Go with Go Modules
Best practices for Dockerfile for Go with Go Modules
🐳 Annotated Dockerfile for Go with Go Modules:
🔍 Why these are best practices:
✅ Multi-stage builds
- Dramatically reduces final image size.
- Eliminates all build dependencies and the Go compiler from the runtime image.
- Final image contains only your statically compiled Go binary.
✅ Go Modules for dependency management
- Ensures reproducible builds with explicit dependency versions.
- go.mod and go.sum provide deterministic dependency resolution.
- Downloads dependencies first to leverage Docker's caching.
✅ Caching Go modules and build cache
- Uses Docker's build cache efficiently to avoid redundant downloads.
- Significantly speeds up builds on iterative development.
- Saves bandwidth and time, especially important in CI/CD environments.
✅ Static binary compilation
- CGO_ENABLED=0 creates binaries with no external dependencies.
- Allows use of scratch or distroless containers for maximum security.
- Simplifies deployment across different environments.
✅ Binary optimization
- Strips debug information to reduce binary size.
- Smaller binaries mean faster container startup and smaller images.
- Reduces attack surface by eliminating unnecessary information.
🚀 Additional Dockerfile best practices you can adopt:
Use scratch instead of distroless for even smaller images
If your application doesn't need certificates or other basics:
Build for multiple architectures
For cross-platform compatibility:
Add build-time metadata with ldflags
Include version info and build timestamps:
Vendor dependencies for air-gapped builds
For environments without internet access:
Use .dockerignore
Exclude unnecessary files from your Docker build context:
Configure health checks
Ensure your container reports health correctly:
Enable Go's build-time security checks
For enhanced security scanning during builds:
By following these practices, you'll create Docker images for your Go applications that are secure, efficient, and optimized for production environments. Go's strengths in producing small, statically-linked binaries make it an excellent language for containerized deployments.
Last updated on