Skip to content

Deploy to Node.js

EmDash runs on any Node.js 18+ hosting platform. This guide covers deployment to common providers using SQLite and local or S3-compatible storage.

  • Node.js 18.17.1 or higher
  • A Node.js hosting provider or VPS

Configure EmDash for Node.js deployment:

astro.config.mjs
import { defineConfig } from "astro/config";
import node from "@astrojs/node";
import emdash, { local, s3 } from "emdash/astro";
import { sqlite } from "emdash/db";
export default defineConfig({
output: "server",
adapter: node({ mode: "standalone" }),
integrations: [
emdash({
database: sqlite({ url: "file:./data/emdash.db" }),
storage: local({
directory: "./data/uploads",
baseUrl: "/_emdash/api/media/file",
}),
}),
],
});
  1. Build the project:
Terminal window
npm run build
  1. Initialize the database:

    Terminal window
    npx emdash init --database ./data/emdash.db
  2. Start the server:

    Terminal window
    node ./dist/server/entry.mjs

The server runs on http://localhost:4321 by default.

For production, use S3-compatible storage instead of local filesystem:

astro.config.mjs
import emdash, { s3 } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
database: sqlite({ url: `file:${process.env.DATABASE_PATH}` }),
storage: s3({
endpoint: process.env.S3_ENDPOINT,
bucket: process.env.S3_BUCKET,
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
publicUrl: process.env.S3_PUBLIC_URL, // Optional CDN URL
}),
}),
],
});

Create a Dockerfile:

Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
ENV HOST=0.0.0.0
ENV PORT=4321
EXPOSE 4321
CMD ["node", "./dist/server/entry.mjs"]

Build and run:

Terminal window
docker build -t my-emdash-site .
docker run -p 4321:4321 -v emdash-data:/app/data my-emdash-site
VariableDescription
EMDASH_AUTH_SECRETSigns session cookies and auth tokens. Generate with npx emdash auth secret.
EMDASH_PREVIEW_SECRETSigns preview URLs for draft content. Generate with npx emdash auth secret.
VariableDescriptionExample
DATABASE_PATHPath to SQLite database/data/emdash.db
HOSTServer host0.0.0.0
PORTServer port4321
S3_ENDPOINTS3 endpoint URLhttps://xxx.r2.cloudflarestorage.com
S3_BUCKETS3 bucket namemy-media-bucket
S3_ACCESS_KEY_IDS3 access keyAKIA...
S3_SECRET_ACCESS_KEYS3 secret key...
S3_PUBLIC_URLPublic URL for mediahttps://cdn.example.com

SQLite requires persistent disk storage. Ensure your hosting platform provides:

  • A mounted volume or persistent disk
  • Write access to the database directory
  • Backup mechanisms for the database file

Add a health check endpoint for load balancers:

src/pages/health.ts
export const GET = () => {
return new Response("OK", { status: 200 });
};

Configure your platform to check /health for liveness probes.