fix(devtools): stabilize Penpot MCP, fix S3 creds, OIDC registration
MCP server: - Replace vite build --watch + livePreview with static vite preview (watch mode was reloading the plugin iframe, killing WebSocket) - Bake WS_URI at Docker build time for production WebSocket URL - Add server-side application-level keepalive messages every 25s - Add client-side auto-reconnect with exponential backoff - Set Pingora route timeout to 86400s for WebSocket idle tolerance Penpot: - Add AWS_ACCESS_KEY_ID/SECRET env vars for S3 SDK compatibility - Set S3 region to satisfy AWS SDK credential chain - Enable OIDC registration (disable-registration blocks OIDC signup) - Fix frontend port (8080 not 80) - Add penpot bucket to seaweedfs-buckets init job
This commit is contained in:
@@ -46,6 +46,8 @@ spec:
|
||||
- CREATE DATABASE find_db OWNER find;
|
||||
- CREATE USER penpot WITH LOGIN;
|
||||
- CREATE DATABASE penpot_db OWNER penpot;
|
||||
- CREATE USER stalwart WITH LOGIN;
|
||||
- CREATE DATABASE stalwart_db OWNER stalwart;
|
||||
|
||||
storage:
|
||||
size: 10Gi
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
FROM node:22-alpine
|
||||
RUN npm install -g pnpm@latest @penpot/mcp@latest && \
|
||||
cd /usr/local/lib/node_modules/@penpot/mcp && \
|
||||
pnpm -r install && \
|
||||
pnpm run build
|
||||
ARG WS_URI=wss://mcp-designer.sunbeam.pt/ws
|
||||
RUN npm install -g pnpm@latest
|
||||
COPY . /opt/penpot-mcp/
|
||||
WORKDIR /opt/penpot-mcp
|
||||
RUN WS_URI=$WS_URI pnpm -r install && WS_URI=$WS_URI pnpm run build
|
||||
ENV PENPOT_MCP_REMOTE_MODE=true \
|
||||
PENPOT_MCP_SERVER_HOST=0.0.0.0 \
|
||||
PENPOT_MCP_SERVER_PORT=4401 \
|
||||
PENPOT_MCP_WEBSOCKET_PORT=4402
|
||||
EXPOSE 4401 4402
|
||||
WORKDIR /usr/local/lib/node_modules/@penpot/mcp
|
||||
EXPOSE 4400 4401 4402
|
||||
CMD ["pnpm", "run", "start"]
|
||||
|
||||
@@ -25,6 +25,8 @@ spec:
|
||||
containerPort: 4401
|
||||
- name: ws
|
||||
containerPort: 4402
|
||||
- name: plugin
|
||||
containerPort: 4400
|
||||
env:
|
||||
- name: PENPOT_MCP_REMOTE_MODE
|
||||
value: "true"
|
||||
@@ -32,6 +34,10 @@ spec:
|
||||
value: "0.0.0.0"
|
||||
- name: PENPOT_MCP_SERVER_ADDRESS
|
||||
value: "mcp-designer.DOMAIN_SUFFIX"
|
||||
- name: WS_URI
|
||||
value: "wss://mcp-designer.DOMAIN_SUFFIX/ws"
|
||||
- name: PENPOT_MCP_PLUGIN_SERVER_HOST
|
||||
value: "0.0.0.0"
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
@@ -54,3 +60,6 @@ spec:
|
||||
- name: ws
|
||||
port: 4402
|
||||
targetPort: ws
|
||||
- name: plugin
|
||||
port: 4400
|
||||
targetPort: plugin
|
||||
|
||||
@@ -14,9 +14,11 @@ data:
|
||||
PENPOT_ASSETS_STORAGE_BACKEND: "assets-s3"
|
||||
PENPOT_STORAGE_ASSETS_S3_ENDPOINT: "http://seaweedfs-filer.storage.svc.cluster.local:8333"
|
||||
PENPOT_STORAGE_ASSETS_S3_BUCKET: "penpot"
|
||||
PENPOT_STORAGE_ASSETS_S3_REGION: "us-east-1"
|
||||
AWS_REGION: "us-east-1"
|
||||
PENPOT_OIDC_BASE_URI: "https://auth.DOMAIN_SUFFIX/"
|
||||
PENPOT_TELEMETRY_ENABLED: "false"
|
||||
PENPOT_FLAGS: "enable-login-with-oidc disable-login-with-password disable-email-verification disable-registration enable-backend-api-doc enable-auto-file-snapshot enable-tiered-file-data-storage enable-webhooks enable-access-tokens enable-cors"
|
||||
PENPOT_FLAGS: "enable-login-with-oidc disable-login-with-password disable-email-verification enable-oidc-registration enable-backend-api-doc enable-auto-file-snapshot enable-tiered-file-data-storage enable-webhooks enable-access-tokens enable-cors"
|
||||
---
|
||||
# ── Frontend (nginx SPA) ─────────────────────────────────────────────────────
|
||||
apiVersion: apps/v1
|
||||
@@ -126,6 +128,16 @@ spec:
|
||||
secretKeyRef:
|
||||
name: penpot-s3-credentials
|
||||
key: secret-key
|
||||
- name: AWS_ACCESS_KEY_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: penpot-s3-credentials
|
||||
key: access-key
|
||||
- name: AWS_SECRET_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: penpot-s3-credentials
|
||||
key: secret-key
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
|
||||
@@ -155,8 +155,32 @@ data:
|
||||
|
||||
[[routes]]
|
||||
host_prefix = "mail"
|
||||
# Caddy is the unified entry point — proxies /api/, /admin/, /static/, /oidc/ internally.
|
||||
backend = "http://messages-frontend.lasuite.svc.cluster.local:80"
|
||||
backend = "http://bulwark.stalwart.svc.cluster.local:80"
|
||||
|
||||
# JMAP protocol (Bulwark ↔ Stalwart)
|
||||
[[routes.paths]]
|
||||
prefix = "/jmap"
|
||||
backend = "http://stalwart.stalwart.svc.cluster.local:8080"
|
||||
|
||||
# Well-known service discovery (autoconfig, caldav, carddav, etc.)
|
||||
[[routes.paths]]
|
||||
prefix = "/.well-known/"
|
||||
backend = "http://stalwart.stalwart.svc.cluster.local:8080"
|
||||
|
||||
# OAuth2/OIDC authorization callback
|
||||
[[routes.paths]]
|
||||
prefix = "/authorize"
|
||||
backend = "http://stalwart.stalwart.svc.cluster.local:8080"
|
||||
|
||||
# Stalwart admin + API
|
||||
[[routes.paths]]
|
||||
prefix = "/api"
|
||||
backend = "http://stalwart.stalwart.svc.cluster.local:8080"
|
||||
|
||||
# JMAP WebSocket
|
||||
[[routes.paths]]
|
||||
prefix = "/ws"
|
||||
backend = "http://stalwart.stalwart.svc.cluster.local:8080"
|
||||
|
||||
[[routes]]
|
||||
host_prefix = "messages"
|
||||
@@ -182,18 +206,25 @@ data:
|
||||
websocket = true
|
||||
|
||||
[[routes]]
|
||||
host_prefix = "mcp-designer"
|
||||
backend = "http://penpot-mcp.devtools.svc.cluster.local:4401"
|
||||
websocket = true
|
||||
host_prefix = "mcp-designer"
|
||||
backend = "http://penpot-mcp.devtools.svc.cluster.local:4400"
|
||||
websocket = true
|
||||
timeout_secs = 86400
|
||||
|
||||
[[routes.paths]]
|
||||
prefix = "/"
|
||||
prefix = "/mcp"
|
||||
backend = "http://penpot-mcp.devtools.svc.cluster.local:4401"
|
||||
auth_request = "http://hydra-public.ory.svc.cluster.local:4444/userinfo"
|
||||
|
||||
[[routes.paths]]
|
||||
prefix = "/ws"
|
||||
backend = "http://penpot-mcp.devtools.svc.cluster.local:4402"
|
||||
prefix = "/sse"
|
||||
backend = "http://penpot-mcp.devtools.svc.cluster.local:4401"
|
||||
auth_request = "http://hydra-public.ory.svc.cluster.local:4444/userinfo"
|
||||
|
||||
[[routes.paths]]
|
||||
prefix = "/ws"
|
||||
backend = "http://penpot-mcp.devtools.svc.cluster.local:4402"
|
||||
timeout_secs = 86400
|
||||
|
||||
[[routes]]
|
||||
host_prefix = "src"
|
||||
@@ -280,43 +311,21 @@ data:
|
||||
|
||||
[[routes]]
|
||||
host_prefix = "cal"
|
||||
backend = "http://calendars-frontend.lasuite.svc.cluster.local:80"
|
||||
|
||||
[[routes.paths]]
|
||||
prefix = "/api/"
|
||||
backend = "http://calendars-backend.lasuite.svc.cluster.local:80"
|
||||
|
||||
[[routes.paths]]
|
||||
prefix = "/admin/"
|
||||
backend = "http://calendars-backend.lasuite.svc.cluster.local:80"
|
||||
|
||||
[[routes.paths]]
|
||||
prefix = "/static/"
|
||||
backend = "http://calendars-backend.lasuite.svc.cluster.local:80"
|
||||
# Default: redirect to unified Bulwark calendar UI.
|
||||
redirect = "https://mail.DOMAIN_SUFFIX/calendar"
|
||||
|
||||
# CalDAV protocol — external calendar clients connect here.
|
||||
[[routes.paths]]
|
||||
prefix = "/caldav"
|
||||
backend = "http://calendars-backend.lasuite.svc.cluster.local:80"
|
||||
backend = "http://stalwart.stalwart.svc.cluster.local:8080"
|
||||
|
||||
[[routes.paths]]
|
||||
prefix = "/.well-known/caldav"
|
||||
backend = "http://calendars-backend.lasuite.svc.cluster.local:80"
|
||||
backend = "http://stalwart.stalwart.svc.cluster.local:8080"
|
||||
|
||||
[[routes.paths]]
|
||||
prefix = "/rsvp/"
|
||||
backend = "http://calendars-backend.lasuite.svc.cluster.local:80"
|
||||
|
||||
[[routes.paths]]
|
||||
prefix = "/ical/"
|
||||
backend = "http://calendars-backend.lasuite.svc.cluster.local:80"
|
||||
|
||||
[[routes.paths]]
|
||||
prefix = "/external_api/"
|
||||
backend = "http://calendars-backend.lasuite.svc.cluster.local:80"
|
||||
|
||||
[[routes.paths]]
|
||||
prefix = "/__"
|
||||
backend = "http://calendars-backend.lasuite.svc.cluster.local:80"
|
||||
prefix = "/.well-known/carddav"
|
||||
backend = "http://stalwart.stalwart.svc.cluster.local:8080"
|
||||
|
||||
[[routes]]
|
||||
host_prefix = "projects"
|
||||
@@ -392,6 +401,21 @@ data:
|
||||
host_prefix = "build"
|
||||
backend = "buildkitd.build.svc.cluster.local:1234"
|
||||
|
||||
# SMTP inbound: port 25 → Stalwart for mail delivery.
|
||||
[smtp]
|
||||
listen = "0.0.0.0:25"
|
||||
backend = "stalwart.stalwart.svc.cluster.local:25"
|
||||
|
||||
# SMTP submission: port 587 → Stalwart for authenticated sending.
|
||||
[smtp-submission]
|
||||
listen = "0.0.0.0:587"
|
||||
backend = "stalwart.stalwart.svc.cluster.local:587"
|
||||
|
||||
# IMAPS: port 993 → Stalwart for desktop/mobile email clients.
|
||||
[imaps]
|
||||
listen = "0.0.0.0:993"
|
||||
backend = "stalwart.stalwart.svc.cluster.local:993"
|
||||
|
||||
# SSH TCP passthrough: port 22 → Gitea SSH pod (headless service → pod:2222).
|
||||
[ssh]
|
||||
listen = "0.0.0.0:22"
|
||||
|
||||
@@ -29,7 +29,8 @@ spec:
|
||||
sunbeam-conversations \
|
||||
sunbeam-git-lfs \
|
||||
sunbeam-game-assets \
|
||||
sunbeam-ml-models; do
|
||||
sunbeam-ml-models \
|
||||
sunbeam-stalwart; do
|
||||
mc mb --ignore-existing "weed/$bucket"
|
||||
echo "Ensured bucket: $bucket"
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user