Skip to content

Commit 06d0bc7

Browse files
create container (#29)
This commit adds support for building container images from nix and a corresponding github action on versioned tags.
1 parent 2e94aab commit 06d0bc7

File tree

3 files changed

+132
-1
lines changed

3 files changed

+132
-1
lines changed

.github/workflows/release.yml

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: Build Release
2+
on:
3+
push:
4+
tags:
5+
- "v[0-9]+.[0-9]+.[0-9]+"
6+
7+
env:
8+
REGISTRY: ghcr.io
9+
IMAGE_NAME: ${{ github.repository }}
10+
11+
jobs:
12+
release:
13+
name: Release
14+
strategy:
15+
matrix:
16+
os: ["ubuntu-24.04", "ubuntu-24.04-arm"]
17+
runs-on: ${{ matrix.os }}
18+
permissions:
19+
contents: read
20+
packages: write
21+
attestations: write
22+
id-token: write
23+
steps:
24+
- uses: actions/checkout@v4
25+
26+
# Extract needed info for use with the other steps
27+
- id: repo-meta
28+
name: Extract Metadata
29+
shell: bash
30+
run: |
31+
echo "fqdn=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" >> $GITHUB_OUTPUT
32+
echo "name=`basename ${{ github.repository }}`" >> $GITHUB_OUTPUT
33+
34+
- uses: nixbuild/nix-quick-install-action@v30
35+
with:
36+
nix_conf: ${{ env.nix_conf }}
37+
- name: Restore and save Nix store
38+
uses: nix-community/cache-nix-action@v6
39+
with:
40+
primary-key: build-${{ runner.os }}-${{ hashFiles('Cargo.lock', '**/Cargo.toml', 'flake.nix', 'flake.lock', 'rust-toolchain.toml') }}
41+
# We don't want to affect the cache when building the container
42+
purge: false
43+
save: false
44+
45+
- name: Log in to the Container registry
46+
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
47+
with:
48+
registry: ${{ env.REGISTRY }}
49+
username: ${{ github.actor }}
50+
password: ${{ secrets.GITHUB_TOKEN }}
51+
52+
- name: Build Container
53+
run: nix run .#streamImage | docker image load
54+
55+
- name: Tag the Container
56+
run: |
57+
docker image tag "${{ steps.repo-meta.outputs.name }}:latest" "${{ steps.repo-meta.outputs.fqdn }}:latest"
58+
docker image tag "${{ steps.repo-meta.outputs.name }}:latest" "${{ steps.repo-meta.outputs.fqdn }}:${{ github.ref_name }}"
59+
60+
- name: Push the Container
61+
run: docker image push --all-tags "${{ steps.repo-meta.outputs.fqdn }}"
62+
63+
- id: digest-meta
64+
name: Extract the digest
65+
shell: bash
66+
run: echo "digest=`docker manifest inspect ${{ steps.repo-meta.outputs.fqdn }}:latest --verbose | nix run nixpkgs#jq -- -r .Descriptor.digest`" >> $GITHUB_OUTPUT
67+
68+
- name: Generate artifact attestation
69+
uses: actions/attest-build-provenance@v2
70+
with:
71+
subject-name: ${{ steps.repo-meta.outputs.fqdn }}
72+
subject-digest: ${{ steps.digest-meta.outputs.digest }}
73+
push-to-registry: true

README.md

+22
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,28 @@ Two new tools will be exposed by the server:
220220

221221
The MCP client can then use these tools to provide schema information to the model, and allow the model to execute GraphQL operations based on that schema.
222222

223+
# Running in a Container
224+
225+
The MCP server is also available as a standalone docker container. The following command
226+
demonstrates how to use the container. Refer to previous sections for all valid
227+
server arguments.
228+
229+
By default, the container expects all schema files to be present in the
230+
`/data` folder within the container, so make sure to mount your files there. The
231+
example below uses the provided weather example for reference
232+
233+
```sh
234+
docker run \
235+
-it --rm \
236+
--name mcp-apollo-server \
237+
-p 5000:5000 \
238+
-v $PWD/graphql/weather:/data \
239+
ghcr.io/apollographql/mcp-apollo:latest \
240+
--sse-port 5000 \
241+
-s api.graphql \
242+
# Other MCP server options...
243+
```
244+
223245
# Licensing
224246

225247
Source code in this repository is covered by the Elastic License 2.0. The

flake.nix

+37-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
inherit pkgs inputs;
8181
derivations = [cargoArtifacts toolchain] ++ mcp-server-tools;
8282
};
83-
in {
83+
in rec {
8484
devShells.default = pkgs.mkShell {
8585
nativeBuildInputs = with pkgs; [pkg-config];
8686
buildInputs =
@@ -141,5 +141,41 @@
141141
# CI related packages
142142
inherit (garbageCollector) saveFromGC;
143143
};
144+
145+
# TODO: This does not work on macOS without cross compiling, so maybe
146+
# we need to disable flake-utils and manually specify the supported
147+
# hosts?
148+
apps = let
149+
# Nix flakes don't yet expose a nice formatted timestamp in ISO-8601
150+
# format, so we need to drop out to date to do so.
151+
commitDate = pkgs.lib.readFile "${pkgs.runCommand "git-timestamp" {env.when = self.lastModified;} "echo -n `date -d @$when --iso-8601=seconds` > $out"}";
152+
builder = pkgs.dockerTools.streamLayeredImage {
153+
name = "mcp-apollo";
154+
tag = "latest";
155+
156+
# Use the latest commit time for reproducible builds
157+
created = commitDate;
158+
mtime = commitDate;
159+
160+
contents = [
161+
packages.mcp-apollo-server
162+
];
163+
164+
config = {
165+
# Make the entrypoint the server
166+
Entrypoint = ["mcp-apollo-server" "-d" "/data"];
167+
168+
# Drop to local user
169+
User = "1000";
170+
Group = "1000";
171+
};
172+
};
173+
in {
174+
streamImage = {
175+
type = "app";
176+
program = "${builder}";
177+
meta.description = "Builds the mcp-apollo-server container and streams the image to stdout.";
178+
};
179+
};
144180
});
145181
}

0 commit comments

Comments
 (0)