Pulp Engine Document Rendering
Get started
Release v0.18.0

Pulp Engine v0.18.0 — Release Notes

Release and Deployment Maturity

Summary

Prior to this release, Pulp Engine had no immutable production artifact. Operators were required to clone the repository at a git tag, install all dependencies (including build toolchain), generate the Prisma client, and compile TypeScript on the production host. This made deployments slow, non-reproducible across hosts, and rollback ambiguous — “revert” meant re-checking out an older tag and rebuilding.

v0.18.0 introduces Docker-first packaging as the recommended deployment model:

  • Multi-stage Dockerfile — builds a self-contained production image: compiled API code, production-only dependencies (workspace packages resolved), and the Puppeteer/Chromium binary, all bundled together
  • GHCR publishing in release.yml — every git tag push now builds and pushes a versioned image to GitHub Container Registry before creating the GitHub Release, so the image and the release note are always in sync
  • Deployment validation scriptscripts/validate-deploy.sh provides a scriptable post-deploy smoke test covering liveness, readiness, metrics, auth, and the render pipeline
  • Updated deployment guide — Docker quick start, postgres and file mode examples, migration command, rollback procedure, volume mount reference, container env var defaults
  • Concrete rollback procedure — tied to the Docker image tag: rollback is docker stop + docker run v0.PREV.Y, with no build step required
  • Release process checklist — per-release checklist covering pre-release, artifact, deployment, monitoring, and rollback

New files

FilePurpose
DockerfileMulti-stage production image (builder → runtime)
.dockerignoreExcludes dev artifacts, tests, docs, and secrets from the build context
scripts/validate-deploy.shPost-deployment validation script
docs/release-checklist.mdPer-release process checklist (added at top of existing MVP checklist file)

Changed files

FileChange
.github/workflows/release.ymlAdded docker job (build + push to GHCR); release job now depends on docker succeeding
apps/api/package.jsonMoved prisma from devDependencies to dependencies
docs/deployment-guide.mdAdded Docker Deployment section; updated intro
docs/runbook.mdUpdated Rollback section (Docker-first with bare-metal fallback); added validate-deploy.sh reference to smoke tests section

Docker image

Image: ghcr.io/OWNER/pulp-engine:v0.18.0 Tags: v0.18.0 (immutable) and latest (rolling) Base: node:22-slim (runtime stage) Default STORAGE_MODE: file (no database required)

Quick start

# File mode (no database)
docker run -d \
  --name pulp-engine \
  -p 3000:3000 \
  -e API_KEY_ADMIN=your-secret-key \
  -e STORAGE_MODE=file \
  -e TEMPLATES_DIR=/templates \
  -v /var/pulp-engine/templates:/templates:ro \
  -v /var/pulp-engine/assets:/data/assets \
  ghcr.io/OWNER/pulp-engine:v0.18.0

See docs/deployment-guide.md (Docker Deployment section) for postgres mode and full operator instructions.

Postgres migration — same artifact

Migrations now run from the same image tag that serves the API. No repo checkout required on the production host:

docker run --rm \
  -e DATABASE_URL=postgres://user:pass@host:5432/pulp-engine \
  ghcr.io/OWNER/pulp-engine:v0.18.0 \
  node_modules/.bin/prisma migrate deploy \
  --schema src/prisma/schema.prisma

This works because prisma was moved to production dependencies (from devDependencies) in this release. The Prisma schema and migration files are included in the image via pnpm deploy.

Chrome sandbox

PULP_ENGINE_DISABLE_SANDBOX=true is set automatically in the image — this is required for containerised Chrome (no kernel sandbox). Do not unset this variable in Docker/Kubernetes deployments.


Deployment validation script

scripts/validate-deploy.sh is a bash smoke test for post-deployment validation.

./scripts/validate-deploy.sh [BASE_URL] [API_KEY] [TEMPLATE_KEY]
CheckConditionWhat it validates
GET /healthAlwaysLiveness
GET /health/readyAlwaysReadiness / storage reachable
GET /metricsAlwaysPrometheus endpoint + format
GET /templatesAPI_KEY providedAuth configured, template store queryable
POST /render/htmlAPI_KEY + TEMPLATE_KEYFull HTML render pipeline

Exits 0 on success, 1 on any failure. Suitable for use as a CI gate or deployment pipeline step.


Release workflow changes

The release.yml workflow now has two jobs:

  1. docker — builds the multi-stage image and pushes to ghcr.io/OWNER/pulp-engine:{tag} and ghcr.io/OWNER/pulp-engine:latest
  2. release — creates the GitHub Release (depends on docker succeeding)

The image and the GitHub Release are always in sync: if the Docker build fails, no release is created.

latest is updated on every tag push. See docs/release-checklist.md for the policy on patch releases from older branches.


Upgrade notes

Existing bare-metal (non-Docker) deployments: No changes required. The Dockerfile and release workflow additions are purely additive. Existing deployment and rollback procedures continue to work.

prisma moved to production dependencies: If you run pnpm install --prod directly (outside of Docker), prisma will now be included. This is a no-op change for most deployments — the CLI was already installed in the monorepo’s root node_modules.

CI: No changes to ci.yml. Tests, lint, and build steps are unchanged.

No database schema changes. No API breaking changes. No endpoint changes.


What is not in scope (planned follow-up)

  • Multi-architecture Docker image (linux/arm64 support)
  • Editor SPA container or CDN deployment guide
  • Automatic migration in container entrypoint (init-container / K8s Job pattern)
  • Helm chart / Kubernetes manifests
  • Automated version bumping (changeset, semantic-release, or release-it)
  • SQL Server migration from Docker image (requires tsx — currently excluded from the production image)