| @@ -1,132 +1,26 @@ |
| 1 | | −# Self-hosted Executor — single container, no external services. |
| 2 | | −# Build context is the REPO ROOT (the bun workspace install needs every member): |
| 1 | +# Self-hosted Executor, single container, no external services. |
| 2 | +# Build context is the repo root because Bun workspaces need every member: |
| 3 | 3 | # docker build -f apps/host-selfhost/Dockerfile -t executor-selfhost . |
| 4 | 4 | # |
| 5 | | −# Runtime needs nothing but this container + a volume for the data dir: |
| 5 | +# Runtime needs this container plus a volume for the data dir: |
| 6 | 6 | # docker run -p 4788:4788 -e BETTER_AUTH_SECRET=$(openssl rand -hex 32) \ |
| 7 | 7 | # -e EXECUTOR_BOOTSTRAP_ADMIN_EMAIL=you@example.com \ |
| 8 | 8 | # -e EXECUTOR_BOOTSTRAP_ADMIN_PASSWORD=... \ |
| 9 | 9 | # -e EXECUTOR_WEB_BASE_URL=https://your.domain \ |
| 10 | 10 | # -v executor-data:/data executor-selfhost |
| 11 | | −# |
| 12 | | −# SQLite (libSQL, file:/data/...) lives in /data, QuickJS + MCP run in-process — |
| 13 | | −# so there's no postgres/worker/proxy to orchestrate. |
| 14 | 11 | |
| 15 | | −# ── Production deps: installs only what the runtime image needs ───────────── |
| 16 | 12 | FROM oven/bun:1 AS prod-deps |
| 17 | 13 | WORKDIR /app |
| 18 | 14 | COPY . . |
| 19 | | −# This stage is independent from the SPA build stage, so BuildKit can run the |
| 20 | | −# slow production install in parallel with the dev install and Vite build. |
| 21 | | −# --ignore-scripts: the root `prepare` hook runs a dev-only tool |
| 22 | | −# (effect-language-service); runtime deps are prebuilt JS with no postinstall. |
| 23 | 15 | RUN bun install --frozen-lockfile --production --ignore-scripts --filter @executor-js/host-selfhost \ |
| 24 | | − && find node_modules/.bun -maxdepth 1 -name '*linux-x64-musl*' -exec rm -rf {} + \ |
| 25 | | − && rm -rf \ |
| 26 | | − node_modules/.bun/@ant-design+* \ |
| 27 | | − node_modules/.bun/@base-ui+* \ |
| 28 | | − node_modules/.bun/@cloudflare+workers-types@* \ |
| 29 | | − node_modules/.bun/@electric-sql+pglite@* \ |
| 30 | | − node_modules/.bun/@emotion+react@* \ |
| 31 | | − node_modules/.bun/@emoji-mart+* \ |
| 32 | | − node_modules/.bun/@esbuild+* \ |
| 33 | | − node_modules/.bun/@floating-ui+react@* \ |
| 34 | | − node_modules/.bun/@dnd-kit+* \ |
| 35 | | − node_modules/.bun/@hookform+* \ |
| 36 | | − node_modules/.bun/@lobehub+* \ |
| 37 | | − node_modules/.bun/@mermaid-js+* \ |
| 38 | | − node_modules/.bun/@pierre+diffs@* \ |
| 39 | | − node_modules/.bun/@pierre+theme@* \ |
| 40 | | − node_modules/.bun/@primer+octicons@* \ |
| 41 | | − node_modules/.bun/@rc-component+* \ |
| 42 | | − node_modules/.bun/@rolldown+binding-* \ |
| 43 | | − node_modules/.bun/@reduxjs+* \ |
| 44 | | − node_modules/.bun/@shikijs+* \ |
| 45 | | − node_modules/.bun/@splinetool+* \ |
| 46 | | − node_modules/.bun/@tanstack+start-plugin-core@* \ |
| 47 | | − node_modules/.bun/@tanstack+react-router@* \ |
| 48 | | − node_modules/.bun/@tanstack+router-core@* \ |
| 49 | | − node_modules/.bun/@types+* \ |
| 50 | | − node_modules/.bun/ahooks@* \ |
| 51 | | − node_modules/.bun/antd@* \ |
| 52 | | − node_modules/.bun/better-sqlite3@* \ |
| 53 | | − node_modules/.bun/bun-types@* \ |
| 54 | | − node_modules/.bun/caniuse-lite@* \ |
| 55 | | − node_modules/.bun/chroma-js@* \ |
| 56 | | − node_modules/.bun/cytoscape*@* \ |
| 57 | | − node_modules/.bun/d3@* \ |
| 58 | | − node_modules/.bun/date-fns*@* \ |
| 59 | | − node_modules/.bun/drizzle-kit@* \ |
| 60 | | − node_modules/.bun/dompurify@* \ |
| 61 | | − node_modules/.bun/emoji-mart@* \ |
| 62 | | − node_modules/.bun/framer-motion@* \ |
| 63 | | − node_modules/.bun/jiti@* \ |
| 64 | | − node_modules/.bun/katex@* \ |
| 65 | | − node_modules/.bun/layout-base@* \ |
| 66 | | − node_modules/.bun/leva@* \ |
| 67 | | − node_modules/.bun/lightningcss-* \ |
| 68 | | − node_modules/.bun/lit-html@* \ |
| 69 | | − node_modules/.bun/lucide-react@* \ |
| 70 | | − node_modules/.bun/mermaid@* \ |
| 71 | | − node_modules/.bun/motion@* \ |
| 72 | | − node_modules/.bun/motion-* \ |
| 73 | | − node_modules/.bun/polished@* \ |
| 74 | | − node_modules/.bun/prettier@* \ |
| 75 | | − node_modules/.bun/react-day-picker@* \ |
| 76 | | − node_modules/.bun/react-hook-form@* \ |
| 77 | | − node_modules/.bun/react@* \ |
| 78 | | − node_modules/.bun/react-dom@* \ |
| 79 | | − node_modules/.bun/react-dropzone@* \ |
| 80 | | − node_modules/.bun/recharts@* \ |
| 81 | | − node_modules/.bun/rolldown@* \ |
| 82 | | − node_modules/.bun/shiki@* \ |
| 83 | | − node_modules/.bun/solid-js@* \ |
| 84 | | − node_modules/.bun/source-map@* \ |
| 85 | | − node_modules/.bun/tailwind-merge@* \ |
| 86 | | − node_modules/.bun/tsx@* \ |
| 87 | | − node_modules/.bun/@upsetjs+venn.js@* \ |
| 88 | | − node_modules/.bun/victory-vendor@* \ |
| 89 | | − node_modules/.bun/virtua@* \ |
| 90 | | − node_modules/.bun/typeorm@* \ |
| 91 | | − node_modules/.bun/vite@* \ |
| 92 | | − node_modules/.bun/vitest@* \ |
| 93 | | − && find node_modules -type f \( -name '*.map' -o -name '*.d.ts' -o -name '*.d.mts' -o -name '*.d.cts' -o -name '*.ts' -o -name '*.tsx' -o -name '*.md' -o -name '*.markdown' \) -delete \ |
| 94 | | − && find node_modules -type d \( -iname test -o -iname tests -o -iname __tests__ -o -iname fixtures -o -iname fixture -o -iname examples \) -prune -exec rm -rf {} + \ |
| 95 | | − && find packages apps/host-selfhost -type f \( -name '*.map' -o -name '*.d.ts' -o -name '*.test.ts' -o -name '*.test.tsx' -o -name '*.md' -o -name '*.markdown' \) -delete \ |
| 96 | | − && rm -rf \ |
| 97 | | − packages/app \ |
| 98 | | − packages/react \ |
| 99 | | − packages/plugins/*/fixtures \ |
| 100 | | − packages/plugins/*/src/react \ |
| 101 | | − packages/plugins/*/src/**/__snapshots__ \ |
| 102 | | − packages/plugins/*/test \ |
| 103 | | − packages/plugins/*/testing \ |
| 104 | | − packages/*/*/CHANGELOG.md \ |
| 105 | | − packages/*/*/tsconfig.json \ |
| 106 | | − packages/*/*/tsup.config.ts \ |
| 107 | | − packages/*/*/vitest.config.ts \ |
| 108 | | − packages/plugins/*/vitest.config.ts \ |
| 109 | | − apps/host-selfhost/CHANGELOG.md \ |
| 110 | | − apps/host-selfhost/Dockerfile \ |
| 111 | | − apps/host-selfhost/docker-compose.yml \ |
| 112 | | − apps/host-selfhost/scripts \ |
| 113 | | − apps/host-selfhost/vitest.config.ts \ |
| 114 | | − apps/host-selfhost/web \ |
| 115 | | − apps/host-selfhost/tsconfig.json \ |
| 116 | | − apps/host-selfhost/tsr.routes.ts \ |
| 117 | | − apps/host-selfhost/vite.config.ts |
| 16 | + && bun run scripts/package-selfhost-runtime.ts |
| 118 | 17 | |
| 119 | | −# ── Build stage: install the workspace + build the SPA ────────────────────── |
| 120 | 18 | FROM oven/bun:1 AS build |
| 121 | 19 | WORKDIR /app |
| 122 | 20 | COPY . . |
| 123 | | −# Full install (dev deps included, vite/turbo/plugins are needed to build). |
| 124 | 21 | RUN bun install --frozen-lockfile |
| 125 | | −# Builds @executor-js/vite-plugin (via turbo) then the self-host SPA into |
| 126 | | −# apps/host-selfhost/dist. |
| 127 | 22 | RUN cd apps/host-selfhost && bun run build |
| 128 | 23 | |
| 129 | | −# ── Runtime stage: serve the built app under Bun ──────────────────────────── |
| 130 | 24 | FROM gcr.io/distroless/cc-debian12 AS runtime |
| 131 | 25 | WORKDIR /app |
| 132 | 26 | LABEL org.opencontainers.image.source="https://github.com/RhysSullivan/executor" \ |
| @@ -137,29 +31,11 @@ ENV NODE_ENV=production \ · 4 unmodified lines |
| 137 | 31 | PORT=4788 \ |
| 138 | 32 | EXECUTOR_DATA_DIR=/data |
| 139 | 33 | COPY --from=prod-deps /usr/local/bin/bun /usr/local/bin/bun |
| 140 | | −COPY --from=prod-deps /app/node_modules /app/node_modules |
| 141 | | −COPY --from=prod-deps /app/packages/core/api /app/packages/core/api |
| 142 | | −COPY --from=prod-deps /app/packages/core/config /app/packages/core/config |
| 143 | | −COPY --from=prod-deps /app/packages/core/execution /app/packages/core/execution |
| 144 | | −COPY --from=prod-deps /app/packages/core/fumadb /app/packages/core/fumadb |
| 145 | | −COPY --from=prod-deps /app/packages/core/sdk /app/packages/core/sdk |
| 146 | | −COPY --from=prod-deps /app/packages/hosts/mcp /app/packages/hosts/mcp |
| 147 | | −COPY --from=prod-deps /app/packages/kernel/core /app/packages/kernel/core |
| 148 | | −COPY --from=prod-deps /app/packages/kernel/runtime-quickjs /app/packages/kernel/runtime-quickjs |
| 149 | | −COPY --from=prod-deps /app/packages/plugins/encrypted-secrets /app/packages/plugins/encrypted-secrets |
| 150 | | −COPY --from=prod-deps /app/packages/plugins/google /app/packages/plugins/google |
| 151 | | −COPY --from=prod-deps /app/packages/plugins/graphql /app/packages/plugins/graphql |
| 152 | | −COPY --from=prod-deps /app/packages/plugins/mcp /app/packages/plugins/mcp |
| 153 | | −COPY --from=prod-deps /app/packages/plugins/microsoft /app/packages/plugins/microsoft |
| 154 | | −COPY --from=prod-deps /app/packages/plugins/openapi /app/packages/plugins/openapi |
| 155 | | −COPY --from=prod-deps /app/apps/host-selfhost /app/apps/host-selfhost |
| 34 | +COPY --from=prod-deps /app/.selfhost-runtime /app |
| 156 | 35 | COPY --from=build /app/apps/host-selfhost/dist /app/apps/host-selfhost/dist |
| 157 | 36 | WORKDIR /app/apps/host-selfhost |
| 158 | 37 | VOLUME ["/data"] |
| 159 | 38 | EXPOSE 4788 |
| 160 | | −# Readiness probe against the public /api/health endpoint (a trivial DB ping). |
| 161 | 39 | HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=5 \ |
| 162 | 40 | CMD bun -e "fetch('http://127.0.0.1:4788/api/health').then(r=>process.exit(r.ok?0:1),()=>process.exit(1))" |
| 163 | | −# serve.ts binds the Effect AppLayer (API + /mcp + /api/auth + /docs) and serves |
| 164 | | −# the built SPA from ./dist — one process. |
| 165 | 41 | CMD ["bun", "run", "src/serve.ts"] |