I'm trying to build a pre-built dev container (see here). Among others, the app has some Go dependencies specified in go.mod (link to file):

module github.com/jovandeginste/workout-tracker/v2

go 1.24.1

replace github.com/anyappinc/fitbit v0.0.3 => github.com/jovandeginste/fitbit v0.0.4-0.20250213164811-b0b3b27c3a84

require (
    github.com/a-h/templ v0.3.943
    github.com/alexedwards/scs/gormstore v0.0.0-20250927115722-fb8d6f122cfb
    github.com/alexedwards/scs/v2 v2.9.0
    github.com/anyappinc/fitbit v0.0.3
    github.com/aquasecurity/table v1.11.0
    github.com/biter777/countries v1.7.5
    github.com/cat-dealer/go-rand/v2 v2.0.0
    github.com/codingsince1985/geo-golang v1.8.5
    github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
    github.com/fsouza/slognil v0.4.3
    github.com/galeone/tcx v1.0.1-0.20230114151622-8168e1e47884
    github.com/glebarez/sqlite v1.11.0
    github.com/go-gorm/caches/v4 v4.0.5
    github.com/golang-jwt/jwt/v5 v5.3.0
    github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a
    github.com/google/go-querystring v1.1.0
    github.com/google/uuid v1.6.0
    github.com/hashicorp/go-retryablehttp v0.7.8
    github.com/invopop/ctxi18n v0.9.0
    github.com/labstack/echo-jwt/v4 v4.3.1
    github.com/labstack/echo/v4 v4.13.4
    github.com/labstack/gommon v0.4.2
    github.com/lmittmann/tint v1.1.2
    github.com/mattn/go-isatty v0.0.20
    github.com/microcosm-cc/bluemonday v1.0.27
    github.com/muktihari/fit v0.25.1
    github.com/orandin/slog-gorm v1.4.0
    github.com/paulmach/orb v0.12.0
    github.com/ringsaturn/tzf v1.0.0
    github.com/samber/slog-echo v1.17.2
    github.com/sersh88/timeago v1.0.0
    github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
    github.com/spazzymoto/echo-scs-session v1.0.0
    github.com/spf13/cast v1.10.0
    github.com/spf13/cobra v1.10.1
    github.com/spf13/viper v1.21.0
    github.com/stackus/hxgo v0.3.0
    github.com/stretchr/testify v1.11.1
    github.com/swaggo/swag v1.16.6
    github.com/tkrajina/gpxgo v1.4.0
    github.com/westphae/geomag v1.0.2
    golang.org/x/crypto v0.42.0
    golang.org/x/text v0.29.0
    gorm.io/datatypes v1.2.7
    gorm.io/driver/mysql v1.6.0
    gorm.io/driver/postgres v1.6.0
    gorm.io/gorm v1.31.0
    resty.dev/v3 v3.0.0-beta.3
)

require (
    filippo.io/edwards25519 v1.1.0 // indirect
    github.com/KyleBanks/depth v1.2.1 // indirect
    github.com/aymerick/douceur v0.2.0 // indirect
    github.com/dustin/go-humanize v1.0.1 // indirect
    github.com/fsnotify/fsnotify v1.9.0 // indirect
    github.com/glebarez/go-sqlite v1.22.0 // indirect
    github.com/go-openapi/jsonpointer v0.22.1 // indirect
    github.com/go-openapi/jsonreference v0.21.2 // indirect
    github.com/go-openapi/spec v0.22.0 // indirect
    github.com/go-openapi/swag/conv v0.25.1 // indirect
    github.com/go-openapi/swag/jsonname v0.25.1 // indirect
    github.com/go-openapi/swag/jsonutils v0.25.1 // indirect
    github.com/go-openapi/swag/loading v0.25.1 // indirect
    github.com/go-openapi/swag/stringutils v0.25.1 // indirect
    github.com/go-openapi/swag/typeutils v0.25.1 // indirect
    github.com/go-openapi/swag/yamlutils v0.25.1 // indirect
    github.com/go-sql-driver/mysql v1.9.3 // indirect
    github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
    github.com/gorilla/css v1.0.1 // indirect
    github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
    github.com/inconshreveable/mousetrap v1.1.0 // indirect
    github.com/invopop/yaml v0.3.1 // indirect
    github.com/jackc/pgpassfile v1.0.0 // indirect
    github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
    github.com/jackc/pgx/v5 v5.7.6 // indirect
    github.com/jackc/puddle/v2 v2.2.2 // indirect
    github.com/jinzhu/inflection v1.0.0 // indirect
    github.com/jinzhu/now v1.1.5 // indirect
    github.com/mattn/go-colorable v0.1.14 // indirect
    github.com/mattn/go-runewidth v0.0.17 // indirect
    github.com/mitchellh/mapstructure v1.5.0 // indirect
    github.com/ncruces/go-strftime v0.1.9 // indirect
    github.com/pelletier/go-toml/v2 v2.2.4 // indirect
    github.com/philhofer/vec v0.0.0-20140421144027-536fc796d369 // indirect
    github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
    github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
    github.com/ringsaturn/tzf-rel-lite v0.0.2025-b // indirect
    github.com/rivo/uniseg v0.4.7 // indirect
    github.com/rogpeppe/go-internal v1.12.0 // indirect
    github.com/sagikazarmark/locafero v0.12.0 // indirect
    github.com/samber/lo v1.51.0 // indirect
    github.com/spf13/afero v1.15.0 // indirect
    github.com/spf13/pflag v1.0.10 // indirect
    github.com/subosito/gotenv v1.6.0 // indirect
    github.com/tidwall/geoindex v1.7.0 // indirect
    github.com/tidwall/geojson v1.4.5 // indirect
    github.com/tidwall/rtree v1.10.0 // indirect
    github.com/twpayne/go-polyline v1.1.1 // indirect
    github.com/valyala/bytebufferpool v1.0.0 // indirect
    github.com/valyala/fasttemplate v1.2.2 // indirect
    go.mongodb.org/mongo-driver v1.17.4 // indirect
    go.opentelemetry.io/otel v1.38.0 // indirect
    go.opentelemetry.io/otel/trace v1.38.0 // indirect
    go.yaml.in/yaml/v3 v3.0.4 // indirect
    golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect
    golang.org/x/mod v0.28.0 // indirect
    golang.org/x/net v0.44.0 // indirect
    golang.org/x/oauth2 v0.31.0 // indirect
    golang.org/x/sync v0.17.0 // indirect
    golang.org/x/sys v0.36.0 // indirect
    golang.org/x/term v0.35.0 // indirect
    golang.org/x/time v0.13.0 // indirect
    golang.org/x/tools v0.37.0 // indirect
    google.golang.org/protobuf v1.36.9 // indirect
    gopkg.in/yaml.v3 v3.0.1 // indirect
    modernc.org/libc v1.66.9 // indirect
    modernc.org/mathutil v1.7.1 // indirect
    modernc.org/memory v1.11.0 // indirect
    modernc.org/sqlite v1.39.0 // indirect
)

replace github.com/tkrajina/gpxgo v1.4.0 => github.com/jovandeginste/gpxgo v1.4.1-0.20250629150855-db85929d31f6

To speed up the dev container performance, I'd like to cache them. For this, I tried the following within the dev container's Dockerfile (shortened for brevity, see here for full file):

# Copy go.mod and download module dependencies so the image has cached deps
COPY ./go.* /tmp/workout-tracker/go-build/
WORKDIR /tmp/workout-tracker/go-build/
RUN go mod download

However, when running go build inside the dev container, Go still needs to download all dependencies.

Is there any option to cache these dependencies within the Dockerfile and reuse them?

4 Replies 4

You're going to run into a problem, which is that the location of Go's cache depends on which user is logged in. (This is also something that pip and many other non-root package managers do.)

By default, everything inside a Dockerfile runs as root, if no user is specified. By default, a GitHub codespace does not run as root.

So one way to solve this would be to run as the same user. This appears to be a user with UID 1000, so I tried using UID 1000 to run the Go install.

I tested this by adding the following code to your Dockerfile.

# Copy go.mod and download module dependencies so the image has cached deps
COPY ./go.* /tmp/workout-tracker/go-build/
WORKDIR /tmp/workout-tracker/go-build/
USER 1000
RUN go mod download

I tested this in a GitHub codespace, and based on how long it takes, it can read the downloads from the cache:

$ time go mod download

real    0m0.096s
user    0m0.060s
sys     0m0.071s

(Compared to ~13s before.)

Full branch here. This contains other changes as well that I needed to get it to build on my repo. I think the USER 1000 change is the only thing you need.

I appreciate your help 🙂 when applying your suggested changes to the Dockerfile, creating the dev container and running make build-serverI still see the following output:

go: downloading github.com/natefinch/atomic v1.0.1
go: downloading github.com/cli/browser v1.3.0
go: downloading github.com/cenkalti/backoff/v4 v4.3.0
go: downloading github.com/fsnotify/fsnotify v1.7.0
go: downloading golang.org/x/sync v0.16.0
go: downloading github.com/a-h/parse v0.0.0-20250122154542-74294addb73e
go: downloading golang.org/x/mod v0.26.0
go: downloading github.com/andybalholm/brotli v1.1.0
go: downloading golang.org/x/net v0.42.0
go: downloading github.com/mattn/go-colorable v0.1.13
go: downloading golang.org/x/tools v0.35.0
go: downloading golang.org/x/sys v0.34.0

That still looks to me as if Go would download the dependencies, no? 🤔

I made a few changes to the Dockerfile, and in my case, it built from cache and worked correctly.

FROM golang:latest AS builder-backend
ARG BUILD_TIME
ARG GIT_COMMIT
ARG GIT_REF
ARG GIT_REF_NAME
ARG GIT_REF_TYPE

WORKDIR /app
COPY go.mod ./
RUN go mod download
RUN apt update && apt install make
COPY Makefile ./
COPY assets ./assets
COPY cmd ./cmd
COPY pkg ./pkg
COPY vendor ./vendor
COPY views ./views
COPY translations ./translations

ENV CGO_ENABLED=0
ENTRYPOINT ["make", "dev-backend"]

@CyberCr0w: I don't get it, where's the magic trick?

Your Reply

By clicking “Post Your Reply”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.