Compare commits

..

2 Commits

Author SHA1 Message Date
7716e424f9 Merge pull request 'feat(gitea): rebuild gitea-mcp on a shell-bearing base' (#122) from feat/gitea-mcp-shell-base into main
Some checks failed
CI/CD / lint (push) Successful in 1m14s
CI/CD / test (push) Successful in 1m26s
CI/CD / typecheck (push) Successful in 2m48s
CI/CD / smoke (push) Failing after 3m7s
CI/CD / build (push) Successful in 2m12s
CI/CD / publish (push) Has been skipped
2026-08-21 10:16:28 +00:00
Michal
f097c0f4d5 feat(gitea): rebuild gitea-mcp on a shell-bearing base
Some checks failed
CI/CD / lint (pull_request) Successful in 1m20s
CI/CD / test (pull_request) Successful in 1m30s
CI/CD / typecheck (pull_request) Successful in 2m52s
CI/CD / smoke (pull_request) Failing after 2m1s
CI/CD / build (pull_request) Successful in 2m23s
CI/CD / publish (pull_request) Has been skipped
Upstream docker.gitea.com/gitea-mcp-server is distroless — `Cmd` is
["/app/gitea-mcp"] and there is no /bin/sh at any path (verified by
exec'ing every candidate against the running pod).

That is fine until the server wants secretDelivery: injector. The OpenBao
agent renders secrets to a FILE, so mcpd wraps the container command as
`sh -c '. /vault/secrets/<name>; exec "$0" "$@"'`, which needs a shell.
gitea was the only server in the fleet blocked on this, and so the only
one whose token had to stay inline in its pod spec.

Copying one static Go binary onto debian:stable-slim is cheaper than
building and maintaining a static envexec shim, and follows the precedent
in deploy/Dockerfile.docmost-mcp — this repo already rebuilds third-party
MCP servers when it needs to change how they run.

ca-certificates is required rather than incidental: the binary talks HTTPS
to mysources.co.uk and the distroless base shipped a trust store we are
leaving behind. Verified in the built image: shell present, binary runs,
ca-certificates.crt present.

ENTRYPOINT is kept so the plain (non-injected) path behaves exactly like
upstream; mcpd replaces it with the sourcing wrapper only when the server
opts in.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018vybEitX4FykeMatKe5Xki
2026-08-21 11:16:23 +01:00
2 changed files with 72 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
# gitea-mcp-server, rebuilt on a shell-bearing base.
#
# WHY THIS EXISTS
# ---------------
# Upstream `docker.gitea.com/gitea-mcp-server` is distroless: `Cmd` is
# ["/app/gitea-mcp"] and there is no /bin/sh at any path (verified by exec'ing
# every candidate against the running pod).
#
# That is fine until the server needs `secretDelivery: injector`. The OpenBao
# agent renders secrets to a FILE, so mcpd wraps the container command as
# `sh -c '. /vault/secrets/<name>; exec "$0" "$@"'` — which needs a shell. With
# no shell the pod cannot source its own credentials, and gitea was the single
# server in the fleet blocked on this.
#
# Copying one static Go binary onto debian:stable-slim is cheaper than building
# and maintaining a static "envexec" shim, and follows the precedent already set
# by deploy/Dockerfile.docmost-mcp — this repo already rebuilds third-party MCP
# servers when it needs to change how they run.
#
# ca-certificates is required, not incidental: the binary talks HTTPS to
# https://mysources.co.uk and a distroless base ships its own trust store which
# we are leaving behind.
FROM debian:stable-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY --from=docker.gitea.com/gitea-mcp-server:latest /app/gitea-mcp /usr/local/bin/gitea-mcp
WORKDIR /app
# Kept as ENTRYPOINT so the plain (non-injected) path behaves exactly like
# upstream. mcpd REPLACES this with the sourcing wrapper when the server opts
# into injected delivery — that is why a shell has to exist in the image.
ENTRYPOINT ["/usr/local/bin/gitea-mcp"]

36
scripts/build-gitea-mcp.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/bash
# Build gitea-mcp Docker image and push to Gitea container registry
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_ROOT"
# Load .env for GITEA_TOKEN
if [ -f .env ]; then
set -a; source .env; set +a
fi
# Push directly to internal address (external proxy has body size limit)
REGISTRY="10.0.0.194:3012"
IMAGE="gitea-mcp"
TAG="${1:-latest}"
echo "==> Building gitea-mcp image..."
podman build -t "$IMAGE:$TAG" -f deploy/Dockerfile.gitea-mcp .
echo "==> Tagging as $REGISTRY/michal/$IMAGE:$TAG..."
podman tag "$IMAGE:$TAG" "$REGISTRY/michal/$IMAGE:$TAG"
echo "==> Logging in to $REGISTRY..."
podman login --tls-verify=false -u michal -p "$GITEA_TOKEN" "$REGISTRY"
echo "==> Pushing to $REGISTRY/michal/$IMAGE:$TAG..."
podman push --tls-verify=false "$REGISTRY/michal/$IMAGE:$TAG"
# Ensure package is linked to the repository
source "$SCRIPT_DIR/link-package.sh"
link_package "container" "$IMAGE"
echo "==> Done!"
echo " Image: $REGISTRY/michal/$IMAGE:$TAG"