buildmymcpserver/apps/web/Dockerfile
Marco Sadjadi cf423de3d5
All checks were successful
Deploy to Production / deploy (push) Successful in 1m22s
@
feat(billing): in-app embedded Stripe checkout + webhook hardening

Checkout previously used hosted ui_mode → window.location to checkout.stripe.com,
which pops out of the installed PWA into the system browser. Switch to embedded:

- API: ui_mode embedded_page (stripe-node v22 / API 2025-10 renamed the enum),
  return_url instead of success/cancel_url, returns client_secret.
- web: @stripe/react-stripe-js EmbeddedCheckout mounted in an in-app modal;
  NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY baked at build (Dockerfile arg + compose arg).
- .env.production.example: full Stripe section (was missing) + admin-email
  placeholder (INF-001).

Also bundled (same files): BILL-002 invoice.paid resets quota only on
subscription_cycle; BILL-003 webhook dedup rolled back on handler failure;
BILL-001 change-plan writes plan locally; BILL-004 webhook cross-checks
sub.customer before trusting metadata.orgId; INF-003 API routed off the raw
docker.sock through a locked-down tecnativa/docker-socket-proxy (CONTAINERS+POST).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@
2026-05-29 20:56:40 +02:00

48 lines
1.9 KiB
Docker

# syntax=docker/dockerfile:1
# Web app (Next.js 15). NEXT_PUBLIC_API_URL is inlined into the client bundle at
# BUILD time — it must be passed as a build arg, not just a runtime env var.
# Build context must be the repo root: docker build -f apps/web/Dockerfile .
FROM node:20-alpine AS base
RUN corepack enable && corepack prepare pnpm@9.12.0 --activate
WORKDIR /app
# ---- deps ----
FROM base AS deps
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY apps/api/package.json apps/api/
COPY apps/web/package.json apps/web/
COPY apps/generator/package.json apps/generator/
COPY apps/runner-template/package.json apps/runner-template/
COPY packages/auth/package.json packages/auth/
COPY packages/db/package.json packages/db/
COPY packages/llm/package.json packages/llm/
COPY packages/types/package.json packages/types/
RUN pnpm install --frozen-lockfile
# ---- build ----
FROM deps AS build
ARG NEXT_PUBLIC_API_URL=http://localhost:4000
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
# Stripe publishable key — inlined into the client bundle so the embedded
# checkout can initialise. Safe to expose (publishable, not secret). Empty
# build = embedded checkout shows a "not configured" message until set.
ARG NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
ENV NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=$NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
ENV NEXT_TELEMETRY_DISABLED=1
COPY . .
RUN pnpm --filter @bmm/web build
# ---- runtime ----
FROM build AS runtime
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
WORKDIR /app/apps/web
EXPOSE 3001
# NOTE (INF-003): non-root `USER node` was reverted — `pnpm start` via corepack
# can't reach its root-owned cache as the node user and the deploy health-check
# doesn't cover web, so a broken web would deploy "green" but take the site down.
# Re-enable only after switching the runtime CMD to invoke next directly
# (node_modules/.bin/next) and smoke-testing the image locally.
CMD ["pnpm", "start"]