Ubuntu-based Go development image published to Docker Hub, with automated multi-version builds.
This repository builds and publishes one or more Go images on a schedule using GitHub Actions.
- Registry: Docker Hub - esacteksab/go
- Runtime base: Ubuntu 24.04 (digest pinned)
- Build schedule: Every Friday at 9:00 AM Central Time (US/Chicago)
Local development is standardized through a shared dev-container instead of per-repo bootstrap files.
- Dev container config: .devcontainer/devcontainer.json
- Shared environment image:
docker.io/esacteksab/dev-container:2026-03-13-20-04@sha256:ff0997d094d0ffadfc73a278ac6b2316a15f0a6025fbfc067c2348929071ded3
- Open this repository in VS Code.
- Run the command:
Dev Containers: Reopen in Container. - Wait for the container build to complete.
- Start working with the preinstalled toolchain inside the container.
The container post-create step installs pre-commit hooks automatically.
The following local bootstrap files were intentionally removed in favor of the shared dev-container:
package.jsonpnpm-lock.yamlrequirements.txt.mise.toml
Project policy/config files such as .pre-commit-config.yaml, .prettierrc, .prettierignore, and GitHub workflow files remain in this repository.
The workflow resolves the build matrix in one of two ways:
- If repository variable
GO_VERSIONis set, only that exact version is built. - If
GO_VERSIONis not set, versions are queried fromhttps://go.dev/dl/?mode=json, then reduced to the latest stable patch release for each stable Go minor line.
For each Go version in the matrix, the workflow:
- Resolves the digest for
golang:<version>-bookworm. - Passes
GO_VERSIONandGO_IMAGE_DIGESTas build args. - Builds an Ubuntu runtime image and copies
/usr/local/gofrom the digest-pinned Go source stage.
This keeps builds reproducible while still supporting multiple Go versions.
For each built version <go-version>:
esacteksab/go:<go-version>esacteksab/go:<go-version>-YYYY-MM-DD
Additionally:
esacteksab/go:latestis applied to the highest version in the matrix for that run.
CGO_ENABLED=0GOPATH=/goPATHincludes/usr/local/go/binand/go/binGO_VERSIONis set in the final image environment- OCI label
org.opencontainers.image.versionis set to the built Go version
docker build \
--build-arg GO_VERSION=1.25.8 \
--build-arg GO_IMAGE_DIGEST=sha256:<digest-for-golang-1.25.8-bookworm> \
-t esacteksab/go:1.25.8 .Symptom in workflow logs:
Failed to resolve digest for golang:<version>-bookworm
Common causes:
- Temporary Docker Hub or network outage on GitHub-hosted runners.
- Invalid or unavailable Go version in the matrix.
What to do:
- Re-run the failed workflow once to rule out transient network errors.
- Verify the version exists:
docker buildx imagetools inspect golang:<version>-bookworm. - If using repository variable
GO_VERSION, confirm it matches a real upstream tag (example:1.25.8).
Symptom in workflow logs:
- Matrix resolves to one value, then digest or build steps fail.
What to do:
- Check repository variable
GO_VERSIONin GitHub Actions settings. - Use semantic Go version format only (for example
1.25.8, notgo1.25.8). - Clear the variable to return to API-driven multi-version builds.
Symptom in workflow logs:
- Login step fails, or push returns
denied/unauthorized.
What to do:
- Confirm
DOCKERHUB_TOKENsecret exists and is valid. - Confirm Docker Hub username in the workflow matches the account that owns the token.
- Recreate the token in Docker Hub and update the GitHub secret if token scope or expiration changed.
Symptom in editor diagnostics:
Context access might be invalid: GO_VERSION
What it means:
- This is often a static validation warning when the repository variable is not defined.
- Workflow runtime still works because the expression falls back to an empty string.
What to do:
- Define repository variable
GO_VERSIONif you want override mode. - Leave it undefined if you want API-driven multi-version mode.
GitHub release notes are generated from .github/release.yml, and PR labels determine which section each change appears in.
Apply labels consistently to ensure entries land in the expected category.
type: breakingtype: deprecationtype: regressiontype: revert
type: releasetype: feattype: fixtype: perftype: enhancementenhancementbug
type: citype: buildtype: refactor
type: docstype: testtype: styledocumentation
github_actionsjavascriptnpmpython
dependenciesdockergo
choretype: choretype: task
questioninvalidduplicatewontfix
ignore-changelog
Conventional commit prefixes (for example chore: or feat:) do not automatically place PRs into a section unless matching labels are applied.
Copy and paste into PR descriptions:
## Release Notes Checklist
- [ ] I applied at least one release label that matches `.github/release.yml`.
- [ ] If this PR should be excluded from release notes, I applied `ignore-changelog`.
- [ ] If this is a breaking change, I applied `type: breaking` and documented impact/migration notes.MIT