This document provides information about the Docker setup and GitHub Container Registry publishing for linkwarden-mcp-server.
The linkwarden-mcp-server is now available as a Docker image published to GitHub Container Registry (GHCR). This makes it easy for users to run the MCP server without needing to build from source.
Location: Dockerfile
A multi-stage Dockerfile that:
- Stage 1 (Builder): Uses
golang:1.23.2-alpineto build the binary- Installs build dependencies (make, bash, git, oapi-codegen)
- Generates SDK from OpenAPI specification
- Builds a static binary with optimizations
- Stage 2 (Final): Uses
alpine:latestfor minimal image size- Installs ca-certificates for HTTPS
- Creates non-root user for security
- Sets up environment variables
- Configures entrypoint for stdio communication
Image Size: Approximately 20-30 MB (final Alpine image with binary)
Location: .dockerignore
Optimizes Docker build context by excluding:
- Build artifacts (bin/, *.log)
- Git and GitHub files
- Documentation files
- Environment files
- IDE files
- macOS files
Location: .github/workflows/docker-publish.yml
Automates Docker image building and publishing with:
- Triggers:
- Push to
mainbranch (after PR merge) - Git tags matching
v*.*.*pattern
- Push to
- Features:
- Multi-platform builds (linux/amd64, linux/arm64)
- Automatic semantic versioning
- GitHub Container Registry publishing
- Build caching for faster builds
- Permissions:
- Read repository contents
- Write to GitHub packages
Location: README.md
Added comprehensive Docker usage instructions:
- Installation section with Docker as recommended method
- Usage examples for Claude Desktop
- Usage examples for Claude Code
- Generic MCP client usage
- Tag versioning explanation
# Latest version
docker pull ghcr.io/irfansofyana/linkwarden-mcp-server:latest
# Specific version
docker pull ghcr.io/irfansofyana/linkwarden-mcp-server:1.0.0docker run --rm -i \
-e LINKWARDEN_BASE_URL="https://your-linkwarden-instance.com" \
-e LINKWARDEN_TOKEN="your-api-token-here" \
ghcr.io/irfansofyana/linkwarden-mcp-server:latestdocker run --rm -i \
-e LINKWARDEN_BASE_URL="https://your-linkwarden-instance.com" \
-e LINKWARDEN_TOKEN="your-api-token-here" \
-e TOOLSETS="search,collection,link" \
-e READ_ONLY="true" \
ghcr.io/irfansofyana/linkwarden-mcp-server:latestTo build the Docker image locally:
# Build for your platform
docker build -t linkwarden-mcp-server:local .
# Build for multiple platforms
docker buildx build --platform linux/amd64,linux/arm64 -t linkwarden-mcp-server:local .The workflow automatically triggers when:
-
Push to main branch:
git push origin main
- Creates image tagged as
latest - Creates image tagged with
main-<sha>
- Creates image tagged as
-
Create a version tag:
git tag v1.0.0 git push origin v1.0.0
- Creates images with tags:
v1.0.0,1.0.0,1.0,1
- Creates images with tags:
The workflow follows semantic versioning (semver):
- Major version tag (e.g.,
v1.0.0→1): Always points to latest major version - Minor version tag (e.g.,
v1.0.0→1.0): Always points to latest minor version - Patch version tag (e.g.,
v1.0.0→1.0.0): Specific version - With 'v' prefix (e.g.,
v1.0.0): Alternative format with prefix
- Go to your GitHub repository
- Navigate to "Actions" tab
- Find "Build and Push Docker Image" workflow
- View build logs and status
Images are published to:
ghcr.io/irfansofyana/linkwarden-mcp-server
View published images at:
https://github.com/irfansofyana/linkwarden-mcp-server/pkgs/container/linkwarden-mcp-server
The Docker image accepts these environment variables:
| Variable | Required | Description | Default |
|---|---|---|---|
LINKWARDEN_BASE_URL |
Yes | Linkwarden instance URL | - |
LINKWARDEN_TOKEN |
Yes | API authentication token | - |
TOOLSETS |
No | Comma-separated toolsets to enable | all |
READ_ONLY |
No | Enable read-only mode | false |
LOG_FILE |
No | Path to log file | - |
- Non-root User: The container runs as user
mcpserver(UID 1000) for security - Static Binary: CGO is disabled for a fully static binary
- Minimal Base Image: Alpine Linux for reduced attack surface
- No Secrets in Image: Secrets are passed via environment variables at runtime
- HTTPS Support: ca-certificates included for secure API communication
If the GitHub Actions build fails:
- Check the workflow logs in the Actions tab
- Verify the Dockerfile builds locally:
docker build -t test .
- Check that SDK generation works:
make generate-sdk
If you can't pull the image:
- Ensure the image is public in GitHub package settings
- Try authenticating with GitHub:
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
The container is designed for stdio communication. It will exit if not connected to an MCP client. This is expected behavior.
- Test locally: Build and test the Docker image locally
- Push to GitHub: Commit and push the changes
- Create a release: Tag a version to trigger the workflow
- Verify publication: Check that the image is published to GHCR
- Update clients: Update your MCP client configurations to use the Docker image
graph LR
A[Push to main] --> B[GitHub Actions]
C[Push tag v*.*.] --> B
B --> D[Build Docker Image]
D --> E[Multi-platform Build]
E --> F[Push to GHCR]
F --> G[Tag with semver]
# 1. Commit all changes
git add .
git commit -m "Add Docker support and GitHub Actions"
# 2. Push to main
git push origin main
# 3. Wait for workflow to complete (check Actions tab)
# 4. Create and push a version tag
git tag v1.0.0
git push origin v1.0.0
# 5. Check GHCR for published images
# Visit: https://github.com/irfansofyana?tab=packages