-
Notifications
You must be signed in to change notification settings - Fork 224
Expand file tree
/
Copy pathDockerfile
More file actions
170 lines (143 loc) · 5.24 KB
/
Dockerfile
File metadata and controls
170 lines (143 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#syntax=docker/dockerfile:1
ARG GO_VERSION=1.25.5
ARG DOCS_FORMATS="md,yaml"
FROM --platform=${BUILDPLATFORM} golangci/golangci-lint:v2.8.0-alpine AS lint-base
FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION}-alpine AS base
RUN apk add --no-cache git rsync
WORKDIR /app
# Docs generation and validation targets
FROM base AS docs-gen
WORKDIR /src
RUN --mount=target=. \
--mount=target=/root/.cache,type=cache \
go build -mod=vendor -o /out/docsgen ./docs/generator/generate.go
FROM base AS docs-build
COPY --from=docs-gen /out/docsgen /usr/bin
ENV DOCKER_CLI_PLUGIN_ORIGINAL_CLI_COMMAND="mcp"
ARG DOCS_FORMATS
RUN --mount=target=/context \
--mount=target=.,type=tmpfs <<EOT
set -e
rsync -a /context/. .
docsgen --formats "$DOCS_FORMATS" --source "docs/generator/reference"
mkdir /out
cp -r docs/generator/reference/* /out/
EOT
FROM scratch AS docs-update
COPY --from=docs-build /out /
FROM docs-build AS docs-validate
RUN --mount=target=/context \
--mount=target=.,type=tmpfs <<EOT
set -e
rsync -a /context/. .
git add -A
rm -rf docs/generator/reference/*
cp -rf /out/* ./docs/generator/reference/
if [ -n "$(git status --porcelain -- docs/generator/reference)" ]; then
echo >&2 'ERROR: Docs result differs. Rebase on main branch and rerun "make docs"'
git status --porcelain -- docs/generator/reference
exit 1
fi
EOT
FROM base AS lint
COPY --from=lint-base /usr/bin/golangci-lint /usr/bin/golangci-lint
ARG TARGETOS
ARG TARGETARCH
RUN --mount=target=. \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/root/.cache/golangci-lint <<EOD
set -e
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} golangci-lint --timeout 30m0s run ./...
EOD
FROM base AS test
ARG TARGETOS
ARG TARGETARCH
RUN --mount=target=. \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build <<EOD
set -e
CGO_ENABLED=0 go test -short --count=1 -v ./...
EOD
FROM base AS do-format
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go install golang.org/x/tools/cmd/goimports@latest \
&& go install mvdan.cc/gofumpt@latest
COPY . .
RUN rm -rf vendor
RUN goimports -local github.com/docker/mcp-gateway -w .
RUN gofumpt -w .
FROM scratch AS format
COPY --from=do-format /app .
FROM base AS build-docker-mcp
ARG TARGETOS
ARG TARGETARCH
ARG GO_LDFLAGS
ARG DOCKER_MCP_PLUGIN_BINARY
RUN --mount=target=.\
--mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -trimpath -ldflags "-s -w ${GO_LDFLAGS}" -o /out/${DOCKER_MCP_PLUGIN_BINARY} ./cmd/docker-mcp
FROM scratch AS binary-docker-mcp-unix
ARG DOCKER_MCP_PLUGIN_BINARY
COPY --link --from=build-docker-mcp /out/${DOCKER_MCP_PLUGIN_BINARY} /
FROM binary-docker-mcp-unix AS binary-docker-mcp-darwin
FROM binary-docker-mcp-unix AS binary-docker-mcp-linux
FROM scratch AS binary-docker-mcp-windows
ARG DOCKER_MCP_PLUGIN_BINARY
COPY --link --from=build-docker-mcp /out/${DOCKER_MCP_PLUGIN_BINARY} /${DOCKER_MCP_PLUGIN_BINARY}.exe
FROM binary-docker-mcp-$TARGETOS AS binary-docker-mcp
FROM --platform=$BUILDPLATFORM alpine AS packager-docker-mcp
WORKDIR /mcp
ARG DOCKER_MCP_PLUGIN_BINARY
RUN --mount=from=binary-docker-mcp mkdir -p /out && cp ${DOCKER_MCP_PLUGIN_BINARY}* /out/
FROM scratch AS package-docker-mcp
COPY --from=packager-docker-mcp /out .
# Build the mcp-gateway image
FROM golang:${GO_VERSION}-alpine AS build-mcp-gateway
WORKDIR /app
RUN --mount=type=cache,target=/root/.cache/go-build,id=mcp-gateway \
--mount=source=.,target=. \
go build -trimpath -ldflags "-s -w" -o / ./cmd/docker-mcp/
FROM golang:${GO_VERSION}-alpine AS build-mcp-bridge
WORKDIR /app
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=source=./tools/docker-mcp-bridge,target=. \
go build -trimpath -ldflags "-s -w" -o /docker-mcp-bridge .
FROM alpine:3.23@sha256:865b95f46d98cf867a156fe4a135ad3fe50d2056aa3f25ed31662dff6da4eb62 AS mcp-gateway
RUN apk update && apk upgrade --no-cache && apk add --no-cache docker-cli socat jq
VOLUME /misc
COPY --from=build-mcp-bridge /docker-mcp-bridge /misc/
ENV DOCKER_MCP_IN_CONTAINER=1
ENTRYPOINT ["/docker-mcp", "gateway", "run"]
COPY --from=build-mcp-gateway /docker-mcp /
FROM docker:dind@sha256:4dd2f7e405b1a10fda628f22cd466be1e3be2bcfc46db653ab620e02eeed5794 AS dind
RUN rm /usr/local/bin/docker-compose \
/usr/local/libexec/docker/cli-plugins/docker-compose \
/usr/local/libexec/docker/cli-plugins/docker-buildx
FROM scratch AS mcp-gateway-dind
COPY --from=dind / /
RUN apk update && apk upgrade --no-cache && apk add --no-cache socat jq
COPY --from=docker/mcp-gateway /docker-mcp /
RUN cat <<-'EOF' >/run.sh
#!/usr/bin/env sh
set -euxo pipefail
echo "Starting dockerd..."
export TINI_SUBREAPER=1
export DOCKER_DRIVER=vfs
dockerd-entrypoint.sh dockerd &
until docker info > /dev/null 2>&1
do
echo "Waiting for dockerd..."
sleep 1
done
echo "Detected dockerd ready for work!"
export DOCKER_MCP_IN_CONTAINER=1
export DOCKER_MCP_IN_DIND=1
echo "Starting MCP Gateway on port $PORT..."
exec /docker-mcp gateway run --port=$PORT "$@"
EOF
RUN chmod +x /run.sh
ENV PORT=8080
ENTRYPOINT ["/run.sh"]