Skip to content

Commit 3d9511c

Browse files
authored
Merge pull request #58 from Azure/docker-build-fix
chore: add multiarch image for mcp-kubernetes image
2 parents dcf7b25 + 798dfce commit 3d9511c

4 files changed

Lines changed: 193 additions & 16 deletions

File tree

.github/workflows/ci.yml

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,29 @@ jobs:
6767
path: coverage.txt
6868
retention-days: 14
6969

70+
args:
71+
runs-on: ubuntu-latest
72+
outputs:
73+
commit-date: ${{ steps.ldflags.outputs.commit-date }}
74+
commit: ${{ steps.ldflags.outputs.commit }}
75+
version: ${{ steps.ldflags.outputs.version }}
76+
tree-state: ${{ steps.ldflags.outputs.tree-state }}
77+
steps:
78+
- id: checkout
79+
uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 # tag=v2.3.4
80+
with:
81+
fetch-depth: 0
82+
- id: ldflags
83+
run: |
84+
echo "commit-date=$(git log --date=iso8601-strict -1 --pretty=%ct)" >> "$GITHUB_OUTPUT"
85+
echo "commit=$GITHUB_SHA" >> "$GITHUB_OUTPUT"
86+
echo "version=$(git describe --tags --always --dirty | cut -c2-)" >> "$GITHUB_OUTPUT"
87+
echo "tree-state=$(if git diff --quiet; then echo "clean"; else echo "dirty"; fi)" >> "$GITHUB_OUTPUT"
88+
7089
build:
71-
name: Build
90+
name: Build Linux
7291
runs-on: ubuntu-latest
73-
needs: [lint, test]
92+
needs: [lint, test, args]
7493
steps:
7594
- name: Checkout code
7695
uses: actions/checkout@v4.2.2
@@ -86,16 +105,35 @@ jobs:
86105

87106
- name: Build binary
88107
run: |
89-
go build -v -ldflags="-X github.com/Azure/mcp-kubernetes/pkg/version.GitCommit=$(git rev-parse HEAD) -X github.com/Azure/mcp-kubernetes/pkg/version.BuildMetadata=$(date +%Y%m%d)" -o mcp-kubernetes ./cmd/mcp-kubernetes
108+
go build -v -o mcp-kubernetes ./cmd/mcp-kubernetes
90109
91110
- name: Build Docker image
92-
run: docker build -t mcp-kubernetes:test --build-arg VERSION=$(git describe --tags --always --dirty | cut -c2-),GIT_COMMIT=$(git rev-parse HEAD),BUILD_DATE=$(date +%Y%m%d),GIT_TREE_STATE=$(if git diff --quiet; then echo "clean"; else echo "dirty"; fi) .
111+
run: docker build -t mcp-kubernetes:test --build-arg VERSION=${{ needs.args.outputs.version }} --build-arg GIT_COMMIT=${{ needs.args.outputs.commit }} --build-arg BUILD_DATE=${{ needs.args.outputs.commit-date }} --build-arg GIT_TREE_STATE=${{ needs.args.outputs.tree-state }} .
93112

94113
- name: Check Docker image
95114
run: |
96115
docker images mcp-kubernetes:test
97116
docker run --rm mcp-kubernetes:test --version || true
98117
118+
build-windows:
119+
name: Build Windows
120+
runs-on: windows-latest
121+
needs: [lint, test, args]
122+
steps:
123+
- name: Checkout code
124+
uses: actions/checkout@v4.2.2
125+
with:
126+
fetch-depth: 0
127+
128+
- name: Build Windows Docker image
129+
run: |
130+
docker build --platform windows/amd64 -f Dockerfile.windows -t mcp-kubernetes:windows-test --build-arg VERSION=${{ needs.args.outputs.version }} --build-arg GIT_COMMIT=${{ needs.args.outputs.commit }} --build-arg BUILD_DATE=${{ needs.args.outputs.commit-date }} --build-arg GIT_TREE_STATE=${{ needs.args.outputs.tree-state }} .
131+
132+
- name: Validate Windows Docker image
133+
run: |
134+
docker images mcp-kubernetes:windows-test
135+
docker run --rm mcp-kubernetes:windows-test --help || true
136+
99137
security:
100138
name: Security Scan
101139
runs-on: ubuntu-latest

.github/workflows/go-ossf-slsa3-publish.yml

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,14 @@ jobs:
6868
# Optional: For more options, see https://github.com/slsa-framework/slsa-github-generator#golang-projects
6969
# =============================================================================================================
7070

71-
build-image:
71+
build-linux-image:
7272
permissions:
7373
contents: read
7474
packages: write
7575
needs: args
7676
outputs:
7777
image: ${{ steps.image.outputs.image }}
78-
digest: ${{ steps.build.outputs.digest }}
78+
digest: ${{ steps.image.outputs.digest }}
7979
runs-on: ubuntu-latest
8080
steps:
8181
- name: Checkout the repository
@@ -101,6 +101,7 @@ jobs:
101101
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
102102
id: build
103103
with:
104+
platforms: linux/amd64,linux/arm64
104105
push: true
105106
tags: ${{ steps.meta.outputs.tags }}
106107
labels: ${{ steps.meta.outputs.labels }}
@@ -109,25 +110,64 @@ jobs:
109110
GIT_COMMIT=${{ needs.args.outputs.commit }}
110111
BUILD_DATE=${{ needs.args.outputs.commit-date }}
111112
GIT_TREE_STATE=${{ needs.args.outputs.tree-state }}
113+
112114
- name: Output image
113115
id: image
114116
run: |
115117
# NOTE: Set the image as an output because the `env` context is not
116118
# available to the inputs of a reusable workflow call.
117119
image_name=$(echo "${IMAGE_REGISTRY}/${IMAGE_NAME}"| tr '[:upper:]' '[:lower:]')
118120
echo "image=$image_name" >> "$GITHUB_OUTPUT"
121+
122+
build-windows-image:
123+
permissions:
124+
contents: read
125+
packages: write
126+
needs: args
127+
runs-on: windows-latest
128+
steps:
129+
- name: Checkout the repository
130+
uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 # v2.3.4
131+
132+
- name: Authenticate Docker
133+
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
134+
with:
135+
registry: ${{ env.IMAGE_REGISTRY }}
136+
username: ${{ github.actor }}
137+
password: ${{ secrets.GITHUB_TOKEN }}
138+
139+
- name: Extract metadata (tags, labels) for Docker
140+
id: meta
141+
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
142+
with:
143+
images: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}
144+
145+
- name: Build and push Windows Docker image
146+
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
147+
with:
148+
platforms: windows/amd64
149+
push: true
150+
tags: ${{ steps.meta.outputs.tags }}
151+
labels: ${{ steps.meta.outputs.labels }}
152+
file: ./Dockerfile.windows
153+
build-args: |
154+
VERSION=${{ needs.args.outputs.version }}
155+
GIT_COMMIT=${{ needs.args.outputs.commit }}
156+
BUILD_DATE=${{ needs.args.outputs.commit-date }}
157+
GIT_TREE_STATE=${{ needs.args.outputs.tree-state }}
158+
119159
# This step calls the container workflow to generate provenance and push it to
120160
# the container registry.
121161
provenance:
122-
needs: build-image
162+
needs: build-linux-image
123163
permissions:
124164
actions: read # for detecting the Github Actions environment.
125165
id-token: write # for creating OIDC tokens for signing.
126166
packages: write # for uploading attestations.
127167
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.1.0
128168
with:
129-
image: ${{ needs.build-image.outputs.image }}
130-
digest: ${{ needs.build-image.outputs.digest }}
169+
image: ${{ needs.build-linux-image.outputs.image }}
170+
digest: ${{ needs.build-linux-image.outputs.digest }}
131171
registry-username: ${{ github.actor }}
132172
private-repository: true
133173
secrets:

Dockerfile

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ ARG VERSION
44
ARG GIT_COMMIT
55
ARG BUILD_DATE
66
ARG GIT_TREE_STATE
7+
ARG TARGETOS
8+
ARG TARGETARCH
9+
710
# Set working directory
811
WORKDIR /app
912

@@ -17,10 +20,11 @@ RUN go mod download
1720
COPY . .
1821

1922
# Build the application
20-
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags "-X github.com/Azure/mcp-kubernetes/pkg/version.GitVersion=${VERSION} -X github.com/Azure/mcp-kubernetes/pkg/version.GitCommit=${GIT_COMMIT} -X github.com/Azure/mcp-kubernetes/pkg/version.BuildMetadata=${BUILD_DATE} -X github.com/Azure/mcp-kubernetes/pkg/version.GitTreeState=${GIT_TREE_STATE}" -o mcp-kubernetes ./cmd/mcp-kubernetes
23+
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags "-X github.com/Azure/mcp-kubernetes/pkg/version.GitVersion=${VERSION} -X github.com/Azure/mcp-kubernetes/pkg/version.GitCommit=${GIT_COMMIT} -X github.com/Azure/mcp-kubernetes/pkg/version.BuildMetadata=${BUILD_DATE} -X github.com/Azure/mcp-kubernetes/pkg/version.GitTreeState=${GIT_TREE_STATE}" -o mcp-kubernetes ./cmd/mcp-kubernetes
2124

2225
# Runtime stage
2326
FROM alpine:3.19
27+
ARG TARGETARCH
2428

2529
# Install required packages for kubectl and helm
2630
RUN apk add --no-cache curl bash openssl ca-certificates git
@@ -32,27 +36,26 @@ RUN addgroup -S mcp && \
3236
chown -R mcp:mcp /home/mcp
3337

3438
# Install kubectl
35-
RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && \
39+
RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/${TARGETARCH}/kubectl" && \
3640
chmod +x kubectl && \
3741
mv kubectl /usr/local/bin/kubectl
3842

3943
# Install helm
40-
RUN curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 && \
44+
RUN HELM_ARCH=${TARGETARCH} && \
45+
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 && \
4146
chmod 700 get_helm.sh && \
4247
VERIFY_CHECKSUM=false ./get_helm.sh && \
4348
rm get_helm.sh
4449

4550
# Install cilium
4651
RUN CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt) && \
47-
CLI_ARCH=amd64 && \
48-
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi && \
52+
CLI_ARCH=${TARGETARCH} && \
4953
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz && \
5054
tar xzf cilium-linux-${CLI_ARCH}.tar.gz -C /usr/local/bin && \
5155
rm cilium-linux-${CLI_ARCH}.tar.gz
5256

5357
RUN HUBBLE_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/hubble/master/stable.txt) && \
54-
HUBBLE_ARCH=amd64 && \
55-
if [ "$(uname -m)" = "aarch64" ]; then HUBBLE_ARCH=arm64; fi && \
58+
HUBBLE_ARCH=${TARGETARCH} && \
5659
curl -L --fail --remote-name-all https://github.com/cilium/hubble/releases/download/$HUBBLE_VERSION/hubble-linux-${HUBBLE_ARCH}.tar.gz{,.sha256sum} && \
5760
sha256sum -c hubble-linux-${HUBBLE_ARCH}.tar.gz.sha256sum && \
5861
tar xzvf hubble-linux-${HUBBLE_ARCH}.tar.gz -C /usr/local/bin && \

Dockerfile.windows

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Build stage
2+
FROM golang:1.24-windowsservercore-ltsc2022 AS builder
3+
ARG VERSION
4+
ARG GIT_COMMIT
5+
ARG BUILD_DATE
6+
ARG GIT_TREE_STATE
7+
ARG TARGETOS=windows
8+
ARG TARGETARCH=amd64
9+
10+
# Set working directory
11+
WORKDIR "C:\\mcp"
12+
13+
# Copy go mod and sum files
14+
COPY go.mod go.sum ./
15+
16+
# Download dependencies
17+
RUN go mod download
18+
19+
# Copy source code
20+
COPY . .
21+
22+
# Build the application
23+
RUN powershell -Command " \
24+
$env:VERSION = '%VERSION%'; \
25+
$env:GIT_COMMIT = '%GIT_COMMIT%'; \
26+
$env:BUILD_DATE = '%BUILD_DATE%'; \
27+
$env:GIT_TREE_STATE = '%GIT_TREE_STATE%'; \
28+
go build -ldflags \"-X github.com/Azure/mcp-kubernetes/pkg/version.GitVersion=$env:VERSION -X github.com/Azure/mcp-kubernetes/pkg/version.GitCommit=$env:GIT_COMMIT -X github.com/Azure/mcp-kubernetes/pkg/version.BuildMetadata=$env:BUILD_DATE -X github.com/Azure/mcp-kubernetes/pkg/version.GitTreeState=$env:GIT_TREE_STATE\" -o mcp-kubernetes.exe ./cmd/mcp-kubernetes"
29+
30+
# Runtime stage
31+
FROM mcr.microsoft.com/windows/servercore:ltsc2022
32+
ARG TARGETARCH=amd64
33+
34+
# Install Chocolatey
35+
RUN powershell -Command \
36+
Set-ExecutionPolicy Bypass -Scope Process -Force; \
37+
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; \
38+
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
39+
40+
41+
# Set working directory
42+
WORKDIR "C:\\mcp"
43+
44+
# Install git and other dependencies
45+
RUN choco install -y git
46+
47+
# Create directory structure
48+
RUN mkdir "C:\\mcp\\.kube"
49+
50+
# Install kubectl
51+
RUN powershell -Command \
52+
$stableVersion = (Invoke-WebRequest -Uri 'https://dl.k8s.io/release/stable.txt' -UseBasicParsing).Content.Trim(); \
53+
$arch = if ($env:TARGETARCH -eq 'arm64') {'arm64'} else {'amd64'}; \
54+
Invoke-WebRequest -Uri "https://dl.k8s.io/release/$stableVersion/bin/windows/$arch/kubectl.exe" -OutFile 'C:\\kubectl.exe' -UseBasicParsing; \
55+
Move-Item C:\\kubectl.exe C:\\Windows\\System32\\kubectl.exe
56+
57+
# Install helm
58+
RUN powershell -Command \
59+
$arch = if ($env:TARGETARCH -eq 'arm64') {'arm64'} else {'amd64'}; \
60+
Invoke-WebRequest -Uri "https://get.helm.sh/helm-v3.17.4-windows-$arch.zip" -OutFile 'helm.zip' -UseBasicParsing; \
61+
Expand-Archive -Path helm.zip -DestinationPath "C:\\helm"; \
62+
Move-Item "C:\\helm\\windows-$arch\\helm.exe" "C:\\Windows\\System32\\helm.exe"; \
63+
Remove-Item -Recurse -Force "C:\\helm"; \
64+
Remove-Item helm.zip
65+
66+
# Install cilium CLI
67+
RUN powershell -Command \
68+
$cliVersion = (Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt' -UseBasicParsing).Content.Trim(); \
69+
$arch = if ($env:TARGETARCH -eq 'arm64') {'arm64'} else {'amd64'}; \
70+
Invoke-WebRequest -Uri "https://github.com/cilium/cilium-cli/releases/download/$cliVersion/cilium-windows-$arch.zip" -OutFile 'cilium.zip' -UseBasicParsing; \
71+
Expand-Archive -Path cilium.zip -DestinationPath "C:\\cilium"; \
72+
Move-Item "C:\\cilium\\cilium.exe" "C:\\Windows\\System32\\cilium.exe"; \
73+
Remove-Item -Recurse -Force "C:\\cilium"; \
74+
Remove-Item cilium.zip
75+
76+
# Install hubble CLI
77+
RUN powershell -Command \
78+
$hubbleVersion = (Invoke-WebRequest -Uri 'https://raw.githubusercontent.com/cilium/hubble/master/stable.txt' -UseBasicParsing).Content.Trim(); \
79+
$arch = if ($env:TARGETARCH -eq 'arm64') {'arm64'} else {'amd64'}; \
80+
Invoke-WebRequest -Uri "https://github.com/cilium/hubble/releases/download/$hubbleVersion/hubble-windows-$arch.tar.gz" -OutFile 'hubble.tar.gz' -UseBasicParsing; \
81+
tar -xzf hubble.tar.gz -C "C:\\Windows\\System32"; \
82+
Remove-Item hubble.tar.gz
83+
84+
# Copy binary from builder
85+
COPY --from=builder "C:\\mcp\\mcp-kubernetes.exe" "C:\\mcp\\mcp-kubernetes.exe"
86+
87+
# Expose the default port for sse/streamable-http transports
88+
EXPOSE 8000
89+
90+
# Set environment variables
91+
ENV HOME="C:\\mcp"
92+
ENV KUBECONFIG="C:\\mcp\\.kube\\config"
93+
94+
# Command to run
95+
ENTRYPOINT ["C:\\mcp\\mcp-kubernetes.exe"]
96+
CMD ["--transport", "streamable-http", "--host", "0.0.0.0"]

0 commit comments

Comments
 (0)