Parallel multi-platform builds (amd64 + arm64) fire ~14 unauthenticated
GitHub API calls concurrently — well over the 60 req/hr limit — causing
05-custom.sh to fail with a 403 on dominikh/go-tools (staticcheck).
Fix: _gh_latest now retries up to 3 times with a 60-second delay on
failure before giving up. A GITHUB_TOKEN build arg is also wired through
to the build stage ENV so callers can pass --build-arg GITHUB_TOKEN=$(gh
auth token) to raise the limit to 5000 req/hr and avoid the delay.
- Dockerfile: add ARG GITHUB_TOKEN="" and ENV GITHUB_TOKEN in build stage
- rootfs/root/docker/setup/05-custom.sh: retry loop (3 attempts, 60s backoff) in _gh_latest
Dockerfile
rootfs/root/docker/setup/05-custom.sh
- Dockerfile: add GOFLAGS=-buildvcs=false to prevent VCS stamp errors when
users mount projects without a .git directory (Go 1.18+ default behaviour)
- Dockerfile: add GOTELEMETRY=off to disable Go 1.23+ telemetry in containers
- Dockerfile: add GOPROXY=https://proxy.golang.org,direct (explicit default,
makes override via --env obvious)
- Dockerfile: add GOBIN=/usr/local/bin to the final stage — was set in the
build stage but missing from the scratch-based final stage; without it,
go install inside the running container lands binaries in /usr/local/share/go/bin
instead of /usr/local/bin
Dockerfile
go install rejects multiple packages from different modules in a single
invocation. Split all 11 go install calls into individual commands chained
with &&.
- Dockerfile: split single multi-package go install into 11 separate
go install calls, one per module, chained with &&
Dockerfile
The arm64 build was stuck for 12+ hours compiling gopls, dlv, and other
Go tools from source under QEMU user-mode emulation. QEMU makes Go
compilation 20-50× slower than native; gopls alone can take hours.
Fix: add a --platform=$BUILDPLATFORM go-tools stage in the Dockerfile that
cross-compiles all go install tools natively on amd64 using Go's built-in
cross-compilation (GOOS=linux GOARCH=$TARGETARCH). The binaries are then
COPYed into the main build stage before 05-custom.sh runs. No QEMU is
involved for any compilation step.
- Dockerfile: add go-tools stage using --platform=$BUILDPLATFORM with golang:alpine;
cross-compiles goimports, stringer, gopls, govulncheck, dlv, gops, benchstat,
wire, mockgen, protoc-gen-go, protoc-gen-go-grpc; COPY /go/bin/ → /usr/local/bin/
before the 05-custom.sh RUN layer
- rootfs/root/docker/setup/05-custom.sh: remove all go install commands (11 tools
now provided by the Dockerfile stage); keep go clean -modcache/-cache cleanup
Dockerfile
rootfs/root/docker/setup/05-custom.sh
Add buf (modern protobuf toolchain) and goose (Go-native DB migration
runner) to complete the Go dev toolchain. Fix PATH order so baked image
tools in /usr/local/bin always take precedence over anything installed
at runtime into $GOPATH/bin. Full README rewrite following canonical
section order.
- Dockerfile: insert /usr/local/bin between /usr/local/go/bin and
/usr/local/share/go/bin in both build and final stage ENV PATH
- rootfs/etc/profile.d/go.sh: same PATH fix; explicit /usr/local/bin
guard added; $GOPATH/bin appended last
- rootfs/root/docker/setup/05-custom.sh: add buf@latest and
goose/v3@latest installs with descriptive comments
- README.md: full rewrite — H1 title, canonical section order (Pull,
Docker, Tools table, Env vars, PATH order, Persistence, Cross-compile,
Development, License); accurate tool list matching actual image content
Dockerfile
README.md
rootfs/etc/profile.d/go.sh
rootfs/root/docker/setup/05-custom.sh
Go is now downloaded from go.dev/dl at build time (always latest stable,
never pinned). All tools are baked into /usr/local/bin so they are on
PATH out of the box. Module cache and build cache live in the volumed
GOPATH (/usr/local/share/go) so they persist across container restarts
without re-downloading.
- Dockerfile: add /usr/local/go/bin to PATH in both build and final stage
- rootfs/root/docker/setup/05-custom.sh: full Go install + tool install
- detects arch (amd64/arm64/armv6l/386) via uname -m
- fetches latest stable version from go.dev/dl?mode=json via jq
- extracts to /usr/local/go; symlinks go+gofmt to /usr/local/bin
- installs with GOBIN=/usr/local/bin (baked into image, not in volume):
gopls, goimports, gofumpt, stringer, golangci-lint, staticcheck,
govulncheck, gotestsum, dlv, air, goreleaser, wire, mockgen (uber),
ko, protoc-gen-go, protoc-gen-go-grpc
- cleans modcache and build cache after install to keep layer lean
- rootfs/etc/profile.d/go.sh: add /usr/local/go/bin prepend so
interactive shells always find the Go distribution binaries first
Volume strategy:
/usr/local/share/go → GOPATH (module cache + build cache + user bins)
Mount a named volume or bind-mount here to avoid re-downloading modules:
docker run -v go-cache:/usr/local/share/go casjaysdevdocker/go
Dockerfile
rootfs/etc/profile.d/go.sh
rootfs/root/docker/setup/05-custom.sh
Sync project with updated upstream template files while preserving all
Go-specific customizations (EXEC_CMD_BIN='', DATA_DIR='', Go env vars,
/data/go symlink, Go-named dirs, etc.).
- .env.scripts: bump version stamp to 202605292219-git
- .gitattributes: update date stamp from template
- .gitea/workflows/docker.yaml: replace bare echo with printf %q for
GITHUB_OUTPUT assignments; use local var assignments for docker org/tag
- .gitignore: expand with editor configs (VSCode/JetBrains/Vim), AI tool
configs (Claude/.cursor/Copilot), env/secrets, build artifacts,
dependency dirs, logs, test/coverage dirs from updated template
- Dockerfile: bump BUILD_DATE to 202605292219; fix PHP_FPM detection from
ls subshell to set -- glob pattern; fix systemd cleanup to use for loop
instead of rm -f $(ls | grep -v ...)
- rootfs/root/docker/setup/00-init.sh through 07-cleanup.sh: update
version/date stamps to 202605292220-git template versions
- rootfs/usr/local/bin/entrypoint.sh: update stamp; fix echo quoting to
use double quotes for CONTAINER_NAME expansion
- rootfs/usr/local/etc/docker/init.d/00-go.sh: apply template improvements:
split SIGPWR trap onto separate line with 2>/dev/null || true; expand
debugger setup to multi-line if/else; use $(<file) instead of cat for
old_pid; apply _script_hash invalidation (W14) before START_SCRIPT
generation; replace heredoc/eval approach with printf %q for safe
quoting; launch START_SCRIPT with bash not eval sh -c (W15); add null
guard on chown in __run_secure_function; use _resolved temp var pattern
for type -P resolution (remove SERVICE_PID_NUMBER); explicit
[ "$1" = "check" ] guard on __check_service; errorCode=${PIPESTATUS[0]};
fix command -v pre check; add grep -- separator; fix ps|awk|grep chain
to pure awk; remove duplicate mkdir block
- rootfs/usr/local/share/template-files/config/env/default.sample:
ENTRYPOINT_PID_FILE path /run/.entrypoint.pid → /run/init.d/entrypoint.pid
- rootfs/usr/local/share/template-files/config/env/examples/zz-entrypoint.sh:
same ENTRYPOINT_PID_FILE path fix
Dockerfile
.env.scripts
.gitattributes
.gitea/workflows/docker.yaml
.gitignore
rootfs/root/docker/setup/00-init.sh
rootfs/root/docker/setup/01-system.sh
rootfs/root/docker/setup/02-packages.sh
rootfs/root/docker/setup/03-files.sh
rootfs/root/docker/setup/04-users.sh
rootfs/root/docker/setup/05-custom.sh
rootfs/root/docker/setup/06-post.sh
rootfs/root/docker/setup/07-cleanup.sh
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/etc/docker/init.d/00-go.sh
rootfs/usr/local/share/template-files/config/env/default.sample
rootfs/usr/local/share/template-files/config/env/examples/zz-entrypoint.sh
Update the embedded entrypoint copies in rootfs/ to match the
upstream template change. Internal state files renamed to dotfiles
so they're not matched by `/run/*.pid` cleanup globs:
- /run/init.d/entrypoint.pid -> /run/.entrypoint.pid
- /run/no_exit.pid -> /run/.no_exit.pid
- /run/backup.pid -> /run/.backup.pid
- /run/__start_init_scripts.pid -> /run/.start_init_scripts.pid
Per-service PIDs in /run/init.d/ are unchanged.
Dockerfile
.env.scripts
rootfs/usr/local/bin/copy
rootfs/usr/local/bin/entrypoint.sh
rootfs/usr/local/bin/healthcheck
rootfs/usr/local/bin/symlink
rootfs/usr/local/etc/docker/functions/entrypoint.sh
rootfs/usr/local/etc/docker/init.d/00-go.sh
rootfs/usr/local/share/template-files/config/env/default.sample
rootfs/usr/local/share/template-files/config/env/examples/zz-entrypoint.sh