Package
Bake your services and their build dependencies into self-contained Docker images and push them to a registry.
The package command turns the container services of your build file into
Docker images. For each service hammerkit builds a multi-stage image that bakes
in the service itself plus the outputs of every task the service depends on, so
the resulting image is self-contained and ready to run without hammerkit.
hammerkit package <registry>The image for a service api is named <registry>/api:<tag>, where the tag
defaults to latest (see Versioning). The <registry> argument is
required - it is the prefix of the produced image name and the target of --push.
Packaging only runs against the Docker runtime. Services without a container
image, and dependency tasks that run locally (without an image), are not
supported.
What gets packaged
For every container service hammerkit generates a Dockerfile that:
- starts
FROMthe service image, - copies the generated outputs of the service's dependency tasks (
deps) into the image, - applies the service
envs,ports(asEXPOSE) andcmd, - labels the image with
hammerkit.dev/nameandhammerkit.dev/id.
A service with no command and no dependencies still produces a valid image from its base image and sources.
Pushing to a registry
Add --push to upload the built images to the registry. Credentials can be
passed with -u/--username and -p/--password.
hammerkit package registry.example.com --push -u ci -p $REGISTRY_TOKENRegistry examples
The <registry> argument is just the image-name prefix, so any registry works:
# Docker Hub - produces docker.io/<user>/api
hammerkit package docker.io/<user> --push -u <user> -p $DOCKER_TOKEN
# GitHub Container Registry
hammerkit package ghcr.io/<org> --push -u <user> -p $GITHUB_TOKEN
# GitLab Container Registry (inside CI the variables are provided for you)
hammerkit package registry.gitlab.com/<group>/<project> \
--push -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORDVersioning
By default the produced image is tagged latest. Use -t/--tag to pin an
explicit version - for example a release number or a CI commit SHA - so the same
build can be promoted across environments:
hammerkit package registry.example.com -t 1.2.3 --pushproduces and pushes registry.example.com/api:1.2.3.
Build platform
By default hammerkit builds for the host architecture (linux/amd64 on x64,
linux/arm64 on arm64 / Apple Silicon). Override it with --platform to build for
a different target, for example when building on arm for an amd64 cluster:
hammerkit package registry.example.com --platform linux/amd64--platform is forwarded to the Docker build, so the Docker daemon must be able to
build that platform (BuildKit / emulation enabled for cross-architecture builds).
Example
Given a service that depends on an install task:
services:
api:
image: node:alpine
deps: [install]
cmd: node server.js
ports: [3000]
mounts: [server.js]
tasks:
install:
image: node:alpine
src:
- package.json
- package-lock.json
generates:
- node_modules
cmds:
- npm cihammerkit package localhost:5000 --pushproduces and pushes localhost:5000/api, with the node_modules produced by
install already baked in.
Options
Options:
-f, --filter <labels...> filter task and services with labels
-e, --exclude <labels...> exclude task and services with labels
--push push image to registry (default: false)
--build-override-user create and run as a dedicated uid/gid 1000 user
-t, --tag <tag> image tag (default: "latest")
--platform <platform> target build platform (default: host architecture)
-u, --username registry username
-p, --password registry password
-h, --help display help for command