Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pnpm-debug.log*
# TypeScript
*.tsbuildinfo
dist/
frontend/build/
!frontend/packages/icons/dist/

# IDE
Expand Down
4 changes: 4 additions & 0 deletions frontend/.ladle/config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** @type {import('@ladle/react').UserConfig} */
export default {
viteConfig: ".ladle/vite.config.ts",
};
14 changes: 14 additions & 0 deletions frontend/.ladle/ladle.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@import "../src/components/theme.css";

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground min-h-screen;
}
}
4 changes: 4 additions & 0 deletions frontend/.ladle/vite.config.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 42 additions & 0 deletions frontend/Caddyfile.ladle
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
admin off
}

:{$PORT:80} {
# Health check endpoint (must come before file_server)
handle /health {
respond "healthy" 200
}

# Main site handler
handle {
root * /srv

# Gzip compression
encode gzip

# Security headers
header {
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
X-XSS-Protection "1; mode=block"
}

# Cache static assets aggressively
@static {
path *.js *.css *.png *.jpg *.jpeg *.gif *.ico *.svg *.woff *.woff2 *.ttf *.eot
}
header @static Cache-Control "public, max-age=31536000, immutable"

# Don't cache HTML files (for SPA updates)
@html {
path *.html
}
header @html Cache-Control "no-store, no-cache, must-revalidate"

# SPA catch-all routing - try file first, then fall back to index.html
try_files {path} /index.html

file_server
}
}
52 changes: 16 additions & 36 deletions frontend/cloud.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,56 +1,52 @@
# Frontend (Cloud) Dockerfile
# Multi-stage build: Node.js for building, nginx for serving

# =============================================================================
# Stage 1: Build
# =============================================================================
FROM node:22-alpine AS builder

# Install git, git-lfs, and coreutils (for env -S support in build scripts)
RUN apk add --no-cache git git-lfs coreutils

# Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate

WORKDIR /app

# Copy workspace configuration files
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml tsconfig.base.json turbo.json tsup.base.ts ./

# Copy all workspace packages that frontend depends on (including transitive deps)
# frontend -> rivetkit, @rivetkit/engine-api-full
# rivetkit -> @rivetkit/virtual-websocket, @rivetkit/engine-runner
# @rivetkit/engine-runner -> @rivetkit/engine-runner-protocol
# Copy frontend package
COPY frontend/ frontend/

# Copy engine SDK dependencies
COPY engine/sdks/typescript/api-full/ engine/sdks/typescript/api-full/
COPY engine/sdks/typescript/runner/ engine/sdks/typescript/runner/
COPY engine/sdks/typescript/runner-protocol/ engine/sdks/typescript/runner-protocol/

# Copy rivetkit dependencies
COPY rivetkit-typescript/packages/rivetkit/ rivetkit-typescript/packages/rivetkit/
COPY rivetkit-typescript/packages/traces/ rivetkit-typescript/packages/traces/
COPY rivetkit-typescript/packages/workflow-engine/ rivetkit-typescript/packages/workflow-engine/
COPY rivetkit-typescript/packages/sqlite-vfs/ rivetkit-typescript/packages/sqlite-vfs/
COPY rivetkit-typescript/packages/sqlite-vfs-linux-arm64/ rivetkit-typescript/packages/sqlite-vfs-linux-arm64/
COPY rivetkit-typescript/packages/sqlite-vfs-linux-x64/ rivetkit-typescript/packages/sqlite-vfs-linux-x64/

# Copy shared libraries
COPY shared/typescript/virtual-websocket/ shared/typescript/virtual-websocket/

# Copy examples and public assets
COPY examples/ examples/
COPY frontend/public/examples/ frontend/public/examples/

# Copy generated API docs (used by rivetkit build)
# Copy generated API docs
COPY rivetkit-asyncapi/ rivetkit-asyncapi/
COPY rivetkit-openapi/ rivetkit-openapi/

# Fetch LFS files if build platform doesn't support Git LFS natively
# Fetch LFS files
COPY scripts/docker/fetch-lfs.sh /tmp/fetch-lfs.sh
RUN chmod +x /tmp/fetch-lfs.sh && /tmp/fetch-lfs.sh

# Arguments required before installing dependencies
ARG FONTAWESOME_PACKAGE_TOKEN=""
ENV FONTAWESOME_PACKAGE_TOKEN=${FONTAWESOME_PACKAGE_TOKEN}

# Install dependencies (with pnpm store cache)
RUN --mount=type=cache,id=s/47975eb7-74fd-4043-a505-62b995ff5718-/pnpm/store,target=/pnpm/store \
RUN --mount=type=cache,id=s/47975eb7-74fd-4043-a505-62b995ff5718-pnpm-store,target=/pnpm/store \
pnpm install --frozen-lockfile

# Build arguments for environment variables
# Use placeholder URLs that pass validation but can be replaced at runtime
# Format: https://__PLACEHOLDER__.rivet.dev allows easy sed replacement
ARG VITE_APP_API_URL="https://VITE_APP_API_URL.placeholder.rivet.dev"
ARG VITE_APP_CLOUD_API_URL="https://VITE_APP_CLOUD_API_URL.placeholder.rivet.dev"
ARG VITE_APP_ASSETS_URL="https://VITE_APP_ASSETS_URL.placeholder.rivet.dev"
Expand All @@ -60,9 +56,7 @@ ARG VITE_APP_SENTRY_PROJECT_ID="0"
ARG VITE_APP_POSTHOG_API_KEY=""
ARG VITE_APP_POSTHOG_HOST=""
ARG DEPLOYMENT_TYPE="staging"
ARG FONTAWESOME_PACKAGE_TOKEN=""

# Set environment variables for build
ENV VITE_APP_API_URL=${VITE_APP_API_URL}
ENV VITE_APP_CLOUD_API_URL=${VITE_APP_CLOUD_API_URL}
ENV VITE_APP_ASSETS_URL=${VITE_APP_ASSETS_URL}
Expand All @@ -76,31 +70,17 @@ ENV DEPLOYMENT_TYPE=${DEPLOYMENT_TYPE}
ENV FONTAWESOME_PACKAGE_TOKEN=${FONTAWESOME_PACKAGE_TOKEN}
ENV VITE_APP_SENTRY_TUNNEL="/tunnel"

# Build the cloud frontend using turbo (automatically builds all dependencies, with turbo cache)
RUN --mount=type=cache,id=s/47975eb7-74fd-4043-a505-62b995ff5718-/app/.turbo,target=/app/.turbo \
RUN --mount=type=cache,id=s/47975eb7-74fd-4043-a505-62b995ff5718-turbo,target=/app/.turbo \
npx turbo run build:cloud --filter=@rivetkit/engine-frontend

# =============================================================================
# Stage 2: Serve with Caddy
# =============================================================================
FROM caddy:alpine

# Install bash for entrypoint script
RUN apk add --no-cache bash

# Copy Caddyfile configuration
COPY frontend/Caddyfile /etc/caddy/Caddyfile

# Copy built files from builder stage
COPY --from=builder /app/frontend/dist /srv

# Copy entrypoint script for runtime env var substitution
COPY frontend/docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh

# Default port (platform injects PORT env var)
ENV PORT=80

# Use custom entrypoint for env var substitution
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile"]
53 changes: 17 additions & 36 deletions frontend/inspector.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,101 +1,82 @@
# Frontend (Inspector) Dockerfile
# Multi-stage build: Node.js for building, Caddy for serving

# =============================================================================
# Stage 1: Build
# =============================================================================
FROM node:22-alpine AS builder

# Install git, git-lfs, and coreutils (for env -S support in build scripts)
RUN apk add --no-cache git git-lfs coreutils

# Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate

WORKDIR /app

# Copy workspace configuration files
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml tsconfig.base.json turbo.json tsup.base.ts ./

# Copy all workspace packages that frontend depends on (including transitive deps)
# frontend -> rivetkit, @rivetkit/engine-api-full
# rivetkit -> @rivetkit/virtual-websocket, @rivetkit/engine-runner
# @rivetkit/engine-runner -> @rivetkit/engine-runner-protocol
# Copy frontend package
COPY frontend/ frontend/

# Copy engine SDK dependencies
COPY engine/sdks/typescript/api-full/ engine/sdks/typescript/api-full/
COPY engine/sdks/typescript/runner/ engine/sdks/typescript/runner/
COPY engine/sdks/typescript/runner-protocol/ engine/sdks/typescript/runner-protocol/

# Copy rivetkit dependencies
COPY rivetkit-typescript/packages/rivetkit/ rivetkit-typescript/packages/rivetkit/
COPY rivetkit-typescript/packages/traces/ rivetkit-typescript/packages/traces/
COPY rivetkit-typescript/packages/workflow-engine/ rivetkit-typescript/packages/workflow-engine/
COPY rivetkit-typescript/packages/sqlite-vfs/ rivetkit-typescript/packages/sqlite-vfs/
COPY rivetkit-typescript/packages/sqlite-vfs-linux-arm64/ rivetkit-typescript/packages/sqlite-vfs-linux-arm64/
COPY rivetkit-typescript/packages/sqlite-vfs-linux-x64/ rivetkit-typescript/packages/sqlite-vfs-linux-x64/

# Copy shared libraries
COPY shared/typescript/virtual-websocket/ shared/typescript/virtual-websocket/

# Copy examples and public assets
COPY examples/ examples/
COPY frontend/public/examples/ frontend/public/examples/

# Copy generated API docs (used by rivetkit build)
# Copy generated API docs
COPY rivetkit-asyncapi/ rivetkit-asyncapi/
COPY rivetkit-openapi/ rivetkit-openapi/

# Fetch LFS files if build platform doesn't support Git LFS natively
# Fetch LFS files
COPY scripts/docker/fetch-lfs.sh /tmp/fetch-lfs.sh
RUN chmod +x /tmp/fetch-lfs.sh && /tmp/fetch-lfs.sh

# Arguments required before installing dependencies
ARG FONTAWESOME_PACKAGE_TOKEN=""
ENV FONTAWESOME_PACKAGE_TOKEN=${FONTAWESOME_PACKAGE_TOKEN}

# Install dependencies (with pnpm store cache)
RUN --mount=type=cache,id=s/11ac71ef-9b68-4d4c-bc8a-bc8b45000c14-/pnpm/store,target=/pnpm/store \
RUN --mount=type=cache,id=s/11ac71ef-9b68-4d4c-bc8a-bc8b45000c14-pnpm-store,target=/pnpm/store \
pnpm install --frozen-lockfile

# Build arguments for environment variables
# Use placeholder URLs that pass validation but can be replaced at runtime
ARG VITE_APP_API_URL="https://VITE_APP_API_URL.placeholder.rivet.dev"
ARG VITE_APP_ASSETS_URL="https://VITE_APP_ASSETS_URL.placeholder.rivet.dev"
ARG VITE_APP_SENTRY_DSN="https://VITE_APP_SENTRY_DSN.placeholder.rivet.dev/0"
ARG VITE_APP_SENTRY_PROJECT_ID="0"
ARG VITE_APP_POSTHOG_API_KEY=""
ARG VITE_APP_POSTHOG_HOST=""
ARG DEPLOYMENT_TYPE="staging"
ARG FONTAWESOME_PACKAGE_TOKEN=""

# Set environment variables for build
ENV VITE_APP_API_URL=${VITE_APP_API_URL}
ENV VITE_APP_ASSETS_URL=${VITE_APP_ASSETS_URL}
ENV VITE_APP_SENTRY_DSN=${VITE_APP_SENTRY_DSN}
ENV VITE_APP_SENTRY_PROJECT_ID=${VITE_APP_SENTRY_PROJECT_ID}
ENV VITE_APP_POSTHOG_API_KEY=${VITE_APP_POSTHOG_API_KEY}
ENV VITE_APP_POSTHOG_HOST=${VITE_APP_POSTHOG_HOST}
ENV VITE_APP_SENTRY_ENV=${RAILWAY_ENVIRONMENT_NAME:-staging}
ENV DEPLOYMENT_TYPE=${DEPLOYMENT_TYPE}
ENV FONTAWESOME_PACKAGE_TOKEN=${FONTAWESOME_PACKAGE_TOKEN}
ENV VITE_APP_SENTRY_ENV=${RAILWAY_ENVIRONMENT_NAME:-staging}
ENV VITE_APP_SENTRY_TUNNEL="/tunnel"

# Build the inspector frontend using turbo (automatically builds all dependencies, with turbo cache)
RUN --mount=type=cache,id=s/11ac71ef-9b68-4d4c-bc8a-bc8b45000c14-/app/.turbo,target=/app/.turbo \
RUN --mount=type=cache,id=s/11ac71ef-9b68-4d4c-bc8a-bc8b45000c14-turbo,target=/app/.turbo \
npx turbo run build:inspector --filter=@rivetkit/engine-frontend

# =============================================================================
# Stage 2: Serve with Caddy
# =============================================================================
FROM caddy:alpine

# Install bash for entrypoint script
RUN apk add --no-cache bash

# Copy Caddyfile configuration
COPY frontend/Caddyfile /etc/caddy/Caddyfile

# Copy built files from builder stage
COPY --from=builder /app/frontend/dist /srv

# Copy entrypoint script for runtime env var substitution
COPY frontend/docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh

# Default port (platform injects PORT env var)
ENV PORT=80

# Use custom entrypoint for env var substitution
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile"]
61 changes: 61 additions & 0 deletions frontend/ladle.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Frontend (Ladle) Dockerfile
FROM node:22-alpine AS builder

RUN apk add --no-cache git git-lfs coreutils

RUN corepack enable && corepack prepare pnpm@latest --activate

WORKDIR /app

# Copy workspace configuration files
COPY pnpm-workspace.yaml package.json pnpm-lock.yaml tsconfig.base.json turbo.json tsup.base.ts ./

# Copy frontend package
COPY frontend/ frontend/

# Copy public examples (required by Vite during ladle build)
COPY frontend/public/examples/ frontend/public/examples/

# Copy engine SDK dependencies
COPY engine/sdks/typescript/api-full/ engine/sdks/typescript/api-full/
COPY engine/sdks/typescript/runner/ engine/sdks/typescript/runner/
COPY engine/sdks/typescript/runner-protocol/ engine/sdks/typescript/runner-protocol/

# Copy rivetkit dependencies
COPY rivetkit-typescript/packages/rivetkit/ rivetkit-typescript/packages/rivetkit/
COPY rivetkit-typescript/packages/traces/ rivetkit-typescript/packages/traces/
COPY rivetkit-typescript/packages/workflow-engine/ rivetkit-typescript/packages/workflow-engine/
COPY rivetkit-typescript/packages/sqlite-vfs/ rivetkit-typescript/packages/sqlite-vfs/
COPY rivetkit-typescript/packages/sqlite-vfs-linux-arm64/ rivetkit-typescript/packages/sqlite-vfs-linux-arm64/
COPY rivetkit-typescript/packages/sqlite-vfs-linux-x64/ rivetkit-typescript/packages/sqlite-vfs-linux-x64/

# Copy shared libraries
COPY shared/typescript/virtual-websocket/ shared/typescript/virtual-websocket/

# Copy examples (needed for ladle stories)
COPY examples/ examples/

# Copy generated API docs
COPY rivetkit-asyncapi/ rivetkit-asyncapi/
COPY rivetkit-openapi/ rivetkit-openapi/

# Fetch LFS files
COPY scripts/docker/fetch-lfs.sh /tmp/fetch-lfs.sh
RUN chmod +x /tmp/fetch-lfs.sh && /tmp/fetch-lfs.sh

ARG FONTAWESOME_PACKAGE_TOKEN=""
ENV FONTAWESOME_PACKAGE_TOKEN=${FONTAWESOME_PACKAGE_TOKEN}

RUN --mount=type=cache,id=s/465998c9-9dc0-4af4-ac91-b772d7596d6e-pnpm-store,target=/pnpm/store \
pnpm install --frozen-lockfile

RUN --mount=type=cache,id=s/465998c9-9dc0-4af4-ac91-b772d7596d6e-turbo,target=/app/.turbo \
npx turbo run build:ladle --filter=@rivetkit/engine-frontend

FROM caddy:alpine

COPY frontend/Caddyfile.ladle /etc/caddy/Caddyfile
COPY --from=builder /app/frontend/build /srv

ENV PORT=80
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile"]
6 changes: 5 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
"preview:cloud": "vite preview --config vite.cloud.config.ts",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:update-snapshots": "playwright test --update-snapshots"
"test:e2e:update-snapshots": "playwright test --update-snapshots",
"dev:ladle": "ladle dev",
"build:ladle": "ladle build"
},
"dependencies": {
"@clerk/clerk-js": "^5.97",
Expand All @@ -39,6 +41,7 @@
"@fortawesome/free-solid-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.6",
"@hookform/resolvers": "^5.2",
"@ladle/react": "^5.1.1",
"@microsoft/fetch-event-source": "^2.0.1",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-avatar": "^1.1.10",
Expand Down Expand Up @@ -100,6 +103,7 @@
"@uiw/codemirror-theme-github": "^4.25.1",
"@uiw/react-codemirror": "^4.25.1",
"@vitejs/plugin-react": "^4.7.0",
"@xyflow/react": "^12.10.0",
"actor-core": "^0.6.3",
"autoprefixer": "^10.4.21",
"bcryptjs": "^2.4.3",
Expand Down
Loading
Loading