From 28f2167e82c8231bc169e7734e3afcfdba3fa4a5 Mon Sep 17 00:00:00 2001 From: casjay Date: Sat, 30 May 2026 02:33:40 -0400 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Install=20Go=20latest=20+=20full=20?= =?UTF-8?q?toolchain=20at=20image=20build=20time=20=E2=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- Dockerfile | 4 +- rootfs/etc/profile.d/go.sh | 8 ++ rootfs/root/docker/setup/05-custom.sh | 113 ++++++++++++++++++++++++-- 3 files changed, 117 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1863ac1..ad70f7d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -58,7 +58,7 @@ ARG PACK_LIST="git make bash tini ca-certificates openssh-client curl wget tar t ENV ENV=~/.profile ENV SHELL="/bin/sh" -ENV PATH="/usr/local/share/go/bin:${PATH}" +ENV PATH="/usr/local/go/bin:/usr/local/share/go/bin:${PATH}" ENV TZ="${TIMEZONE}" ENV TIMEZONE="${TZ}" ENV LANG="${LANGUAGE}" @@ -234,7 +234,7 @@ LABEL com.github.containers.toolbox="false" ENV ENV=~/.bashrc ENV USER="${USER}" -ENV PATH="/usr/local/share/go/bin:${PATH}" +ENV PATH="/usr/local/go/bin:/usr/local/share/go/bin:${PATH}" ENV TZ="${TIMEZONE}" ENV SHELL="/bin/bash" ENV TIMEZONE="${TZ}" diff --git a/rootfs/etc/profile.d/go.sh b/rootfs/etc/profile.d/go.sh index 061ffdb..1f962e1 100644 --- a/rootfs/etc/profile.d/go.sh +++ b/rootfs/etc/profile.d/go.sh @@ -5,12 +5,20 @@ # /data/go are symlinks to that location, so any of them can be used # interchangeably and the data persists across container rebuilds when # the volume is named. +# +# The Go distribution itself lives at /usr/local/go (baked into the image, +# not volumed). Tools installed at build time land in /usr/local/bin. export GOPATH="${GOPATH:-/usr/local/share/go}" export GOCACHE="${GOCACHE:-${GOPATH}/cache}" export CGO_ENABLED="${CGO_ENABLED:-0}" export GOTOOLCHAIN="${GOTOOLCHAIN:-auto}" +case ":${PATH}:" in + *":/usr/local/go/bin:"*) ;; + *) export PATH="/usr/local/go/bin:${PATH}" ;; +esac + case ":${PATH}:" in *":${GOPATH}/bin:"*) ;; *) export PATH="${GOPATH}/bin:${PATH}" ;; diff --git a/rootfs/root/docker/setup/05-custom.sh b/rootfs/root/docker/setup/05-custom.sh index f18f4aa..d9474c2 100755 --- a/rootfs/root/docker/setup/05-custom.sh +++ b/rootfs/root/docker/setup/05-custom.sh @@ -8,11 +8,11 @@ # @@Copyright : Copyright 2026 CasjaysDev # @@Created : Fri May 29 10:20:10 PM EDT 2026 # @@File : 05-custom.sh -# @@Description : script to run custom -# @@Changelog : newScript -# @@TODO : Refactor code +# @@Description : Install Go latest and Go tooling +# @@Changelog : Add Go install and toolchain setup +# @@TODO : N/A # @@Other : N/A -# @@Resource : N/A +# @@Resource : https://go.dev/dl/ # @@Terminal App : yes # @@sudo/root : yes # @@Template : templates/dockerfiles/init_scripts/05-custom.sh @@ -20,18 +20,120 @@ # shellcheck disable=SC1001,SC1003,SC2001,SC2003,SC2016,SC2031,SC2090,SC2115,SC2120,SC2155,SC2199,SC2229,SC2317,SC2329 # - - - - - - - - - - - - - - - - - - - - - - - - - # Set bash options -set -o pipefail +set -eo pipefail [ "$DEBUGGER" = "on" ] && echo "Enabling debugging" && set -x$DEBUGGER_OPTIONS # - - - - - - - - - - - - - - - - - - - - - - - - - # Set env variables exitCode=0 +# Installation root for the Go distribution (not GOPATH) +GOINSTALL_DIR="/usr/local/go" +# GOPATH: module cache, pkg index, user-installed binaries (declared VOLUME) +GOPATH_DIR="/usr/local/share/go" +# Baked-in tool binaries land here so they are on the default PATH +GOBIN_DIR="/usr/local/bin" +# Throwaway build cache used only during this image build layer +GOCACHE_BUILD="/tmp/go-build-cache" + # - - - - - - - - - - - - - - - - - - - - - - - - - # Predefined actions # - - - - - - - - - - - - - - - - - - - - - - - - - # Main script +# Map uname -m to the Go download architecture suffix +case "$(uname -m)" in + x86_64) _GOARCH="amd64" ;; + aarch64) _GOARCH="arm64" ;; + armv7l) _GOARCH="armv6l" ;; + i386|i686) _GOARCH="386" ;; + *) + echo "Unsupported architecture: $(uname -m)" >&2 + exit 1 + ;; +esac + +# Fetch the latest stable Go version string from the official download API +_GO_VERSION="$(curl -fsSL 'https://go.dev/dl/?mode=json' | jq -r '.[0].version')" +echo "Installing ${_GO_VERSION} (linux/${_GOARCH})" + +# Remove any prior installation and extract the new tarball +rm -rf "${GOINSTALL_DIR}" +curl -fsSL "https://dl.google.com/go/${_GO_VERSION}.linux-${_GOARCH}.tar.gz" | tar -C /usr/local -xz + +# Symlink the core binaries so they are found without /usr/local/go/bin in PATH +ln -sf "${GOINSTALL_DIR}/bin/go" "${GOBIN_DIR}/go" +ln -sf "${GOINSTALL_DIR}/bin/gofmt" "${GOBIN_DIR}/gofmt" + +# Wire up the environment for the tool installation that follows +export GOPATH="${GOPATH_DIR}" +export GOBIN="${GOBIN_DIR}" +export PATH="${GOINSTALL_DIR}/bin:${PATH}" +export GOCACHE="${GOCACHE_BUILD}" +export CGO_ENABLED="0" +export GOTOOLCHAIN="auto" + +# Ensure the GOPATH directory tree exists +mkdir -p "${GOPATH_DIR}/pkg/mod" "${GOPATH_DIR}/cache" "${GOPATH_DIR}/bin" + +echo "Installing Go tooling (GOBIN=${GOBIN_DIR})" + +# Language server - editor integration (VSCode, Neovim, etc.) +go install golang.org/x/tools/gopls@latest + +# Import organiser - superset of gofmt that also manages import groups +go install golang.org/x/tools/cmd/goimports@latest + +# Stricter formatter used by many golangci-lint configs +go install mvdan.cc/gofumpt@latest + +# Generate String() methods for iota-based types +go install golang.org/x/tools/cmd/stringer@latest + +# Meta-linter: runs golint, errcheck, ineffassign, gocyclo, and many more +go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + +# Standalone advanced static analyser +go install honnef.co/go/tools/cmd/staticcheck@latest + +# Vulnerability scanner against the Go vulnerability database +go install golang.org/x/vuln/cmd/govulncheck@latest + +# Structured test runner with better output and JUnit/JSON export +go install gotest.tools/gotestsum@latest + +# Source-level debugger +go install github.com/go-delve/delve/cmd/dlv@latest + +# Live-reload dev server for iterative development +go install github.com/air-verse/air@latest + +# Release automation: cross-compile, sign, publish, container images +go install github.com/goreleaser/goreleaser/v2@latest + +# Compile-time dependency injection code generator +go install github.com/google/wire/cmd/wire@latest + +# Mock generator for interfaces (uber fork of golang/mock) +go install go.uber.org/mock/mockgen@latest + +# Build Go container images without a Dockerfile +go install github.com/google/ko@latest + +# protobuf Go code generator +go install google.golang.org/protobuf/cmd/protoc-gen-go@latest + +# gRPC Go code generator +go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest + +echo "Go tooling installed" + +# Strip the module download cache and ephemeral build cache from this layer. +# The installed binaries in GOBIN_DIR are preserved in the image. +go clean -modcache +go clean -cache +rm -rf "${GOCACHE_BUILD}" + # - - - - - - - - - - - - - - - - - - - - - - - - - # Set the exit code exitCode=$? @@ -40,4 +142,3 @@ exit $exitCode # - - - - - - - - - - - - - - - - - - - - - - - - - # ex: ts=2 sw=2 et filetype=sh # - - - - - - - - - - - - - - - - - - - - - - - - - -