From cc6effa5d4d246b11de1fef70375241a32ff3f3b Mon Sep 17 00:00:00 2001 From: Yao Date: Wed, 17 Jun 2026 14:50:01 +1000 Subject: [PATCH] ci: build + publish the product MCP server image Adds apps/mcp/Dockerfile (bundles the guest MCP-App + tsc the server) and restructures the publish workflow into a matrix that publishes both ghcr.io/blueprintlabio/tidebase and tidebase-mcp (amd64-native). Dockerfile validated locally (image boots, /health + resources/list OK). Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/publish-image.yml | 26 +++++++++++++++----------- apps/mcp/Dockerfile | 25 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 apps/mcp/Dockerfile diff --git a/.github/workflows/publish-image.yml b/.github/workflows/publish-image.yml index a7bc20b..9531288 100644 --- a/.github/workflows/publish-image.yml +++ b/.github/workflows/publish-image.yml @@ -1,4 +1,4 @@ -name: Publish server image +name: Publish images on: push: @@ -13,11 +13,17 @@ permissions: jobs: publish: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - image: tidebase + dockerfile: apps/server/Dockerfile + - image: tidebase-mcp + dockerfile: apps/mcp/Dockerfile steps: - uses: actions/checkout@v4 - - uses: docker/setup-qemu-action@v3 - - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 @@ -29,7 +35,7 @@ jobs: - uses: docker/metadata-action@v5 id: meta with: - images: ghcr.io/blueprintlabio/tidebase + images: ghcr.io/blueprintlabio/${{ matrix.image }} tags: | type=ref,event=tag type=raw,value=latest,enable={{is_default_branch}} @@ -38,14 +44,12 @@ jobs: - uses: docker/build-push-action@v6 with: context: . - file: apps/server/Dockerfile - # amd64 only: matches the deployment target (Coolify host) and builds - # natively on the GitHub runner. The linux/arm64 leg required QEMU - # emulation that, on a lockfile cache-miss, took 40+ min; re-add it with - # a dedicated arm64 runner or warmed cache if arm64 images are needed. + file: ${{ matrix.dockerfile }} + # amd64 only: matches the deploy target (Coolify host) and builds + # natively on the GitHub runner. Native arm64 is added separately. platforms: linux/amd64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max + cache-from: type=gha,scope=${{ matrix.image }} + cache-to: type=gha,mode=max,scope=${{ matrix.image }} diff --git a/apps/mcp/Dockerfile b/apps/mcp/Dockerfile new file mode 100644 index 0000000..377384b --- /dev/null +++ b/apps/mcp/Dockerfile @@ -0,0 +1,25 @@ +# Tidebase product MCP server image. Build context must be the repo root: +# docker build -f apps/mcp/Dockerfile -t tidebase-mcp . +# Reaches the Tidebase server via TIDEBASE_URL / TIDEBASE_API_KEY at runtime. +FROM node:22-alpine AS build +RUN corepack enable +WORKDIR /repo +COPY pnpm-workspace.yaml pnpm-lock.yaml package.json tsconfig.base.json ./ +COPY packages/sdk/package.json packages/sdk/package.json +COPY apps/mcp/package.json apps/mcp/package.json +RUN pnpm install --frozen-lockfile --filter @tidebase/mcp-server +COPY apps/mcp apps/mcp +# build = bundle the guest MCP-App (esbuild) into a string + tsc the server +RUN pnpm --filter @tidebase/mcp-server build + +FROM node:22-alpine +ENV NODE_ENV=production +WORKDIR /app +COPY --from=build /repo/apps/mcp/dist apps/mcp/dist +# Runtime needs only hono + @mcp-ui/server (createUIResource); the guest app SDK +# is bundled into the resource HTML at build time, so it is not a runtime dep. +RUN printf '{"name":"tidebase-mcp","private":true,"type":"module"}' > apps/mcp/package.json \ + && cd apps/mcp && npm install --omit=dev --no-audit --no-fund \ + hono@^4.6.16 @hono/node-server@^1.13.8 @mcp-ui/server@^6.1.0 +EXPOSE 7377 +CMD ["node", "apps/mcp/dist/index.js"]