Build statically-linked binaries using Docker multi-stage builds for portable, minimal container deployments.
- Static Linking - Produce fully statically-linked binaries using musl libc
- Multi-stage Builds - Leverage Docker BuildKit for efficient, cacheable builds
- Minimal Images - Target Red Hat UBI9 Micro or similar minimal runtime images
- Extensible - Add new build targets by following a simple directory structure
- Reproducible - Version-controlled configurations via
.envfiles
- Docker with Docker Compose
- BuildKit support (automatically uses
moby/buildkit:rootless)
make build <target>make help
make list-targets
make build nginxBuild artifacts are written directly under <target>/.
.
├── build.sh # Main build entry point
├── download.sh # Download dispatcher (routes to module download.sh)
├── .github/
│ ├── docker-compose.yaml
│ └── scripts/
│ └── common.sh # Shared common functions
└── <target>/ # Build target directory
├── .env # Version configuration
├── Dockerfile # Multi-stage build definition
├── download.sh # Source download script (optional)
└── ... # Built artifacts (for example `sbin/`, `bin/`)
-
Create a new directory with your target name
-
Add a
.envfile with version variables:ALPINE_VERSION=3.23 YOUR_SOFTWARE_VERSION=1.0.0 -
Add a
Dockerfilewith your multi-stage build configuration -
Optionally add
download.shfor source downloads
Tip
Check existing targets (nginx/, haproxy/, apache-httpd/) for reference implementations.
- The
Makefileinvokesbuild.sh, which validates the target directory and required files - Docker Compose launches a BuildKit container
- BuildKit executes the multi-stage Dockerfile
- Built artifacts are output directly into the target directory
Build caching is automatically handled via the .cache/ directory.
- Archive upload includes selected release files as a workflow artifact.
- Release upload is optional and packages selected release files into one
.tgzper tag. - To enable release upload in GitHub Actions, set
release=trueand use one of:release_tag: explicit full tag (for example,httpd-2.4.66.1)release_suffix: custom last segment; CI composes<name>-<version>.<suffix>
- Tag push release uses per-target caller workflows:
.github/workflows/release-nginx-from-tag.yaml.github/workflows/release-haproxy-from-tag.yaml.github/workflows/release-httpd-from-tag.yaml.github/workflows/release-coredns-from-tag.yaml.github/workflows/release-dnsmasq-from-tag.yaml.github/workflows/release-vector-from-tag.yaml
- Each caller is bound to one tag pattern (
nginx-*,haproxy-*,httpd-*,coredns-*,dnsmasq-*,vector-*) and calls reusable template.github/workflows/template-release.yaml. - Template builds mapped target, uploads selected files as artifact, then uploads
${tag}.tgzthat contains selected release files.
Selected release binaries:
nginx:<target>/sbin/nginxhaproxy:<target>/sbin/haproxyapache-httpd:<target>/bin/httpdcoredns:<target>/corednsdnsmasq:<target>/sbin/dnsmasqvector:<target>/bin/vector
Note: apache-httpd releases include both bin/httpd and bin/rotatelogs for piped logging support.
The rotatelogs utility is included in apache-httpd releases and can be used for log rotation:
- External rotatelogs: Use a system-installed
rotatelogsor provide it separately - Alternative rotation tools: Use
logrotate,multilog, or other log rotation solutions - Application-level logging: Configure applications to write directly to files managed by external rotation
For containerized deployments, leverage Docker's native logging drivers:
# Example: Use Docker's built-in log rotation
docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 <image>
# Or use external logging drivers
docker run --log-driver fluentd --log-opt fluentd-address=fluentd:24224 <image>Docker automatically handles log rotation and can forward logs to external systems like ELK, Splunk, or cloud logging services.
See the ADR document at .sisyphus/plans/rotatelogs-packaging-decision.md for the complete decision rationale and implementation guidance.
docker run --rm \
-v "$(pwd)/haproxy.cfg:/etc/haproxy/haproxy.cfg:ro" \
<image> -c -f /etc/haproxy/haproxy.cfg