Bun is an all-in-one JavaScript runtime, package manager, bundler, and test runner — and it's fast at all of them. Its bun install speed alone makes CI builds noticeably quicker. This guide covers deploying a Bun app to production with a managed database.
Why Bun is nice to deploy
- Fast installs —
bun installresolves and links dependencies far faster than npm in most cases, cutting build times. - Built-in HTTP server —
Bun.serveis a high-performance server with no framework needed. - Native bundler and transpiler — runs TypeScript directly, no separate build step required for many apps.
- A bundled SQL/SQLite client —
bun:sqliteand a Postgres client ship with the runtime.
A production Dockerfile
Use the official Bun image and a lockfile-aware install for reproducible builds:
FROM oven/bun:1 AS build
WORKDIR /app
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile
COPY . .
# If your app has a build step:
RUN bun run build
FROM oven/bun:1
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build /app .
EXPOSE 3000
USER bun
CMD ["bun", "run", "start"]--frozen-lockfile makes the build fail if bun.lock is out of sync with package.json — exactly the determinism you want in CI. The official image includes a non-root bun user.
Writing a server with Bun.serve
const port = Number(process.env.PORT ?? 3000);
Bun.serve({
port,
hostname: "0.0.0.0",
fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/healthz") {
return Response.json({ status: "ok" });
}
return new Response("Hello from Bun");
},
});
console.log(`Listening on ${port}`);Bind to 0.0.0.0 so the container accepts external traffic. Bun.serve handles high concurrency natively and supports WebSockets if you need them.
Frameworks work too — Bun runs Express, Hono, Elysia, and others. Hono pairs especially well with Bun for a tiny, fast API.
A managed database
Bun ships a native SQL client. For PostgreSQL:
import { SQL } from "bun";
const sql = new SQL(process.env.DATABASE_URL!);
const users = await sql`SELECT id, email FROM users LIMIT 10`;
console.log(users);The bun SQL client uses tagged-template queries that are parameterized (safe from injection) by default. As always, keep your effective connection count under the database's limit when running multiple replicas.
Configuration and secrets
Bun reads .env files automatically in development, but in production set real environment variables through your platform. Never bake secrets into the image.
const dbUrl = process.env.DATABASE_URL;
if (!dbUrl) throw new Error("DATABASE_URL is required");Deploying on PandaStack
- 1Create a PostgreSQL database —
DATABASE_URLis injected automatically. - 2Connect your repo as a container app. PandaStack detects the Dockerfile and builds via rootless BuildKit; the install command is overridable to
bun installif you skip the Dockerfile. - 3Set secrets in the dashboard.
- 4Push — live build logs stream and you get automatic SSL.
Bun's quick startup makes it well suited to free-tier scale-to-zero, and you get rollbacks and deploy history.
| Concern | Setting |
|---|---|
| Install | bun install --frozen-lockfile |
| Server | Bun.serve on 0.0.0.0 |
| DB client | new SQL(DATABASE_URL) |
| User | non-root bun |
| Lockfile | commit bun.lock |
Common pitfalls
- No frozen lockfile — non-reproducible builds; always commit
bun.lockand use--frozen-lockfile. - Binding to
localhost— unreachable in a container; use0.0.0.0. - Relying on auto-loaded
.envin production — set real env vars instead. - Assuming 100% Node compatibility — Bun is close but a few native modules differ; test in a container before shipping.
References
- Bun Docker guide: https://bun.sh/guides/ecosystem/docker
- Bun.serve HTTP server: https://bun.sh/docs/api/http
- Bun SQL (PostgreSQL) client: https://bun.sh/docs/api/sql
- bun install & lockfile: https://bun.sh/docs/cli/install
- Hono framework: https://hono.dev/
---
Bun's speed and PandaStack's free-tier scale-to-zero make for fast deploys and fast cold starts. Add a managed PostgreSQL database with DATABASE_URL auto-wired and push. Get started at https://dashboard.pandastack.io