Skip to content

Commit 458c6c5

Browse files
authored
feat: multi-arch Docker images built with Nix (#62)
- Replace `Dockerfile` and `.dockerignore` with pure Nix image builds (`dockerTools.buildLayeredImage` + `pkgsCross`) - Build `linux/amd64` and `linux/arm64` images via `nix build` - Publish workflow pushes images by digest (via `skopeo`) and assembles multi-arch manifests with `docker buildx imagetools create` - Test workflow runs both arch builds in a matrix; functional test and scan run on amd64 - Add `skopeo` to dev shell and use `nix develop --command bash {0}` as default shell in CI jobs
1 parent 21356d8 commit 458c6c5

15 files changed

Lines changed: 210 additions & 89 deletions

.dockerignore

Lines changed: 0 additions & 11 deletions
This file was deleted.

.github/workflows/publish.yaml

Lines changed: 97 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,34 +51,108 @@ jobs:
5151
echo "new_version=$VERSION" >> $GITHUB_OUTPUT
5252
fi
5353
54-
push_to_registry:
55-
name: Push Docker image to GitHub Packages
54+
build:
55+
name: Build ${{ matrix.arch }} image
5656
runs-on: ubuntu-latest
5757
needs: [ get-newer-version ]
5858
if: needs.get-newer-version.outputs.new-version != ''
59+
defaults:
60+
run:
61+
shell: nix develop --command bash {0}
5962
permissions:
60-
contents: read # required for actions/checkout
61-
packages: write # required for pushing to ghcr.io
63+
contents: read
64+
packages: write
65+
strategy:
66+
matrix:
67+
include:
68+
- arch: amd64
69+
nix_package: sysdig-mcp-server-image-amd64
70+
- arch: arm64
71+
nix_package: sysdig-mcp-server-image-aarch64
6272
steps:
6373
- name: Check out the repo
6474
uses: actions/checkout@v5
6575

76+
- name: Install Nix
77+
# Pinned to v21 commit SHA for supply-chain safety.
78+
# To update: git ls-remote https://github.com/DeterminateSystems/nix-installer-action.git <tag>
79+
uses: DeterminateSystems/nix-installer-action@c5a866b6ab867e88becbed4467b93592bce69f8a # v21
80+
81+
- name: Enable Nix cache
82+
# Pinned to v13 commit SHA for supply-chain safety.
83+
# To update: git ls-remote https://github.com/DeterminateSystems/magic-nix-cache-action.git <tag>
84+
uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39 # v13
85+
with:
86+
use-flakehub: false
87+
88+
- name: Build image
89+
run: nix build .#${{ matrix.nix_package }} -o result
90+
91+
- name: Log in to GitHub Container Registry
92+
run: echo "${{ secrets.GITHUB_TOKEN }}" | skopeo login ghcr.io -u "${{ github.actor }}" --password-stdin
93+
94+
- name: Push image by digest
95+
id: push
96+
env:
97+
REGISTRY: ghcr.io/sysdiglabs/sysdig-mcp-server
98+
run: |
99+
skopeo copy --digestfile /tmp/digest \
100+
docker-archive:result \
101+
docker://$REGISTRY --format oci
102+
103+
mkdir -p /tmp/digests
104+
cp /tmp/digest /tmp/digests/${{ matrix.arch }}
105+
106+
- name: Upload digest
107+
uses: actions/upload-artifact@v5
108+
with:
109+
name: digests-${{ matrix.arch }}
110+
path: /tmp/digests/*
111+
if-no-files-found: error
112+
retention-days: 1
113+
114+
push_to_registry:
115+
name: Push multi-arch manifest to GitHub Packages
116+
runs-on: ubuntu-latest
117+
needs: [ get-newer-version, build ]
118+
permissions:
119+
contents: read
120+
packages: write
121+
env:
122+
REGISTRY: ghcr.io/sysdiglabs/sysdig-mcp-server
123+
steps:
124+
- name: Download digests
125+
uses: actions/download-artifact@v6
126+
with:
127+
path: /tmp/digests
128+
pattern: digests-*
129+
merge-multiple: true
130+
131+
- name: Set up Docker Buildx
132+
uses: docker/setup-buildx-action@v3
133+
66134
- name: Log in to GitHub Container Registry
67135
uses: docker/login-action@v3
68136
with:
69137
registry: ghcr.io
70138
username: ${{ github.actor }}
71139
password: ${{ secrets.GITHUB_TOKEN }}
72140

73-
- name: Build and push Docker image
74-
id: build-and-push
75-
uses: docker/build-push-action@v6
76-
with:
77-
context: .
78-
push: true
79-
tags: |
80-
ghcr.io/sysdiglabs/sysdig-mcp-server:latest
81-
ghcr.io/sysdiglabs/sysdig-mcp-server:${{ needs.get-newer-version.outputs.new-version }}
141+
- name: Create manifest list and push
142+
env:
143+
VERSION: ${{ needs.get-newer-version.outputs.new-version }}
144+
working-directory: /tmp/digests
145+
run: |
146+
docker buildx imagetools create --tag $REGISTRY:${VERSION} \
147+
$(printf "$REGISTRY@%s " $(cat *))
148+
149+
docker buildx imagetools create --tag $REGISTRY:latest \
150+
$(printf "$REGISTRY@%s " $(cat *))
151+
152+
- name: Inspect image
153+
env:
154+
VERSION: ${{ needs.get-newer-version.outputs.new-version }}
155+
run: docker buildx imagetools inspect $REGISTRY:${VERSION}
82156

83157
release:
84158
name: Create release at Github
@@ -94,7 +168,16 @@ jobs:
94168
fetch-tags: true
95169

96170
- name: Install Nix
97-
uses: DeterminateSystems/nix-installer-action@main
171+
# Pinned to v21 commit SHA for supply-chain safety.
172+
# To update: git ls-remote https://github.com/DeterminateSystems/nix-installer-action.git <tag>
173+
uses: DeterminateSystems/nix-installer-action@c5a866b6ab867e88becbed4467b93592bce69f8a # v21
174+
175+
- name: Enable Nix cache
176+
# Pinned to v13 commit SHA for supply-chain safety.
177+
# To update: git ls-remote https://github.com/DeterminateSystems/magic-nix-cache-action.git <tag>
178+
uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39 # v13
179+
with:
180+
use-flakehub: false
98181

99182
- name: Install git-chglog
100183
run: nix profile install nixpkgs#git-chglog

.github/workflows/test.yaml

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ concurrency:
1313
cancel-in-progress: true
1414

1515
jobs:
16-
test:
17-
name: Test
16+
build-and-test:
17+
name: Build and Test
1818
runs-on: ubuntu-latest
1919
defaults:
2020
run:
@@ -24,25 +24,22 @@ jobs:
2424
uses: actions/checkout@v4
2525

2626
- name: Install nix
27-
uses: DeterminateSystems/nix-installer-action@main
27+
# Pinned to v21 commit SHA for supply-chain safety.
28+
# To update: git ls-remote https://github.com/DeterminateSystems/nix-installer-action.git <tag>
29+
uses: DeterminateSystems/nix-installer-action@c5a866b6ab867e88becbed4467b93592bce69f8a # v21
30+
31+
- name: Enable Nix cache
32+
# Pinned to v13 commit SHA for supply-chain safety.
33+
# To update: git ls-remote https://github.com/DeterminateSystems/magic-nix-cache-action.git <tag>
34+
uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39 # v13
35+
with:
36+
use-flakehub: false
37+
38+
- name: Build
39+
run: go build ./...
2840

2941
- name: Run Checks
3042
run: just check
3143
env:
3244
SYSDIG_MCP_API_HOST: ${{ vars.SYSDIG_MCP_API_HOST }}
3345
SYSDIG_MCP_API_TOKEN: ${{ secrets.SYSDIG_MCP_API_SECURE_TOKEN }}
34-
build:
35-
name: Build
36-
runs-on: ubuntu-latest
37-
defaults:
38-
run:
39-
shell: nix develop --command bash {0}
40-
steps:
41-
- name: Check out the repo
42-
uses: actions/checkout@v4
43-
44-
- name: Install nix
45-
uses: DeterminateSystems/nix-installer-action@main
46-
47-
- name: Build
48-
run: go build ./...

.github/workflows/test_image.yaml

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,54 @@ concurrency:
1515

1616
jobs:
1717
test_build:
18-
name: Test Build
18+
name: Test Build (${{ matrix.arch }})
1919
runs-on: ubuntu-latest
2020
permissions:
2121
contents: read # required for actions/checkout
22-
packages: write # required for pushing the test image to ghcr.io
22+
strategy:
23+
max-parallel: 1
24+
matrix:
25+
include:
26+
- arch: amd64
27+
nix_package: sysdig-mcp-server-image-amd64
28+
- arch: arm64
29+
nix_package: sysdig-mcp-server-image-aarch64
2330
steps:
2431
- name: Check out the repo
2532
uses: actions/checkout@v5
2633
with:
27-
ref: ${{ github.sha }} # required for better experience using pre-releases
28-
fetch-depth: "0" # Required due to the way Git works, without it this action won't be able to find any or the correct tags
34+
ref: ${{ github.sha }}
35+
fetch-depth: "0"
2936

30-
- name: Build Docker image and test push action
31-
id: build-to-test
32-
uses: docker/build-push-action@v6
37+
- name: Install Nix
38+
# Pinned to v21 commit SHA for supply-chain safety.
39+
# To update: git ls-remote https://github.com/DeterminateSystems/nix-installer-action.git <tag>
40+
uses: DeterminateSystems/nix-installer-action@c5a866b6ab867e88becbed4467b93592bce69f8a # v21
41+
42+
- name: Enable Nix cache
43+
# Pinned to v13 commit SHA for supply-chain safety.
44+
# To update: git ls-remote https://github.com/DeterminateSystems/magic-nix-cache-action.git <tag>
45+
uses: DeterminateSystems/magic-nix-cache-action@565684385bcd71bad329742eefe8d12f2e765b39 # v13
3346
with:
34-
context: .
35-
load: true
36-
push: false
37-
tags: |
38-
ghcr.io/sysdiglabs/sysdig-mcp-server:test
47+
use-flakehub: false
48+
49+
- name: Build image
50+
run: nix build .#${{ matrix.nix_package }} -o result
3951

40-
- name: Test we can execute the docker image
52+
- name: Load image
53+
id: load
4154
run: |
42-
docker run --rm ghcr.io/sysdiglabs/sysdig-mcp-server:test --help | grep "Sysdig MCP Server"
55+
IMAGE_TAG=$(docker load < result | sed -n 's/Loaded image: //p')
56+
echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
57+
58+
- name: Test image
59+
if: matrix.arch == 'amd64'
60+
run: docker run --rm "${{ steps.load.outputs.image_tag }}" --help | grep "Sysdig MCP Server"
4361

4462
- name: Scan Docker image
4563
uses: sysdiglabs/scan-action@v6
4664
with:
47-
image-tag: ghcr.io/sysdiglabs/sysdig-mcp-server:test
65+
image-tag: ${{ steps.load.outputs.image_tag }}
4866
sysdig-secure-token: ${{ secrets.SECURE_ENV_MON_API_KEY }}
4967
sysdig-secure-url: ${{ secrets.SECURE_ENV_MON_ENDPOINT }}
5068
stop-on-failed-policy-eval: true

AGENTS.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,16 @@ fix: correct API endpoint URL
133133
chore: update dependencies
134134
```
135135

136+
### 4.5. Known Flaky Integration Tests
137+
138+
The process tree integration tests in `internal/infra/sysdig/client_process_tree_integration_test.go` use a **hardcoded event ID** that points to a real Sysdig event. Since Sysdig events have a retention period, this event will eventually be deleted and the tests will fail with a `not found` error.
139+
140+
**How to fix it:**
141+
142+
1. Use the `list_runtime_events` MCP tool (or the Sysdig API) to find a recent runtime event that originates from a **syscall/workload source** (not cloud/cloudtrail), as only these have process trees. Filter for `category = "runtime"` and `source = "syscall"`.
143+
2. Verify the event has a process tree by calling `get_event_process_tree` with the event ID.
144+
3. Update the `eventID` variable in the test's `BeforeEach` block with the new event ID.
145+
136146
## 5. Guides & Reference
137147

138148
* **Tools & New Tool Creation:** See `internal/infra/mcp/tools/README.md`

Dockerfile

Lines changed: 0 additions & 23 deletions
This file was deleted.

docker-base-aarch64.nix

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
imageName = "quay.io/sysdig/sysdig-mini-ubi9";
3+
imageDigest = "sha256:efee7299f1be1971c83826175f8583bed3736ff817dc38c1d266dfa6385d9b3b";
4+
hash = "sha256-Ga+VuvBYshe93r8yIN9//dRdw/sfTNsxHl2x+3A5TXE=";
5+
finalImageName = "quay.io/sysdig/sysdig-mini-ubi9";
6+
finalImageTag = "1";
7+
}

docker-base-amd64.nix

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
imageName = "quay.io/sysdig/sysdig-mini-ubi9";
3+
imageDigest = "sha256:efee7299f1be1971c83826175f8583bed3736ff817dc38c1d266dfa6385d9b3b";
4+
hash = "sha256-3K1eClgXOCAYFg5OA6SbzrUrI9xATXkG3bM1Y/t3E6I=";
5+
finalImageName = "quay.io/sysdig/sysdig-mini-ubi9";
6+
finalImageTag = "1";
7+
}

docker.nix

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
dockerTools,
3+
sysdig-mcp-server,
4+
stdenv,
5+
}:
6+
let
7+
arch = if stdenv.hostPlatform.isAarch64 then "arm64" else "amd64";
8+
baseImageAmd64 = import ./docker-base-amd64.nix;
9+
baseImageAarch64 = import ./docker-base-aarch64.nix;
10+
baseImage = dockerTools.pullImage (
11+
if stdenv.hostPlatform.isAarch64 then baseImageAarch64 else baseImageAmd64
12+
);
13+
in
14+
dockerTools.buildLayeredImage {
15+
name = sysdig-mcp-server.pname;
16+
tag = "${sysdig-mcp-server.version}-${arch}";
17+
contents = [ sysdig-mcp-server ];
18+
fromImage = baseImage;
19+
config = {
20+
Entrypoint = [ "${sysdig-mcp-server}/bin/sysdig-mcp-server" ];
21+
User = "1000";
22+
};
23+
}

flake.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)