From 85bf96cb35a0aa28e2197dcc14ebe556bc5b4edf Mon Sep 17 00:00:00 2001 From: Rene Leonhardt <65483435+reneleonhardt@users.noreply.github.com> Date: Mon, 22 Sep 2025 07:59:46 +0200 Subject: [PATCH] feat: docker image respects shutdown signals (#98) ### Features - Docker image respects shutdown signals - Improve Docker build and metadata --- .dockerignore | 8 ++++++++ .github/workflows/cd.yaml | 28 ++++++++++++++++------------ Dockerfile | 12 ++++++++---- README.md | 4 ++-- 4 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0d149f1 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +# Exclude everything +* + +# Include required files only +!/src/ +!pyproject.toml +!uv.lock +!LICENSE \ No newline at end of file diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 3d28f62..3e435c1 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -37,15 +37,18 @@ jobs: id: meta uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 with: - images: ${{ github.repository }} + images: sparfenyuk/mcp-proxy tags: | type=sha,format=short,prefix=commit- type=ref,event=tag labels: | - maintainer="Sergey Parfenyuk" + org.opencontainers.image.authors=Sergey Parfenyuk org.opencontainers.image.source=https://github.com/sparfenyuk/mcp-proxy - org.opencontainers.image.description="Connect to MCP servers that run on SSE transport, or expose stdio servers as an SSE server using the MCP Proxy server." + org.opencontainers.image.url=https://github.com/sparfenyuk/mcp-proxy + org.opencontainers.image.title=mcp-proxy + org.opencontainers.image.description=Connect to MCP servers that run on SSE transport, or expose stdio servers as an SSE server using the MCP Proxy server. org.opencontainers.image.licenses=MIT + org.opencontainers.image.base.name=docker.io/library/python:3.13-alpine - name: Log in to Docker Hub uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 @@ -60,9 +63,8 @@ jobs: context: . platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - annotations: ${{ steps.meta.outputs.annotations }} + build-args: | + DOCKER_METADATA_OUTPUT_JSON cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache @@ -91,15 +93,18 @@ jobs: id: meta uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0 with: - images: ghcr.io/${{ github.repository }} + images: ghcr.io/sparfenyuk/mcp-proxy tags: | type=sha,format=short,prefix=commit- type=ref,event=tag labels: | - maintainer="Sergey Parfenyuk" + org.opencontainers.image.authors=Sergey Parfenyuk org.opencontainers.image.source=https://github.com/sparfenyuk/mcp-proxy - org.opencontainers.image.description="Connect to MCP servers that run on SSE transport, or expose stdio servers as an SSE server using the MCP Proxy server." + org.opencontainers.image.url=https://github.com/sparfenyuk/mcp-proxy + org.opencontainers.image.title=mcp-proxy + org.opencontainers.image.description=Connect to MCP servers that run on SSE transport, or expose stdio servers as an SSE server using the MCP Proxy server. org.opencontainers.image.licenses=MIT + org.opencontainers.image.base.name=docker.io/library/python:3.13-alpine - name: Log in to GHCR uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 @@ -115,9 +120,8 @@ jobs: context: . platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - annotations: ${{ steps.meta.outputs.annotations }} + build-args: | + DOCKER_METADATA_OUTPUT_JSON cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache diff --git a/Dockerfile b/Dockerfile index ff2bcdb..3726045 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,10 +5,10 @@ FROM ghcr.io/astral-sh/uv:python3.12-alpine AS uv WORKDIR /app # Enable bytecode compilation -ENV UV_COMPILE_BYTECODE=1 +ARG UV_COMPILE_BYTECODE=1 # Copy from the cache instead of linking since it's a mounted volume -ENV UV_LINK_MODE=copy +ARG UV_LINK_MODE=copy # Install the project's dependencies using the lockfile and settings RUN --mount=type=cache,target=/root/.cache/uv \ @@ -18,16 +18,20 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Then, add the rest of the project source code and install it # Installing separately from its dependencies allows optimal layer caching -ADD . /app +COPY . /app RUN --mount=type=cache,target=/root/.cache/uv \ uv sync --frozen --no-dev --no-editable +RUN apk add --update --no-cache catatonit + # Final stage with explicit platform specification FROM python:3.12-alpine COPY --from=uv --chown=app:app /app/.venv /app/.venv +COPY --from=uv /usr/bin/catatonit /usr/bin/ +COPY --from=uv /usr/libexec/podman/catatonit /usr/libexec/podman/ # Place executables in the environment at the front of the path ENV PATH="/app/.venv/bin:$PATH" -ENTRYPOINT ["mcp-proxy"] +ENTRYPOINT ["catatonit", "--", "mcp-proxy"] diff --git a/README.md b/README.md index 43a995c..1aeadad 100644 --- a/README.md +++ b/README.md @@ -254,7 +254,7 @@ uv tool install git+https://github.com/sparfenyuk/mcp-proxy Starting from version 0.3.2, it's possible to pull and run the corresponding container image: ```bash -docker run -t ghcr.io/sparfenyuk/mcp-proxy:v0.3.2-alpine --help +docker run --rm -t ghcr.io/sparfenyuk/mcp-proxy:v0.3.2-alpine --help ``` ### Troubleshooting @@ -288,7 +288,7 @@ RUN python3 -m ensurepip && pip install --no-cache-dir uv ENV PATH="/usr/local/bin:$PATH" \ UV_PYTHON_PREFERENCE=only-system -ENTRYPOINT [ "mcp-proxy" ] +ENTRYPOINT ["catatonit", "--", "mcp-proxy"] ``` ## Docker Compose Setup