diff --git a/README.md b/README.md index f27f8160..1e3ca2df 100644 --- a/README.md +++ b/README.md @@ -281,6 +281,16 @@ export BUILDKIT_HOST=tcp://0.0.0.0:1234 buildctl build --help ``` +To run client and an ephemeral daemon in a single container ("daemonless mode"): + +``` +docker run -it --rm --privileged -v /path/to/dir:/tmp/work --entrypoint buildctl-daemonless.sh moby/buildkit:master build --frontend dockerfile.v0 --local context=/tmp/work --local dockerfile=/tmp/work +``` +or +``` +docker run -it --rm --security-opt seccomp=unconfined --security-opt apparmor=unconfined -e BUILDKITD_FLAGS=--oci-worker-no-process-sandbox -v /path/to/dir:/tmp/work --entrypoint buildctl-daemonless.sh moby/buildkit:master-rootless build --frontend dockerfile.v0 --local context=/tmp/work --local dockerfile=/tmp/work +``` + The images can be also built locally using `./hack/dockerfiles/test.Dockerfile` (or `./hack/dockerfiles/test.buildkit.Dockerfile` if you already have BuildKit). Run `make images` to build the images as `moby/buildkit:local` and `moby/buildkit:local-rootless`. diff --git a/examples/buildctl-daemonless/buildctl-daemonless.sh b/examples/buildctl-daemonless/buildctl-daemonless.sh new file mode 100755 index 00000000..f2e8e17f --- /dev/null +++ b/examples/buildctl-daemonless/buildctl-daemonless.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# buildctl-daemonless.sh spawns ephemeral buildkitd for executing buildctl. +# +# Usage: buildctl-daemonless.sh build ... +# +# Flags for buildkitd can be specified as $BUILDKITD_FLAGS . +# +# The script is compatible with BusyBox shell. +set -eu + +: ${BUILDCTL=buildctl} +: ${BUILDKITD=buildkitd} +: ${BUILDKITD_FLAGS=} +: ${ROOTLESSKIT=rootlesskit} + +# $tmp holds the following files: +# * pid +# * addr +# * log +tmp=$(mktemp -d /tmp/buildctl-daemonless.XXXXXX) +trap "kill \$(cat $tmp/pid); rm -rf $tmp" EXIT + +startBuildkitd() { + addr= + helper= + if [ $(id -u) = 0 ]; then + addr=unix:///run/buildkit/buildkitd.sock + else + addr=unix://$XDG_RUNTIME_DIR/buildkit/buildkitd.sock + helper=$ROOTLESSKIT + fi + $helper $BUILDKITD $BUILDKITD_FLAGS --addr=$addr >$tmp/log 2>&1 & + pid=$! + echo $pid >$tmp/pid + echo $addr >$tmp/addr +} + +# buildkitd supports NOTIFY_SOCKET but as far as we know, there is no easy way +# to wait for NOTIFY_SOCKET activation using busybox-builtin commands... +waitForBuildkitd() { + addr=$(cat $tmp/addr) + try=0 + max=10 + until $BUILDCTL --addr=$addr debug workers >/dev/null 2>&1; do + if [ $try -gt $max ]; then + echo >&2 "could not connect to $addr after $max trials" + exit 1 + fi + sleep $(awk "BEGIN{print (100 + $try * 20) * 0.001}") + try=$(expr $try + 1) + done +} + +startBuildkitd +waitForBuildkitd +$BUILDCTL --addr=$(cat $tmp/addr) $@ diff --git a/hack/dockerfiles/test.Dockerfile b/hack/dockerfiles/test.Dockerfile index d42fdae7..e4789632 100644 --- a/hack/dockerfiles/test.Dockerfile +++ b/hack/dockerfiles/test.Dockerfile @@ -126,6 +126,7 @@ RUN go build -ldflags "$(cat .tmp/ldflags)" -o /out/buildkitd.exe ./cmd/buildkit FROM alpine AS buildkit-export RUN apk add --no-cache git +COPY examples/buildctl-daemonless/buildctl-daemonless.sh /usr/bin/ VOLUME /var/lib/buildkit # Copy together all binaries for oci+containerd mode diff --git a/hack/dockerfiles/test.buildkit.Dockerfile b/hack/dockerfiles/test.buildkit.Dockerfile index 846f1bfe..084ee214 100644 --- a/hack/dockerfiles/test.buildkit.Dockerfile +++ b/hack/dockerfiles/test.buildkit.Dockerfile @@ -124,6 +124,7 @@ FROM scratch AS release COPY --from=releaser /out/ / FROM tonistiigi/git@sha256:704fcc24a17b40833625ee37c4a4acf0e4aa90d0aa276926d63847097134defd AS buildkit-export +COPY examples/buildctl-daemonless/buildctl-daemonless.sh /usr/bin/ VOLUME /var/lib/buildkit FROM git AS containerd-src @@ -252,6 +253,7 @@ FROM rootless-base-$ROOTLESS_BASE_MODE AS rootless-base FROM rootless-base AS rootless COPY --from=rootlesskit /rootlesskit /usr/bin/ COPY --from=binaries / /usr/bin/ +COPY examples/buildctl-daemonless/buildctl-daemonless.sh /usr/bin/ USER user ENV HOME /home/user ENV USER user