Skip to content

docs: use bind mounts in Go Dockerfile examples #22388

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Juneezee
Copy link
Contributor

@Juneezee Juneezee commented Apr 8, 2025

Description

I remembered there used to be a page (https://docs.docker.com/build/guide/mounts/) that demonstrated how to use both bind mounts and cache mounts together in a Dockerfile for a Go application. However, that page was removed in #20715, and the new page (https://docs.docker.com/build/cache/optimize/) now separates the examples for bind mounts and cache mounts.

RUN --mount=type=cache,target=/go/pkg/mod/ \
--mount=type=bind,source=go.sum,target=go.sum \
--mount=type=bind,source=go.mod,target=go.mod \
go mod download -x
- COPY . .
FROM base AS build-client
RUN --mount=type=cache,target=/go/pkg/mod/ \
+ --mount=type=bind,target=. \
go build -o /bin/client ./cmd/client

It would be great if the remaining Go Dockerfile examples could show how to use both bind mounts and cache mounts together specifically for go.mod and go.sum. This combination was really helpful for improving build performance and clarity when using Docker for Go development. (See #22388 (comment) for updtae)

Related issues or tickets

Reviews

  • Technical review
  • Editorial review
  • Product review

@github-actions github-actions bot added area/build Relates to Dockerfiles or docker build command area/release Relates to CI or deployment labels Apr 8, 2025
Copy link

netlify bot commented Apr 8, 2025

Deploy Preview for docsdocker ready!

Name Link
🔨 Latest commit cf728b4
🔍 Latest deploy log https://app.netlify.com/sites/docsdocker/deploys/681192b6fcf80700081bba9e
😎 Deploy Preview https://deploy-preview-22388--docsdocker.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@github-actions github-actions bot added the area/extensions Relates to Docker Extensions label Apr 8, 2025
@Juneezee Juneezee changed the title docs(ci/github-actions): use bind mounts in Dockerfile example docs: use bind mounts in Go Dockerfile examples Apr 8, 2025
@Juneezee Juneezee marked this pull request as ready for review April 8, 2025 16:56
@Juneezee
Copy link
Contributor Author

Juneezee commented Apr 11, 2025

UPDATE: I have removed the go mod download step in commit ad5ded2.

go build will automatically download module dependencies. In many cases, that is a much smaller set of modules than what is downloaded by go mod download. I found a great explanation on StackOverflow here: https://stackoverflow.com/a/68172023/7902371

Using the https://github.com/github/github-mcp-server Go application as an example below.

Size of GOMODCACHE with go mod download:

~/Desktop/github/github-mcp-server docker ❯ go clean -i -r -cache -modcache

~/Desktop/github/github-mcp-server docker ❯ go mod download

~/Desktop/github/github-mcp-server docker ❯ du -sh ~/go/pkg/mod
186M	/home/jun/go/pkg/mod

Size of GOMODCACHE with go build:

~/Desktop/github/github-mcp-server docker !1 ❯ go clean -i -r -cache -modcache

~/Desktop/github/github-mcp-server docker !1 ❯ CGO_ENABLED=0 go build -ldflags="-s -w" cmd/github-mcp-server/main.go
go: downloading github.com/spf13/viper v1.20.1
go: downloading github.com/mark3labs/mcp-go v0.18.0
go: downloading github.com/google/go-github/v69 v69.2.0
go: downloading github.com/sirupsen/logrus v1.9.3
go: downloading github.com/spf13/cobra v1.9.1
go: downloading golang.org/x/sys v0.31.0
go: downloading github.com/spf13/afero v1.14.0
go: downloading github.com/fsnotify/fsnotify v1.8.0
go: downloading github.com/spf13/cast v1.7.1
go: downloading github.com/go-viper/mapstructure/v2 v2.2.1
go: downloading github.com/subosito/gotenv v1.6.0
go: downloading gopkg.in/yaml.v3 v3.0.1
go: downloading github.com/spf13/pflag v1.0.6
go: downloading github.com/pelletier/go-toml/v2 v2.2.3
go: downloading github.com/sagikazarmark/locafero v0.9.0
go: downloading golang.org/x/text v0.23.0
go: downloading github.com/google/uuid v1.6.0
go: downloading github.com/yosida95/uritemplate/v3 v3.0.2
go: downloading github.com/sourcegraph/conc v0.3.0
go: downloading github.com/google/go-querystring v1.1.0

~/Desktop/github/github-mcp-server docker !1 ?1 ❯ du -sh ~/go/pkg/mod
80M	/home/jun/go/pkg/mod

Running go build results in a smaller GOMODCACHE (~80 MB) compared to go mod download (~186 MB).

`go build` will automatically download module dependencies. In many
cases, that is a much smaller set of modules than what is downloaded by
`go mod download`.

Using the https://github.com/github/github-mcp-server Go application as
an example below.

Size of GOMODCACHE with `go mod download`:

	$ go clean -i -r -cache -modcache
	$ go mod download
	$ du -sh ~/go/pkg/mod
	186M	/home/jun/go/pkg/mod

Size of GOMODCACHE with `go build`:

	$ go clean -i -r -cache -modcache
	$ CGO_ENABLED=0 go build -ldflags="-s -w" cmd/github-mcp-server/main.go
	go: downloading github.com/spf13/viper v1.20.1
	go: downloading github.com/mark3labs/mcp-go v0.18.0
	go: downloading github.com/google/go-github/v69 v69.2.0
	go: downloading github.com/sirupsen/logrus v1.9.3
	go: downloading github.com/spf13/cobra v1.9.1
	go: downloading golang.org/x/sys v0.31.0
	go: downloading github.com/spf13/afero v1.14.0
	go: downloading github.com/fsnotify/fsnotify v1.8.0
	go: downloading github.com/spf13/cast v1.7.1
	go: downloading github.com/go-viper/mapstructure/v2 v2.2.1
	go: downloading github.com/subosito/gotenv v1.6.0
	go: downloading gopkg.in/yaml.v3 v3.0.1
	go: downloading github.com/spf13/pflag v1.0.6
	go: downloading github.com/pelletier/go-toml/v2 v2.2.3
	go: downloading github.com/sagikazarmark/locafero v0.9.0
	go: downloading golang.org/x/text v0.23.0
	go: downloading github.com/google/uuid v1.6.0
	go: downloading github.com/yosida95/uritemplate/v3 v3.0.2
	go: downloading github.com/sourcegraph/conc v0.3.0
	go: downloading github.com/google/go-querystring v1.1.0
	$ du -sh ~/go/pkg/mod
	80M	/home/jun/go/pkg/mod

Reference: https://stackoverflow.com/a/68172023/7902371
Signed-off-by: Eng Zer Jun <[email protected]>
@Juneezee
Copy link
Contributor Author

Hi @aevesdocker @crazy-max, when you have a moment, could you take a quick look at this PR and let me know if it would be a worthwhile improvement to the documentation?

Thanks 😊

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like I wrote some comments last week, but didn't submit them 🙈

@@ -197,13 +197,11 @@ Example Dockerfile in `build/package/Dockerfile`
FROM golang:1.21.1-alpine as base-build

WORKDIR /build
RUN go env -w GOMODCACHE=/root/.cache/go-build
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if this one would still be useful; the default would be ~/.cache/go-build, but as the mounts are hard-coded to a location, it could be useful to explicitly configure go to use a location (for the mounts).

Possibly it could be a custom path so that the cache-directory can be set up to a predictable location for situations where you want to run the build as a user (USER) that's not root 🤔


COPY go.mod go.sum ./
RUN --mount=type=cache,target=/root/.cache/go-build go mod download
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps @crazy-max or @tonistiigi have ideas on this part; yes, it looks like go mod download may download more; but it could depend on the situation; i.e., if all modules are downloaded, then possibly the cache could be re-used for multiple stages (instead of each stage downloading "just" the parts it needs).

COPY go.mod go.sum ./
RUN --mount=type=cache,target=/root/.cache/go-build go mod download

COPY ./src ./
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also double-checking with @crazy-max and @tonistiigi on this one; i.e., if copying the source was intentional here (restoring cache or otherwise?).

These are always tricky as there's no "single" rule, some bits may depend on your situation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/build Relates to Dockerfiles or docker build command area/extensions Relates to Docker Extensions area/release Relates to CI or deployment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants