Skip to content

Commit de3f3ec

Browse files
committed
Add rootless container builds via Docker/Podman
- update builder image Dockerfile - copy project/repo content into container at build time - explicitly changing owner:group to `builduser` - explicitly create new `builduser` user and group - this is explicitly used for Docker-based builds - set `/builds` as the working directory - add new `.dockerignore` file to exclude the same items as the `.gitignore` file - set Git `safe.directory` logic at system level - update Makefile recipes - add separate docker/podman variants of container-based project build recipes - each uses slightly different logic to achieve rootless container execution - explicitly emit the tool used to perform specific tasks - this can be useful to help explain why a generated builder image does not appear in the `docker image ls` output as a sysadmin might expect (if it was instead built with the `docker` command) - rename/remove the helper build recipe from the `help` recipe output (not useful to call directly) - to explicitly run the build container as the `builduser` user that is created during build image generation when using Docker to build/run containers (Podman uses different settings) - to send `xz` compressed output to stdout, then redirect to a target file - this works around failures to `chmod` and `chgrp` the compressed copy of input files when run within a non-root container - to explicitly bind mount the `release_assets` path into `/builds/release_assets` (using the same Makefile variable) read/write (instead of relying on implied read/write access) - to explicitly use `/builds` as the working directory This collection of changes allows reliably building this project using either Docker or Podman via a "rootless" container.
1 parent 76bb8ba commit de3f3ec

File tree

3 files changed

+185
-45
lines changed

3 files changed

+185
-45
lines changed

.dockerignore

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright 2023 Adam Chalkley
2+
#
3+
# https://github.com/atc0005/check-cert
4+
#
5+
# Licensed under the MIT License. See LICENSE file in the project root for
6+
# full license information.
7+
8+
# Binaries for programs and plugins
9+
*.exe
10+
*.exe~
11+
*.dll
12+
*.so
13+
*.dylib
14+
15+
# Test binary, built with `go test -c`
16+
*.test
17+
18+
# Output of the go coverage tool, specifically when used with LiteIDE
19+
*.out
20+
21+
# Ignore Visual Studio Code workspace-level settings
22+
/.vscode
23+
24+
# Ignore go generate produced Windows executable resource files
25+
*.syso
26+
27+
# Ignore local "scratch" directory of temporary files
28+
scratch/
29+
30+
# Ignore plugin name in its multiple (potential) variations
31+
/check_cert
32+
/check-cert
33+
34+
# Ignore one-off CLI app builds
35+
/lscert
36+
/certsum
37+
38+
# Generated assets are placed here
39+
/release_assets

Makefile

+123-45
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ QUICK_BUILDCMD := go build -mod=vendor
135135
GOCLEANCMD := go clean -mod=vendor ./...
136136
GITCLEANCMD := git clean -xfd
137137
CHECKSUMCMD := sha256sum -b
138-
COMPRESSCMD := xz --compress --threads=0
138+
COMPRESSCMD := xz --compress --threads=0 --stdout
139139

140140
.DEFAULT_GOAL := help
141141

@@ -302,7 +302,9 @@ windows-x86-compress:
302302

303303
@set -e; for target in $(WHAT); do \
304304
echo " compressing $$target 386 binary" && \
305-
$(COMPRESSCMD) $(ASSETS_PATH)/$$target/$$target-windows-386.exe; \
305+
$(COMPRESSCMD) $(ASSETS_PATH)/$$target/$$target-windows-386.exe > \
306+
$(ASSETS_PATH)/$$target/$$target-windows-386.exe.xz && \
307+
rm -f $(ASSETS_PATH)/$$target/$$target-windows-386.exe; \
306308
done
307309

308310
@echo "Completed compress tasks for windows x86"
@@ -358,7 +360,9 @@ windows-x64-compress:
358360

359361
@set -e; for target in $(WHAT); do \
360362
echo " compressing $$target amd64 binary" && \
361-
$(COMPRESSCMD) $(ASSETS_PATH)/$$target/$$target-windows-amd64.exe; \
363+
$(COMPRESSCMD) $(ASSETS_PATH)/$$target/$$target-windows-amd64.exe > \
364+
$(ASSETS_PATH)/$$target/$$target-windows-amd64.exe.xz && \
365+
rm -f $(ASSETS_PATH)/$$target/$$target-windows-amd64.exe; \
362366
done
363367

364368
@echo "Completed compress tasks for windows x64"
@@ -430,7 +434,9 @@ linux-x86-compress:
430434

431435
@set -e; for target in $(WHAT); do \
432436
echo " compressing $$target 386 binary" && \
433-
$(COMPRESSCMD) $(ASSETS_PATH)/$$target/$$target-linux-386; \
437+
$(COMPRESSCMD) $(ASSETS_PATH)/$$target/$$target-linux-386 > \
438+
$(ASSETS_PATH)/$$target/$$target-linux-386.xz && \
439+
rm -f $(ASSETS_PATH)/$$target/$$target-linux-386; \
434440
done
435441

436442
@echo "Completed compress tasks for linux x86"
@@ -482,7 +488,9 @@ linux-x64-compress:
482488

483489
@set -e; for target in $(WHAT); do \
484490
echo " compressing $$target amd64 binary" && \
485-
$(COMPRESSCMD) $(ASSETS_PATH)/$$target/$$target-linux-amd64; \
491+
$(COMPRESSCMD) $(ASSETS_PATH)/$$target/$$target-linux-amd64 > \
492+
$(ASSETS_PATH)/$$target/$$target-linux-amd64.xz && \
493+
rm -f $(ASSETS_PATH)/$$target/$$target-linux-amd64; \
486494
done
487495

488496
@echo "Completed compress tasks for linux x64"
@@ -532,7 +540,9 @@ linux-x64-dev-compress:
532540

533541
@set -e; for target in $(WHAT); do \
534542
echo " compressing $$target amd64 binary" && \
535-
$(COMPRESSCMD) $(ASSETS_PATH)/$$target/$$target-linux-amd64-dev; \
543+
$(COMPRESSCMD) $(ASSETS_PATH)/$$target/$$target-linux-amd64-dev > \
544+
$(ASSETS_PATH)/$$target/$$target-linux-amd64-dev.xz && \
545+
rm -f $(ASSETS_PATH)/$$target/$$target-linux-amd64-dev; \
536546
done
537547

538548
@echo "Completed dev compress tasks for linux x64"
@@ -752,89 +762,157 @@ dev-build: clean linux-x64-dev-build packages-dev package-links linux-x64-dev-co
752762
release-build: clean windows linux-x86 packages-dev clean-linux-x64-dev packages-stable linux-x64-compress linux-x64-checksums links
753763
@echo "Completed all tasks for stable release build"
754764

755-
.PHONY: helper-docker-builder-setup
756-
## helper-docker-builder-setup: refreshes builder image for Docker-based tasks
757-
helper-docker-builder-setup:
765+
.PHONY: helper-builder-setup
766+
helper-builder-setup:
758767

759-
@echo "Beginning regeneration of Docker builder image"
768+
@echo "Beginning regeneration of builder image using $(CONTAINER_COMMAND)"
760769
@echo "Removing any previous build image"
761-
@docker image prune --all --force --filter "label=atc0005_projects_builder_image"
770+
$(CONTAINER_COMMAND) image prune --all --force --filter "label=atc0005_projects_builder_image"
762771

763-
@echo "Gathering Docker build environment details"
764-
@docker version
772+
@echo "Gathering $(CONTAINER_COMMAND) build environment details"
773+
@$(CONTAINER_COMMAND) version
765774

766775
@echo
767776
@echo "Generating release builder image"
768-
@docker image build \
777+
$(CONTAINER_COMMAND) image build \
769778
--pull \
770779
--no-cache \
771780
--force-rm \
772-
dependabot/docker/builds/ \
781+
. \
782+
-f dependabot/docker/builds/Dockerfile \
773783
-t builder_image \
774784
--label="atc0005_projects_builder_image"
775785
@echo "Completed generation of release builder image"
776786

787+
@echo "Listing current container images managed by $(CONTAINER_COMMAND)"
788+
$(CONTAINER_COMMAND) image ls
789+
777790
@echo
778-
@echo "Inspecting release builder image environment"
779-
@docker inspect --format "{{range .Config.Env}}{{println .}}{{end}}" builder_image
791+
@echo "Inspecting release builder image environment using $(CONTAINER_COMMAND)"
792+
@$(CONTAINER_COMMAND) inspect --format "{{range .Config.Env}}{{println .}}{{end}}" builder_image
793+
794+
@echo "Completed regeneration of builder image using $(CONTAINER_COMMAND)"
780795

781-
@echo "Completed regeneration of Docker builder image"
796+
@echo "Prepare output path for generated assets"
797+
@mkdir -p $(ASSETS_PATH)
782798

783799
.PHONY: docker-release-build
784-
## docker-release-build: generates stable build assets for public release using Docker
785-
docker-release-build: clean helper-docker-builder-setup
800+
## docker-release-build: generates stable build assets for public release using docker container
801+
docker-release-build: CONTAINER_COMMAND := docker
802+
docker-release-build: clean helper-builder-setup
786803

787-
@echo "Beginning release build using Docker"
804+
@echo "Beginning release build using $(CONTAINER_COMMAND)"
788805

789806
@echo
790807
@echo "Using release builder image to generate project release assets"
791-
@docker container run \
792-
--user $${UID:-1000} \
808+
$(CONTAINER_COMMAND) container run \
809+
--user builduser:builduser \
793810
--rm \
794811
-i \
795-
-v $$PWD:$$PWD \
796-
-w $$PWD \
812+
-v $$PWD/$(OUTPUTDIR):/builds/$(OUTPUTDIR):rw \
813+
-w /builds \
797814
builder_image \
798-
env GOCACHE=/tmp/ make release-build
815+
make release-build
816+
817+
@echo "Completed release build using $(CONTAINER_COMMAND)"
818+
819+
.PHONY: podman-release-build
820+
## podman-release-build: generates stable build assets for public release using podman container
821+
podman-release-build: CONTAINER_COMMAND := podman
822+
podman-release-build: clean helper-builder-setup
799823

800-
@echo "Completed release build using Docker"
824+
@echo "Beginning release build using $(CONTAINER_COMMAND)"
825+
826+
@echo
827+
@echo "Using release builder image to generate project release assets"
828+
$(CONTAINER_COMMAND) container run \
829+
--rm \
830+
-i \
831+
-v $$PWD/$(OUTPUTDIR):/builds/$(OUTPUTDIR):rw \
832+
-w /builds \
833+
builder_image \
834+
make release-build
835+
836+
@echo "Completed release build using $(CONTAINER_COMMAND)"
801837

802838
.PHONY: docker-dev-build
803-
## docker-dev-build: generates dev build assets for public release using Docker
804-
docker-dev-build: clean helper-docker-builder-setup
839+
## docker-dev-build: generates dev build assets for public release using docker container
840+
docker-dev-build: CONTAINER_COMMAND := docker
841+
docker-dev-build: clean helper-builder-setup
805842

806-
@echo "Beginning dev build using Docker"
843+
@echo "Beginning dev build using $(CONTAINER_COMMAND)"
807844

808845
@echo
809846
@echo "Using release builder image to generate project release assets"
810-
@docker container run \
811-
--user $${UID:-1000} \
847+
$(CONTAINER_COMMAND) container run \
848+
--user builduser:builduser \
812849
--rm \
813850
-i \
814-
-v $$PWD:$$PWD \
815-
-w $$PWD \
851+
-v $$PWD/$(OUTPUTDIR):/builds/$(OUTPUTDIR):rw \
852+
-w /builds \
816853
builder_image \
817-
env GOCACHE=/tmp/ make dev-build
854+
make dev-build
818855

819-
@echo "Completed dev build using Docker"
856+
@echo "Completed dev build using $(CONTAINER_COMMAND)"
820857

858+
.PHONY: podman-dev-build
859+
## podman-dev-build: generates dev build assets for public release using podman container
860+
podman-dev-build: CONTAINER_COMMAND := podman
861+
podman-dev-build: clean helper-builder-setup
821862

863+
@echo "Beginning dev build using $(CONTAINER_COMMAND)"
864+
865+
@echo
866+
@echo "Using release builder image to generate project release assets"
867+
$(CONTAINER_COMMAND) container run \
868+
--rm \
869+
-i \
870+
-v $$PWD/$(OUTPUTDIR):/builds/$(OUTPUTDIR):rw \
871+
-w /builds \
872+
builder_image \
873+
make dev-build
874+
875+
@echo "Completed dev build using $(CONTAINER_COMMAND)"
822876

823877
.PHONY: docker-packages
824-
## docker-packages: generates dev and stable packages using Docker
825-
docker-packages: helper-docker-builder-setup
878+
## docker-packages: generates dev and stable packages using builder image
879+
docker-packages: CONTAINER_COMMAND := docker
880+
docker-packages: helper-builder-setup
881+
882+
@echo "Beginning package generation using $(CONTAINER_COMMAND)"
883+
884+
@echo
885+
@echo "Using release builder image to generate packages"
826886

827-
@echo "Beginning package generation using Docker"
887+
@echo "Building with $(CONTAINER_COMMAND)"
888+
$(CONTAINER_COMMAND) container run \
889+
--rm \
890+
--user builduser:builduser \
891+
-i \
892+
-v $$PWD/$(OUTPUTDIR):/builds/$(OUTPUTDIR):rw \
893+
-w /builds \
894+
builder_image \
895+
make packages
896+
897+
@echo "Completed package generation using $(CONTAINER_COMMAND)"
898+
899+
.PHONY: podman-packages
900+
## podman-packages: generates dev and stable packages using podman container
901+
podman-packages: CONTAINER_COMMAND := podman
902+
podman-packages: helper-builder-setup
903+
904+
@echo "Beginning package generation using $(CONTAINER_COMMAND)"
828905

829906
@echo
830907
@echo "Using release builder image to generate packages"
831-
@docker container run \
832-
--user $${UID:-1000} \
908+
909+
@echo "Building with $(CONTAINER_COMMAND)"
910+
$(CONTAINER_COMMAND) container run \
833911
--rm \
834912
-i \
835-
-v $$PWD:$$PWD \
836-
-w $$PWD \
913+
-v $$PWD/$(OUTPUTDIR):/builds/$(OUTPUTDIR):rw \
914+
-w /builds \
837915
builder_image \
838-
env GOCACHE=/tmp/ make packages
916+
make packages
839917

840-
@echo "Completed package generation using Docker"
918+
@echo "Completed package generation using $(CONTAINER_COMMAND)"

dependabot/docker/builds/Dockerfile

+23
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,26 @@
1414
# https://github.com/atc0005/go-ci/releases
1515
# https://github.com/atc0005/go-ci/pkgs/container/go-ci
1616
FROM ghcr.io/atc0005/go-ci:go-ci-oldstable-build-v0.9.1
17+
18+
# Setup isolated build environment with a full copy of the Git repo contents
19+
# MINUS any file or path listed in the .dockerignore file at the root of this
20+
# repo.
21+
RUN useradd --create-home --shell /bin/bash --user-group builduser
22+
23+
# Prevent Git from complaining when it encounters Git-tracked directories that
24+
# are owned by someone other than the current user. We set this at the
25+
# "system" level so that the setting is not specific to any one user account.
26+
#
27+
# https://stackoverflow.com/questions/71849415/i-cannot-add-the-parent-directory-to-safe-directory-in-git
28+
# https://git-scm.com/docs/git-config/2.35.2#Documentation/git-config.txt-safedirectory
29+
# https://github.com/git/git/commit/8959555cee7ec045958f9b6dd62e541affb7e7d9
30+
RUN git config --system --add safe.directory '*'
31+
32+
# We skip setting a specific container user. This allows generating a
33+
# container with a bind-mounted path using Podman and explicitly specifying
34+
# `--user builduser:builduser` using Docker.
35+
#
36+
#USER builduser
37+
38+
WORKDIR /builds
39+
COPY --chown=builduser:builduser . /builds

0 commit comments

Comments
 (0)