Skip to content

Dokploy (Docker)

The site is server-rendered with the Astro Node adapter and the EmDash CMS, so it deploys as a long-running Node server rather than static files. The repo ships a multi-stage Dockerfile that builds a standalone server (dist/server/entry.mjs).

  1. Push the repo to GitHub.
  2. In Dokploy, create an Application from the repository using the Dockerfile build.
  3. Mount a persistent volume at /app/data. This holds the SQLite database (emdash.db) and any local uploads, so content survives redeploys.
  4. Set environment variables (see Environment Variables): SITE_URL, the S3_* Cloudflare R2 credentials, and any optional analytics keys.
  5. Expose port 4321 and point your domain at the service.
  6. Deploy. On a fresh volume, the entrypoint seeds content automatically (below).

In production, media is stored in Cloudflare R2 through its S3-compatible API. Create an R2 bucket and an S3 API token, then set S3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY_ID, and S3_SECRET_ACCESS_KEY. If S3_BUCKET is unset, EmDash falls back to local filesystem storage under ./data/uploads.

Uploads PUT directly to R2 from the browser via presigned URLs, so the bucket needs a CORS policy allowing your site origin (GET, PUT, HEAD). The bucket can stay private — EmDash serves media through its own proxy route (/_emdash/api/media/file/<key>) that streams objects from R2, so URLs always look same-origin and S3_PUBLIC_URL is not needed. See Environment Variables → Media storage for the exact CORS policy and details.

The SQLite database is runtime state and is not committed to git - it lives on the /app/data volume. On deploy:

  • The server runs schema migrations automatically on the first request, creating the database and tables on the volume.
  • The container docker-entrypoint.sh runs emdash seed from seed/seed.json only when no database exists yet (a fresh volume), so a first deploy comes up populated and redeploys never overwrite your data.

To seed or re-seed manually (e.g. outside Docker):

Terminal window
pnpm exec emdash seed --database data/emdash.db --uploads-dir data/uploads

Afterwards, content is edited through the admin panel at /_emdash/admin (create the owner account on first visit) and requires no redeploy.

Terminal window
docker build -t astro-emdash .
docker run --rm -p 4321:4321 -v "$PWD/data:/app/data" astro-emdash