# Self-hosted Executor, single container, no external services.# Build context is the repo root because Bun workspaces need every member:# docker build -f apps/host-selfhost/Dockerfile -t executor-selfhost .## Runtime needs this container plus a volume for the data dir:# docker run -p 4788:4788 -e BETTER_AUTH_SECRET=$(openssl rand -hex 32) \# -e EXECUTOR_BOOTSTRAP_ADMIN_EMAIL=you@example.com \# -e EXECUTOR_BOOTSTRAP_ADMIN_PASSWORD=... \# -e EXECUTOR_WEB_BASE_URL=https://your.domain \# -v executor-data:/data executor-selfhost FROM oven/bun:1 AS prod-depsWORKDIR /appCOPY . .RUN bun install --frozen-lockfile --production --ignore-scripts --filter @executor-js/host-selfhost \ && bun run apps/host-selfhost/scripts/package-runtime.ts FROM oven/bun:1 AS buildWORKDIR /appCOPY . .RUN bun install --frozen-lockfileRUN cd apps/host-selfhost && bun run build FROM gcr.io/distroless/cc-debian12 AS runtimeWORKDIR /appLABEL org.opencontainers.image.source="https://github.com/UsefulSoftwareCo/executor" \ org.opencontainers.image.description="Single-container self-hosted Executor" \ org.opencontainers.image.licenses="MIT"ENV NODE_ENV=production \ EXECUTOR_HOST=0.0.0.0 \ PORT=4788 \ EXECUTOR_DATA_DIR=/dataCOPY --from=prod-deps /usr/local/bin/bun /usr/local/bin/bunCOPY --from=prod-deps /app/.selfhost-runtime /appCOPY --from=build /app/apps/host-selfhost/dist /app/apps/host-selfhost/distWORKDIR /app/apps/host-selfhostVOLUME ["/data"]EXPOSE 4788HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=5 \ CMD ["bun", "-e", "fetch('http://127.0.0.1:4788/api/health').then(r=>process.exit(r.ok?0:1),()=>process.exit(1))"]CMD ["bun", "run", "dist-server/serve.js"]
# Self-hosted Executor, single container, no external services.
# Build context is the repo root because Bun workspaces need every member:
# docker build -f apps/host-selfhost/Dockerfile -t executor-selfhost .
#
# Runtime needs this container plus a volume for the data dir:
# docker run -p 4788:4788 -e BETTER_AUTH_SECRET=$(openssl rand -hex 32) \
# -e EXECUTOR_BOOTSTRAP_ADMIN_EMAIL=you@example.com \
# -e EXECUTOR_BOOTSTRAP_ADMIN_PASSWORD=... \
# -e EXECUTOR_WEB_BASE_URL=https://your.domain \
# -v executor-data:/data executor-selfhost
FROM oven/bun:1 AS prod-deps
WORKDIR /app
COPY . .
RUN bun install --frozen-lockfile --production --ignore-scripts --filter @executor-js/host-selfhost \
&& bun run apps/host-selfhost/scripts/package-runtime.ts
FROM oven/bun:1 AS build
WORKDIR /app
COPY . .
RUN bun install --frozen-lockfile
RUN cd apps/host-selfhost && bun run build
FROM gcr.io/distroless/cc-debian12 AS runtime
WORKDIR /app
LABEL org.opencontainers.image.source="https://github.com/UsefulSoftwareCo/executor" \
org.opencontainers.image.description="Single-container self-hosted Executor" \
org.opencontainers.image.licenses="MIT"
ENV NODE_ENV=production \
EXECUTOR_HOST=0.0.0.0 \
PORT=4788 \
EXECUTOR_DATA_DIR=/data
COPY --from=prod-deps /usr/local/bin/bun /usr/local/bin/bun
COPY --from=prod-deps /app/.selfhost-runtime /app
COPY --from=build /app/apps/host-selfhost/dist /app/apps/host-selfhost/dist
WORKDIR /app/apps/host-selfhost
VOLUME ["/data"]
EXPOSE 4788
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=5 \
CMD ["bun", "-e", "fetch('http://127.0.0.1:4788/api/health').then(r=>process.exit(r.ok?0:1),()=>process.exit(1))"]
CMD ["bun", "run", "dist-server/serve.js"]