From c16d7964c9dc2ba1e9b23a427a5ebc7e2bb27ced Mon Sep 17 00:00:00 2001 From: Michal Date: Fri, 21 Aug 2026 17:07:23 +0100 Subject: [PATCH] fix(gitea): pin the rebuilt image by digest and match upstream's CMD form MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two corrections to the shell-bearing rebuild. **Pin by digest.** It copied from `:latest`, so a rebuild silently ships whatever upstream has moved to. When a probe started failing right after a rebuild I could not tell a version change from a broken build, and burned time on the wrong one — the binary's own `--version` prints 1.1.0 while the image label says 1.6.0, so that was a red herring too. Now pinned to sha256:dda8d56e…, which IS the running 1.6.0. **CMD, not ENTRYPOINT.** Upstream sets `Cmd: ["/app/gitea-mcp"]` with no entrypoint. mcpd maps a server's `command` to k8s `args`, which REPLACES Cmd but only APPENDS to an ENTRYPOINT — so the ENTRYPOINT form would have changed how the binary is invoked for any server that sets a command. Matching upstream's shape keeps the non-injected path byte-identical. gitea also needs `entrypoint` on its server row: its `command` is [], so there is nothing for the injector wrapper to wrap without it. Set to ["/usr/local/bin/gitea-mcp"] via apply -f (patch cannot express an array). Verified live: gitea RUNNING/healthy on secretDelivery: injector, with vault-agent-init present and the command wrapped as ["/bin/sh","-c",". /vault/secrets/gitea-creds; exec \"$0\" \"$@\"", "/usr/local/bin/gitea-mcp"] `get_me` — which needs read:user, the scope that started this whole session — returns the real account. Plaintext credentials across all mcpctl server pod specs: 4 -> 0. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_018vybEitX4FykeMatKe5Xki --- deploy/Dockerfile.gitea-mcp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/deploy/Dockerfile.gitea-mcp b/deploy/Dockerfile.gitea-mcp index 3c6aad0..758f67a 100644 --- a/deploy/Dockerfile.gitea-mcp +++ b/deploy/Dockerfile.gitea-mcp @@ -26,11 +26,18 @@ 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 +# Pinned by DIGEST, not :latest. `latest` moves, and a rebuild that silently +# ships a different server version is indistinguishable from a broken rebuild — +# chased exactly that here when a probe started failing after a rebuild. +# This digest is gitea-mcp-server 1.6.0 (label org.opencontainers.image.version), +# the build that was running when this image was introduced. +# To bump: skopeo inspect docker://docker.gitea.com/gitea-mcp-server:latest +COPY --from=docker.gitea.com/gitea-mcp-server@sha256:dda8d56e6a91fa89cad186becc27c7aa83d74acdd5dc69f89af840d7bb78a631 /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"] +# CMD, not ENTRYPOINT — matching upstream, which sets Cmd ["/app/gitea-mcp"] and +# no entrypoint. mcpd maps a server's `command` to k8s `args`, which REPLACES +# Cmd but only appends to an ENTRYPOINT; keeping the same form means the plain +# (non-injected) path behaves byte-identically to upstream. +CMD ["/usr/local/bin/gitea-mcp"] -- 2.49.1