PreviewDrop for Express
Deploy previews for Express & Node.js apps
Push a branch, get a live preview URL. PreviewDrop installs your dependencies, runs your Node server as a real process, and posts the link to the pull request in under 60 seconds.
TL;DR
Add a Dockerfile, connect your repo, push. PreviewDrop runs
npm ci and boots node server.js behind a TLS-terminated subdomain. Because it’s an always-on process, your websockets, SSE streams, in-memory caches and persistent DB pools all behave exactly as they do locally.Dockerfile
Drop this at the root of your repo. PreviewDrop picks it up on the next push and builds it into a container behind a TLS-terminated subdomain.
DockerfileFROM node:22-slim WORKDIR /app COPY package*.json ./ RUN npm ci --omit=dev COPY . . # If you have a build step (TypeScript / bundler), run it here: # RUN npm run build -> then CMD ["node", "dist/server.js"] EXPOSE 3000 CMD ["node", "server.js"]
Environment variables
Set these in the Variables tab of your PreviewDrop project. They're encrypted at rest and injected into every preview container at start.
| Variable | Example value | Note |
|---|---|---|
| PORT | 3000 | PreviewDrop injects this. Read it with process.env.PORT and listen on it. |
| NODE_ENV | production | Enables Express production optimisations and disables verbose error pages. |
| DATABASE_URL | postgres://user:pass@host:5432/db | Point at a shared dev DB, or omit for stateless previews. |
Common gotchas
Listen on 0.0.0.0 and read process.env.PORT
Use
app.listen(process.env.PORT || 3000, '0.0.0.0'). Omitting the host can bind to localhost inside the container, which the proxy can’t reach — the preview will 502.Commit your lockfile
npm ci requires a committed package-lock.json and fails without one. If you don’t keep a lockfile, switch the build line to npm install --omit=dev. (pnpm / yarn work too — use their install + lockfile.)Let the image build node_modules
Add a
.dockerignore with node_modules so your host’s modules aren’t copied in. Native modules (bcrypt, sharp, better-sqlite3) compile per-platform — a macOS/Windows node_modules will crash inside the Linux container.Run your build step in the image
If you ship TypeScript or a bundler, add
RUN npm run build and point the CMD at the compiled output (node dist/server.js). Don’t rely on ts-node in previews — it’s slower and pulls dev deps you excluded with --omit=dev.Why not Vercel or Netlify?
Vercel runs Express by wrapping the whole app in a serverless function: every request cold-boots the app, websockets and long-lived SSE connections break, and you can’t hold an in-memory cache or a persistent database pool between requests. PreviewDrop runs
node server.js as a genuine always-on process — the same way it runs in production.Preview your Express app in 5 minutes
Connect a repo, push a branch, get a URL. No credit card, no trial clock.
Start free