Skip to content

Commit 04d6aed

Browse files
ralyodioclaude
andcommitted
Run on Bun: bun install, Bun image, Bun for web + orchestrator
Moves meshhook.com off Node + pnpm onto Bun, following the fleet recipe (phonenumbers.bot pilot): Bun is now the package manager and the runtime. - Package manager: bun.lock is migrated from pnpm-lock.yaml (every version kept exactly: kit 2.70.2, svelte 5.56.8, vite 5.4.21, pg 8.23.0, undici 6.28.0). pnpm-workspace.yaml becomes `workspaces` in package.json; its esbuild build approval becomes trustedDependencies. - Runtime: the Dockerfile is oven/bun:1.4.0-slim, non-root, `bun server.mjs`. The supervisor spawns the SvelteKit server and the orchestrator with process.execPath, so both children run on Bun. Port 3000, env and the / health path are unchanged; dev2's compose file needs no change. - Scripts and the mh CLI call bun instead of node/pnpm; the SvelteKit build is `bun --bun vite build`. - Tests: vitest runs via `bun --bun vitest run`; the node:test suites run under `bun test`. Four http-call tests were nested inside another test's body (a paste error). Node ran them as subtests, Bun skipped them silently, so they are un-nested; both runners now execute all 258. - CI: new ci workflow (frozen install, tests, build, boot the web server). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent d1580a3 commit 04d6aed

14 files changed

Lines changed: 1040 additions & 3941 deletions

File tree

‎.dockerignore‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.git
2+
.github
3+
**/node_modules
4+
apps/web/build
5+
apps/web/.svelte-kit
6+
.env
7+
.env.*
8+
!.env.example
9+
docs

‎.github/workflows/ci.yml‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: ci
2+
3+
on:
4+
pull_request:
5+
branches: [master]
6+
push:
7+
branches: [master]
8+
9+
jobs:
10+
build:
11+
name: install, test, build (Bun)
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
# The version comes from packageManager in package.json, the same Bun the
16+
# image (Dockerfile) pins.
17+
- uses: oven-sh/setup-bun@v2
18+
with:
19+
bun-version-file: package.json
20+
- run: bun install --frozen-lockfile
21+
- run: bun run test
22+
- run: bun run build
23+
# The SvelteKit server must boot under Bun and answer.
24+
- name: Web server answers under Bun
25+
run: |
26+
(cd apps/web && PORT=3000 HOST=127.0.0.1 ORIGIN=http://127.0.0.1:3000 bun build/index.js > /tmp/web.log 2>&1 &)
27+
for i in $(seq 1 30); do
28+
code=$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3000/ || true)
29+
case "$code" in 2*|3*) echo "/ -> $code"; exit 0;; esac
30+
sleep 1
31+
done
32+
cat /tmp/web.log; exit 1

‎Dockerfile‎

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,33 @@
1-
# meshhook on dev2: a plain image because nixpacks' pinned nixpkgs ships Node 22.11
2-
# while pnpm 11.18 needs >= 22.13 and has no nodejs_24. Same commands railway.toml ran.
3-
FROM node:24-bookworm-slim
1+
# syntax=docker/dockerfile:1
2+
#
3+
# meshhook.com on dev2, run on Bun. dev2's compose stack builds this file
4+
# (/home/anthony/www/meshhook.com/docker-compose.app.yml, `dockerfile: Dockerfile`).
5+
#
6+
# One container, the same two processes as before: server.mjs supervises the
7+
# SvelteKit web app (adapter-node build) and the queue orchestrator. It spawns
8+
# both with process.execPath, so under Bun they run on Bun too.
9+
#
10+
# Contract with dev2, unchanged from the Node image: listens on 3000 (compose maps
11+
# 127.0.0.1:APP_PORT), answers / for the deploy health check, reads DATABASE_URL,
12+
# ORIGIN and the rest from app.env at run time.
13+
FROM oven/bun:1.4.0-slim
414
WORKDIR /app
5-
RUN corepack enable && corepack prepare pnpm@11.18.0 --activate
6-
COPY . .
7-
RUN pnpm install --frozen-lockfile && pnpm --filter @meshhook/web run build
15+
RUN chown bun:bun /app
16+
USER bun
17+
# The workspace manifests first, so a source-only change keeps the install layer.
18+
COPY --chown=bun:bun package.json bun.lock ./
19+
COPY --chown=bun:bun apps/web/package.json apps/web/
20+
COPY --chown=bun:bun workers/package.json workers/
21+
COPY --chown=bun:bun packages/shared/package.json packages/shared/
22+
COPY --chown=bun:bun packages/cli/package.json packages/cli/
23+
COPY --chown=bun:bun scripts/socket-patch.mjs scripts/
24+
RUN bun install --frozen-lockfile
25+
COPY --chown=bun:bun . .
26+
# `bun --bun vite build`: the SvelteKit build runs on Bun, not Node.
27+
RUN bun run build
828
ENV NODE_ENV=production
929
EXPOSE 3000
10-
CMD ["node", "server.mjs"]
30+
# 127.0.0.1, not localhost: localhost can resolve ::1 first.
31+
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
32+
CMD bun -e "fetch('http://127.0.0.1:'+(process.env.PORT||3000)+'/').then(r=>process.exit(r.status<500?0:1)).catch(()=>process.exit(1))"
33+
CMD ["bun", "server.mjs"]

‎README.md‎

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@
4141

4242
1. **Install dependencies**
4343
```bash
44-
pnpm install
44+
bun install
4545
```
4646

4747
2. **Setup environment** (interactive)
4848
```bash
49-
pnpm run setup
49+
bun run setup
5050
```
5151
Select "Local Development" when prompted. This creates `.env.local` pointing at a
5252
local SQLite file (`file:./meshhook.db`) and generates a secrets encryption key.
@@ -55,52 +55,52 @@
5555

5656
3. **Run migrations**
5757
```bash
58-
pnpm run db:migrate
58+
bun run db:migrate
5959
```
6060

6161
4. **Start the orchestrator**
6262
```bash
63-
pnpm run start
63+
bun run start
6464
```
6565
Runs on port 8080 (configurable via PORT environment variable)
6666

6767
### Production / Staging
6868

6969
1. **Install dependencies**
7070
```bash
71-
pnpm install
71+
bun install
7272
```
7373

7474
2. **Setup environment** (interactive)
7575
```bash
76-
pnpm run setup
76+
bun run setup
7777
```
7878
Select "Production" or "Staging" and enter your Postgres URL
7979
(`postgres://user:pass@host:5432/meshhook`). Anything else is refused.
8080

8181

8282
3. **Run migrations**
8383
```bash
84-
pnpm run db:migrate
84+
bun run db:migrate
8585
```
8686
Applies any pending migrations from `migrations/` and records them in
8787
`schema_migrations`. Re-running is a no-op.
8888

8989
4. **Start the server**
9090
```bash
91-
pnpm run start
91+
bun run start
9292
```
9393
Runs on port 8080 by default. Configure your reverse proxy to forward traffic to this port.
9494

9595
## Available Commands
9696

97-
- `pnpm run setup` - Interactive environment configuration (local/staging/production)
98-
- `pnpm run db:migrate` - Apply pending database migrations
99-
- `pnpm run db:status` - Show applied and pending migrations
100-
- `pnpm run db:verify` - Verify the schema matches what the app expects
101-
- `pnpm test` - Run the test suite
102-
- `pnpm run start` - Start the orchestrator worker (production)
103-
- `pnpm mh --help` - CLI help
97+
- `bun run setup` - Interactive environment configuration (local/staging/production)
98+
- `bun run db:migrate` - Apply pending database migrations
99+
- `bun run db:status` - Show applied and pending migrations
100+
- `bun run db:verify` - Verify the schema matches what the app expects
101+
- `bun run test` - Run the test suite
102+
- `bun run start` - Start the orchestrator worker (production)
103+
- `bun run mh --help` - CLI help
104104

105105
## Environment Files
106106

0 commit comments

Comments
 (0)