Skip to content

Commit b8ad559

Browse files
JAORMXdanbarr
andauthored
docs: Add comprehensive thv build command documentation (#116)
* docs: Add comprehensive thv build command documentation - Add build-containers.mdx guide covering thv build command usage - Add advanced-cicd.mdx guide for production CI/CD patterns - Update sidebar navigation to include both new guides - Cover protocol schemes (uvx://, npx://, go://) - Include Kubernetes deployment workflows - Add troubleshooting section and best practices - Include proper installation commands using GitHub releases Closes #108 * docs: Fix link anchor in build-containers.mdx Remove fragment from thv run link as suggested by GitHub Copilot review * docs: Fix ESLint errors in advanced-cicd.mdx Remove unused Tabs and TabItem imports that were causing lint failures * Fix linter issues Signed-off-by: Juan Antonio Osorio <[email protected]> * Address suggestions Signed-off-by: Juan Antonio Osorio <[email protected]> * Fix broken links Signed-off-by: Dan Barr <[email protected]> --------- Signed-off-by: Juan Antonio Osorio <[email protected]> Signed-off-by: Dan Barr <[email protected]> Co-authored-by: Dan Barr <[email protected]>
1 parent 8764141 commit b8ad559

File tree

3 files changed

+710
-0
lines changed

3 files changed

+710
-0
lines changed
Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
---
2+
title: Advanced CI/CD with ToolHive
3+
description:
4+
Advanced CI/CD patterns for building and deploying MCP server containers with
5+
ToolHive.
6+
---
7+
8+
This guide covers advanced CI/CD patterns for building MCP server containers
9+
using ToolHive's [`thv build`](../reference/cli/thv_build.md) command. These
10+
patterns include multi-architecture builds, supply chain security, and efficient
11+
change detection.
12+
13+
These patterns are intended for anyone building MCP server containers regularly,
14+
such as maintainers of MCP servers or organizations deploying custom servers or
15+
repackaging existing ones.
16+
17+
## Prerequisites
18+
19+
Before implementing these advanced patterns, ensure you have:
20+
21+
- Basic understanding of [`thv build`](./build-containers.mdx) command
22+
- Experience with CI/CD pipelines (GitHub Actions, GitLab CI, etc.)
23+
- Container registry access for pushing images
24+
- Understanding of Docker Buildx for multi-architecture builds
25+
26+
## Multi-architecture MCP server builds
27+
28+
Build MCP server containers for multiple architectures (amd64, arm64) using
29+
Docker Buildx:
30+
31+
```yaml
32+
name: Multi-arch Build
33+
on:
34+
push:
35+
tags: ['v*']
36+
37+
jobs:
38+
build:
39+
runs-on: ubuntu-latest
40+
steps:
41+
- uses: actions/checkout@v4
42+
43+
- name: Set up QEMU
44+
uses: docker/setup-qemu-action@v3
45+
46+
- name: Set up Docker Buildx
47+
uses: docker/setup-buildx-action@v3
48+
49+
- name: Install ToolHive
50+
uses: StacklokLabs/toolhive-actions/install@v0
51+
with:
52+
version: latest
53+
54+
- name: Generate Dockerfile
55+
run: |
56+
thv build --dry-run --output Dockerfile uvx://mcp-server-git
57+
58+
- name: Build multi-arch container
59+
run: |
60+
docker buildx build \
61+
--platform linux/amd64,linux/arm64 \
62+
--tag ghcr.io/myorg/mcp-server:${{ github.ref_name }} \
63+
--push \
64+
.
65+
```
66+
67+
## Supply chain security
68+
69+
Enhance security with SBOM generation, provenance attestation, and image
70+
signing:
71+
72+
```yaml
73+
name: Secure Build
74+
on:
75+
push:
76+
tags: ['v*']
77+
78+
jobs:
79+
build:
80+
runs-on: ubuntu-latest
81+
permissions:
82+
contents: read
83+
packages: write
84+
id-token: write
85+
steps:
86+
- uses: actions/checkout@v4
87+
88+
- name: Install Cosign
89+
uses: sigstore/cosign-installer@v3
90+
91+
- name: Set up Docker Buildx
92+
uses: docker/setup-buildx-action@v3
93+
94+
- name: Install ToolHive
95+
uses: StacklokLabs/toolhive-actions/install@v0
96+
with:
97+
version: latest
98+
99+
- name: Generate Dockerfile
100+
run: |
101+
thv build --dry-run --output Dockerfile uvx://mcp-server-git
102+
103+
- name: Build with security features
104+
uses: docker/build-push-action@v6
105+
id: build
106+
with:
107+
context: .
108+
platforms: linux/amd64,linux/arm64
109+
push: true
110+
tags: ghcr.io/myorg/mcp-server:${{ github.ref_name }}
111+
sbom: true # Generate Software Bill of Materials
112+
provenance: true # Generate build provenance
113+
cache-from: type=gha
114+
cache-to: type=gha,mode=max
115+
116+
- name: Sign container image
117+
env:
118+
DIGEST: ${{ steps.build.outputs.digest }}
119+
run: |
120+
cosign sign --yes ghcr.io/myorg/mcp-server@${DIGEST}
121+
```
122+
123+
## Efficient change detection
124+
125+
Build only when relevant files change to optimize CI/CD performance:
126+
127+
```yaml
128+
name: Conditional Build
129+
on:
130+
push:
131+
branches: [main]
132+
pull_request:
133+
branches: [main]
134+
135+
jobs:
136+
detect-changes:
137+
runs-on: ubuntu-latest
138+
outputs:
139+
build_needed: ${{ steps.changes.outputs.build_needed }}
140+
steps:
141+
- uses: actions/checkout@v4
142+
with:
143+
fetch-depth: 2
144+
145+
- name: Detect changes
146+
id: changes
147+
run: |
148+
# Check if MCP server configs or Dockerfiles changed
149+
if git diff --name-only HEAD~1..HEAD | grep -E "(mcp-configs/|Dockerfile|\.thv)"; then
150+
echo "build_needed=true" >> $GITHUB_OUTPUT
151+
else
152+
echo "build_needed=false" >> $GITHUB_OUTPUT
153+
fi
154+
155+
build:
156+
needs: detect-changes
157+
if: needs.detect-changes.outputs.build_needed == 'true'
158+
runs-on: ubuntu-latest
159+
steps:
160+
- uses: actions/checkout@v4
161+
162+
- name: Install ToolHive
163+
uses: StacklokLabs/toolhive-actions/install@v0
164+
with:
165+
version: latest
166+
167+
- name: Build containers
168+
run: |
169+
thv build --tag ghcr.io/myorg/mcp-server:latest uvx://mcp-server-git
170+
```
171+
172+
## Matrix builds for multiple servers
173+
174+
Build multiple MCP servers in parallel using matrix strategies:
175+
176+
```yaml
177+
name: Matrix Build
178+
on:
179+
push:
180+
tags: ['v*']
181+
182+
jobs:
183+
build:
184+
runs-on: ubuntu-latest
185+
strategy:
186+
matrix:
187+
server:
188+
- name: git-server
189+
scheme: uvx://mcp-server-git
190+
- name: filesystem-server
191+
scheme: npx://@modelcontextprotocol/server-filesystem
192+
- name: custom-server
193+
scheme: go://github.com/myorg/custom-mcp-server@latest
194+
steps:
195+
- uses: actions/checkout@v4
196+
197+
- name: Install ToolHive
198+
uses: StacklokLabs/toolhive-actions/install@v0
199+
with:
200+
version: latest
201+
202+
- name: Build ${{ matrix.server.name }}
203+
run: |
204+
thv build --tag ghcr.io/myorg/${{ matrix.server.name }}:${{ github.ref_name }} \
205+
${{ matrix.server.scheme }}
206+
207+
- name: Push ${{ matrix.server.name }}
208+
run: |
209+
docker push ghcr.io/myorg/${{ matrix.server.name }}:${{ github.ref_name }}
210+
```
211+
212+
## Vulnerability scanning
213+
214+
Integrate security scanning into your build pipeline:
215+
216+
```yaml
217+
name: Secure Build with Scanning
218+
on:
219+
push:
220+
tags: ['v*']
221+
222+
jobs:
223+
build-and-scan:
224+
runs-on: ubuntu-latest
225+
steps:
226+
- uses: actions/checkout@v4
227+
228+
- name: Install ToolHive
229+
uses: StacklokLabs/toolhive-actions/install@v0
230+
with:
231+
version: latest
232+
233+
- name: Build container
234+
run: |
235+
thv build --tag mcp-server:scan uvx://mcp-server-git
236+
237+
- name: Run Trivy vulnerability scanner
238+
uses: aquasecurity/trivy-action@master
239+
with:
240+
image-ref: 'mcp-server:scan'
241+
format: 'sarif'
242+
output: 'trivy-results.sarif'
243+
244+
- name: Upload Trivy scan results
245+
uses: github/codeql-action/upload-sarif@v3
246+
if: always()
247+
with:
248+
sarif_file: 'trivy-results.sarif'
249+
250+
- name: Tag and push if scan passes
251+
run: |
252+
docker tag mcp-server:scan ghcr.io/myorg/mcp-server:${{ github.ref_name }}
253+
docker push ghcr.io/myorg/mcp-server:${{ github.ref_name }}
254+
```
255+
256+
## GitLab CI example
257+
258+
For GitLab CI users, here's an equivalent pipeline:
259+
260+
```yaml
261+
# .gitlab-ci.yml
262+
stages:
263+
- build
264+
- security
265+
- deploy
266+
267+
variables:
268+
DOCKER_DRIVER: overlay2
269+
DOCKER_TLS_CERTDIR: '/certs'
270+
271+
build:
272+
stage: build
273+
image: docker:latest
274+
services:
275+
- docker:dind
276+
before_script:
277+
# Install ToolHive CLI using curl and jq to get the latest version
278+
- |
279+
VERSION=$(curl -s https://api.github.com/repos/stacklok/toolhive/releases/latest | jq -r .tag_name)
280+
wget "https://github.com/stacklok/toolhive/releases/download/${VERSION}/toolhive_${VERSION#v}_linux_amd64.tar.gz"
281+
tar -xzf "toolhive_${VERSION#v}_linux_amd64.tar.gz"
282+
install -m 0755 thv /usr/local/bin/
283+
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
284+
script:
285+
- thv build --tag $CI_REGISTRY_IMAGE/mcp-server:$CI_COMMIT_TAG
286+
uvx://mcp-server-git
287+
- docker push $CI_REGISTRY_IMAGE/mcp-server:$CI_COMMIT_TAG
288+
only:
289+
- tags
290+
291+
security_scan:
292+
stage: security
293+
image: aquasec/trivy:latest
294+
script:
295+
- trivy image --exit-code 1 --severity HIGH,CRITICAL
296+
$CI_REGISTRY_IMAGE/mcp-server:$CI_COMMIT_TAG
297+
only:
298+
- tags
299+
```
300+
301+
## Best practices
302+
303+
When implementing advanced CI/CD patterns:
304+
305+
1. **Use specific tags** instead of `latest` for production deployments
306+
2. **Implement proper caching** to speed up builds
307+
3. **Scan for vulnerabilities** before pushing to production registries
308+
4. **Sign images** for supply chain security
309+
5. **Use matrix builds** for multiple MCP servers
310+
6. **Implement change detection** to avoid unnecessary builds
311+
7. **Store sensitive data** in CI/CD secrets, not in code
312+
313+
## Related information
314+
315+
- [Build MCP server containers](./build-containers.mdx)
316+
- [Run MCP servers in Kubernetes](../guides-k8s/run-mcp-k8s.md)
317+
- [`thv build` command reference](../reference/cli/thv_build.md)
318+
- [Secrets management](./secrets-management.mdx)

0 commit comments

Comments
 (0)