Skip to content

Commit 39caed8

Browse files
committed
Add Docker deployment support with GitHub Container Registry
## Docker Infrastructure - Added multi-stage Dockerfile with Python 3.10 Alpine base - Optimized for security with non-root user - Multi-platform support (linux/amd64, linux/arm64) - Minimal image size using Alpine Linux ## Files Added - `Dockerfile`: Multi-stage build for production-ready image - `.dockerignore`: Excludes unnecessary files from build context - `docker-compose.yml`: Local development and testing setup - `.github/workflows/docker-publish.yml`: Automated image publishing to GHCR ## Documentation Updates ### README.md - Added "Docker Deployment" section - Pre-built image usage instructions - Claude Desktop integration with Docker - Benefits of Docker deployment ### USAGE.md - Comprehensive Docker deployment guide - Quick start with pre-built images - Local build instructions - Docker Compose usage - Claude Desktop configuration examples (basic and with autoapprove) - Troubleshooting section for common Docker issues - Image details and specifications ## GitHub Actions Workflow - Publishes to GitHub Container Registry (ghcr.io) - Triggered on: push to main, version tags (v*.*.*), PRs, manual dispatch - Multi-architecture builds: amd64 and arm64 - Layer caching for faster builds - Semantic versioning support - Automatic 'latest' tag on main branch ## Usage Users can now run the server with: ```bash docker pull ghcr.io/sperekrestova/github-mcp-server:latest docker run -i --rm -e GITHUB_TOKEN=xxx ghcr.io/sperekrestova/github-mcp-server:latest ``` Or configure Claude Desktop with Docker instead of Python.
1 parent 5f915a4 commit 39caed8

File tree

6 files changed

+460
-2
lines changed

6 files changed

+460
-2
lines changed

.dockerignore

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
23+
# Virtual environments
24+
venv/
25+
env/
26+
ENV/
27+
.venv
28+
29+
# Environment files
30+
.env
31+
.env.local
32+
.env.*.local
33+
34+
# Testing
35+
.pytest_cache/
36+
.coverage
37+
htmlcov/
38+
.tox/
39+
.hypothesis/
40+
41+
# IDE
42+
.vscode/
43+
.idea/
44+
*.swp
45+
*.swo
46+
*~
47+
.DS_Store
48+
49+
# Git
50+
.git/
51+
.gitignore
52+
.gitattributes
53+
54+
# Documentation (not needed in image)
55+
*.md
56+
LICENSE
57+
CODEOWNERS
58+
59+
# CI/CD
60+
.github/
61+
62+
# Docker
63+
Dockerfile*
64+
docker-compose*.yml
65+
.dockerignore
66+
67+
# Logs
68+
*.log
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: Docker Build and Publish
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- 'v*.*.*'
9+
pull_request:
10+
branches:
11+
- main
12+
workflow_dispatch:
13+
14+
env:
15+
REGISTRY: ghcr.io
16+
IMAGE_NAME: ${{ github.repository }}
17+
18+
jobs:
19+
build-and-push:
20+
runs-on: ubuntu-latest
21+
permissions:
22+
contents: read
23+
packages: write
24+
id-token: write
25+
26+
steps:
27+
- name: Checkout repository
28+
uses: actions/checkout@v4
29+
30+
- name: Set up QEMU
31+
uses: docker/setup-qemu-action@v3
32+
33+
- name: Set up Docker Buildx
34+
uses: docker/setup-buildx-action@v3
35+
36+
- name: Log into registry ${{ env.REGISTRY }}
37+
if: github.event_name != 'pull_request'
38+
uses: docker/login-action@v3
39+
with:
40+
registry: ${{ env.REGISTRY }}
41+
username: ${{ github.actor }}
42+
password: ${{ secrets.GITHUB_TOKEN }}
43+
44+
- name: Extract Docker metadata
45+
id: meta
46+
uses: docker/metadata-action@v5
47+
with:
48+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
49+
tags: |
50+
type=ref,event=branch
51+
type=ref,event=pr
52+
type=semver,pattern={{version}}
53+
type=semver,pattern={{major}}.{{minor}}
54+
type=semver,pattern={{major}}
55+
type=raw,value=latest,enable={{is_default_branch}}
56+
57+
- name: Build and push Docker image
58+
id: build-and-push
59+
uses: docker/build-push-action@v5
60+
with:
61+
context: .
62+
platforms: linux/amd64,linux/arm64
63+
push: ${{ github.event_name != 'pull_request' }}
64+
tags: ${{ steps.meta.outputs.tags }}
65+
labels: ${{ steps.meta.outputs.labels }}
66+
cache-from: type=gha
67+
cache-to: type=gha,mode=max

Dockerfile

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Multi-stage build for GitHub MCP Server
2+
# Stage 1: Builder - Install dependencies
3+
FROM python:3.10-alpine AS builder
4+
5+
# Install build dependencies
6+
RUN apk add --no-cache gcc musl-dev libffi-dev
7+
8+
WORKDIR /app
9+
10+
# Copy requirements and install dependencies
11+
COPY requirements.txt .
12+
RUN pip install --no-cache-dir --user -r requirements.txt
13+
14+
# Stage 2: Runtime - Minimal image
15+
FROM python:3.10-alpine
16+
17+
# Create a non-root user 'app'
18+
RUN adduser -D -h /home/app -s /bin/sh app
19+
20+
WORKDIR /app
21+
22+
# Copy installed packages from builder
23+
COPY --from=builder --chown=app:app /root/.local /home/app/.local
24+
25+
# Copy application code
26+
COPY --chown=app:app main.py .
27+
28+
# Switch to non-root user
29+
USER app
30+
31+
# Add local packages to PATH
32+
ENV PATH="/home/app/.local/bin:$PATH"
33+
ENV PYTHONUNBUFFERED=1
34+
35+
# Run the MCP server
36+
ENTRYPOINT ["python", "main.py"]

README.md

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,69 @@ Get file content directly via URI.
107107
content://anthropics/anthropic-sdk-python/doc/README.md
108108
```
109109

110-
## Claude Desktop Integration
110+
## Docker Deployment
111+
112+
### Using Pre-built Docker Image
113+
114+
Pull the latest image from GitHub Container Registry:
115+
116+
```bash
117+
docker pull ghcr.io/sperekrestova/github-mcp-server:latest
118+
```
119+
120+
### Building Docker Image Locally
121+
122+
```bash
123+
# Build the image
124+
docker build -t github-mcp-server .
125+
126+
# Or use docker-compose
127+
docker-compose build
128+
```
129+
130+
### Running with Docker
131+
132+
```bash
133+
# Run interactively
134+
docker run -i --rm \
135+
-e GITHUB_TOKEN=ghp_your_token_here \
136+
ghcr.io/sperekrestova/github-mcp-server:latest
137+
138+
# Or use docker-compose
139+
GITHUB_TOKEN=ghp_your_token_here docker-compose up
140+
```
141+
142+
### Claude Desktop Integration with Docker
143+
144+
Add this configuration to your `claude_desktop_config.json`:
145+
146+
```json
147+
{
148+
"mcpServers": {
149+
"github-docs": {
150+
"command": "docker",
151+
"args": [
152+
"run",
153+
"-i",
154+
"--rm",
155+
"-e", "GITHUB_TOKEN",
156+
"ghcr.io/sperekrestova/github-mcp-server:latest"
157+
],
158+
"env": {
159+
"GITHUB_TOKEN": "ghp_your_token_here"
160+
}
161+
}
162+
}
163+
}
164+
```
165+
166+
**Benefits of Docker deployment:**
167+
- No Python installation required
168+
- Consistent environment across platforms
169+
- Easy updates (`docker pull`)
170+
- Isolated dependencies
171+
172+
## Claude Desktop Integration (Python)
111173

112174
Add to your `claude_desktop_config.json`:
113175

0 commit comments

Comments
 (0)