Skip to content

Optimize Docker build with bind mounts #208

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 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.github
.vscode
script
third-party
.dockerignore
.gitignore
**/*.yml
**/*.yaml
**/*.md
**/*_test.go
LICENSE
23 changes: 11 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
FROM golang:1.23.7-alpine AS build
ARG VERSION="dev"

FROM golang:1.23.7 AS build
# allow this step access to build arg
ARG VERSION
# Set the working directory
WORKDIR /build

RUN go env -w GOMODCACHE=/root/.cache/go-build
# Install git
RUN --mount=type=cache,target=/var/cache/apk \
apk add git

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

COPY . ./
# Build the server
RUN --mount=type=cache,target=/root/.cache/go-build CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=${VERSION} -X main.commit=$(git rev-parse HEAD) -X main.date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-o github-mcp-server cmd/github-mcp-server/main.go
# go build automatically download required module dependencies to /go/pkg/mod
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
--mount=type=bind,target=. \
CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=${VERSION} -X main.commit=$(git rev-parse HEAD) -X main.date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
-o /bin/github-mcp-server cmd/github-mcp-server/main.go
Comment on lines -11 to +17
Copy link
Contributor Author

@Juneezee Juneezee Apr 11, 2025

Choose a reason for hiding this comment

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

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). I found a great explanation on StackOverflow here: https://stackoverflow.com/a/68172023/7902371

The go build step took 19.1 seconds, which is 2 seconds faster than go mod download (4.1 seconds) + go build (17.1 seconds).

[+] Building 37.1s (13/13) FINISHED                                                                                                                            docker:default
 => [internal] load build definition from Dockerfile                                                                                                                     0.0s
 => => transferring dockerfile: 838B                                                                                                                                     0.0s
 => [internal] load metadata for gcr.io/distroless/base-debian12:latest                                                                                                  2.1s
 => [internal] load metadata for docker.io/library/golang:1.23.7-alpine                                                                                                  2.6s
 => [internal] load .dockerignore                                                                                                                                        0.0s
 => => transferring context: 148B                                                                                                                                        0.0s
 => [build 1/4] FROM docker.io/library/golang:1.23.7-alpine@sha256:e438c135c348bd7677fde18d1576c2f57f265d5dfa1a6b26fca975d4aa40b3bb                                     13.6s
 => => resolve docker.io/library/golang:1.23.7-alpine@sha256:e438c135c348bd7677fde18d1576c2f57f265d5dfa1a6b26fca975d4aa40b3bb                                            0.0s
 => => sha256:e291f2c3258d0d58c0a39814b55a8dfa54665485847a55af621f3370f12deccc 2.08kB / 2.08kB                                                                           0.0s
 => => sha256:e438c135c348bd7677fde18d1576c2f57f265d5dfa1a6b26fca975d4aa40b3bb 10.29kB / 10.29kB                                                                         0.0s
 => => sha256:44b3a1c80b6c3a3083df7893a996ecea1e45d4f4fd5682951b6a13569bdb64e3 1.92kB / 1.92kB                                                                           0.0s
 => => sha256:f18232174bc91741fdf3da96d85011092101a032a93a388b79e99e69c2d5c870 3.64MB / 3.64MB                                                                           3.2s
 => => sha256:4a6853717b24861f4773c7c44c0700bc67775e6432b117e9f6cb5d80c1259c40 294.90kB / 294.90kB                                                                       3.1s
 => => sha256:6ca661eb024f09b95cfdf77781effc26400df52d97566fbd0fd4d45a67c3a3e6 74.06MB / 74.06MB                                                                         4.8s
 => => sha256:d509c56e130243a89eef696356c0605801f3be8cf6ae8bb68ab53854704a178e 126B / 126B                                                                               3.5s
 => => extracting sha256:f18232174bc91741fdf3da96d85011092101a032a93a388b79e99e69c2d5c870                                                                                0.3s
 => => sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 32B / 32B                                                                                 3.5s
 => => extracting sha256:4a6853717b24861f4773c7c44c0700bc67775e6432b117e9f6cb5d80c1259c40                                                                                0.1s
 => => extracting sha256:6ca661eb024f09b95cfdf77781effc26400df52d97566fbd0fd4d45a67c3a3e6                                                                                8.4s
 => => extracting sha256:d509c56e130243a89eef696356c0605801f3be8cf6ae8bb68ab53854704a178e                                                                                0.0s
 => => extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1                                                                                0.0s
 => [internal] load build context                                                                                                                                        0.1s
 => => transferring context: 820.15kB                                                                                                                                    0.0s
 => [stage-1 1/3] FROM gcr.io/distroless/base-debian12:latest@sha256:27769871031f67460f1545a52dfacead6d18a9f197db77110cfc649ca2a91f44                                    3.3s
 => => resolve gcr.io/distroless/base-debian12:latest@sha256:27769871031f67460f1545a52dfacead6d18a9f197db77110cfc649ca2a91f44                                            0.0s
 => => sha256:dd32b4a5eed124ce1e86eab9959b67c9d6f114a1578a07cb679b2e3955d80b68 1.71kB / 1.71kB                                                                           0.0s
 => => sha256:3d78e577de35c8bf231e34862a13cde36cd7b253b6a7af2158035251d2dc48c0 104.23kB / 104.23kB                                                                       0.8s
 => => sha256:bfb59b82a9b65e47d485e53b3e815bca3b3e21a095bd0cb88ced9ac0b48062bf 13.36kB / 13.36kB                                                                         0.8s
 => => sha256:4eff9a62d888790350b2481ff4a4f38f9c94b3674d26b2f2c85ca39cdef43fd9 547.59kB / 547.59kB                                                                       0.9s
 => => sha256:d65201b3fe8eb56abcec05aec99acec815e40b10b63b854ce02bec4575f64526 2.27kB / 2.27kB                                                                           0.0s
 => => sha256:27769871031f67460f1545a52dfacead6d18a9f197db77110cfc649ca2a91f44 1.51kB / 1.51kB                                                                           0.0s
 => => extracting sha256:3d78e577de35c8bf231e34862a13cde36cd7b253b6a7af2158035251d2dc48c0                                                                                0.0s
 => => sha256:a62778643d563b511190663ef9a77c30d46d282facfdce4f3a7aecc03423c1f3 67B / 67B                                                                                 1.2s
 => => sha256:7c12895b777bcaa8ccae0605b4de635b68fc32d60fa08f421dc3818bf55ee212 188B / 188B                                                                               1.2s
 => => extracting sha256:bfb59b82a9b65e47d485e53b3e815bca3b3e21a095bd0cb88ced9ac0b48062bf                                                                                0.0s
 => => extracting sha256:4eff9a62d888790350b2481ff4a4f38f9c94b3674d26b2f2c85ca39cdef43fd9                                                                                0.3s
 => => sha256:3214acf345c0cc6bbdb56b698a41ccdefc624a09d6beb0d38b5de0b2303ecaf4 123B / 123B                                                                               1.4s
 => => extracting sha256:a62778643d563b511190663ef9a77c30d46d282facfdce4f3a7aecc03423c1f3                                                                                0.0s
 => => extracting sha256:7c12895b777bcaa8ccae0605b4de635b68fc32d60fa08f421dc3818bf55ee212                                                                                0.0s
 => => sha256:5664b15f108bf9436ce3312090a767300800edbbfd4511aa1a6d64357024d5dd 168B / 168B                                                                               1.6s
 => => sha256:0bab15eea81d0fe6ab56ebf5fba14e02c4c1775a7f7436fbddd3505add4e18fa 93B / 93B                                                                                 1.6s
 => => extracting sha256:3214acf345c0cc6bbdb56b698a41ccdefc624a09d6beb0d38b5de0b2303ecaf4                                                                                0.0s
 => => sha256:4aa0ea1413d37a58615488592a0b827ea4b2e48fa5a77cf707d0e35f025e613f 385B / 385B                                                                               1.8s
 => => extracting sha256:5664b15f108bf9436ce3312090a767300800edbbfd4511aa1a6d64357024d5dd                                                                                0.0s
 => => extracting sha256:0bab15eea81d0fe6ab56ebf5fba14e02c4c1775a7f7436fbddd3505add4e18fa                                                                                0.0s
 => => sha256:9aee425378d2c16cd44177dc54a274b312897f5860a8e78fdfda555a0d79dd71 130.50kB / 130.50kB                                                                       2.4s
 => => sha256:da7816fa955ea24533c388143c78804c28682eef99b4ee3723b548c70148bba6 321B / 321B                                                                               2.1s
 => => extracting sha256:4aa0ea1413d37a58615488592a0b827ea4b2e48fa5a77cf707d0e35f025e613f                                                                                0.0s
 => => sha256:d00c3209d92970dad10c006c4d7120e5fd276349ce6e57dbad95a3a3f05411fc 5.83MB / 5.83MB                                                                           2.6s
 => => extracting sha256:da7816fa955ea24533c388143c78804c28682eef99b4ee3723b548c70148bba6                                                                                0.0s
 => => sha256:221438ca359c95b5f7ecb07541b094ae1e5ce63442a404e8a38b6d84b6a7bcb4 2.83MB / 2.83MB                                                                           3.0s
 => => extracting sha256:9aee425378d2c16cd44177dc54a274b312897f5860a8e78fdfda555a0d79dd71                                                                                0.0s
 => => extracting sha256:d00c3209d92970dad10c006c4d7120e5fd276349ce6e57dbad95a3a3f05411fc                                                                                0.3s
 => => extracting sha256:221438ca359c95b5f7ecb07541b094ae1e5ce63442a404e8a38b6d84b6a7bcb4                                                                                0.2s
 => [stage-1 2/3] WORKDIR /server                                                                                                                                        0.0s
 => [build 2/4] WORKDIR /build                                                                                                                                           0.0s
 => [build 3/4] RUN --mount=type=cache,target=/var/cache/apk     apk add git                                                                                             1.6s
 => [build 4/4] RUN --mount=type=cache,target=/go/pkg/mod     --mount=type=cache,target=/root/.cache/go-build     --mount=type=bind,target=.     CGO_ENABLED=0 go buil  19.1s
 => [stage-1 3/3] COPY --from=build /bin/github-mcp-server .                                                                                                             0.0s
 => exporting to image                                                                                                                                                   0.1s
 => => exporting layers                                                                                                                                                  0.1s
 => => writing image sha256:b9ddd66d7962298abd8380c7f2eee5cc87b9f7b4919068da8b2641a42a0ede68                                                                             0.0s


# Make a stage to run the app
FROM gcr.io/distroless/base-debian12
# Set the working directory
WORKDIR /server
# Copy the binary from the build stage
COPY --from=build /build/github-mcp-server .
COPY --from=build /bin/github-mcp-server .
# Command to run the server
CMD ["./github-mcp-server", "stdio"]