PreviewDrop for Astro
Deploy previews for Astro apps
Push a branch, get a live preview URL. PreviewDrop builds your Astro site and runs it behind a TLS-terminated subdomain in under 60 seconds — SSR via the Node adapter, or a static build served from a container.
TL;DR
For dynamic sites, use
@astrojs/node in standalone mode and the Dockerfile below — PreviewDrop runs dist/server/entry.mjs as a real Node process so SSR routes and API endpoints work. Static Astro sites build to dist/ and can be served by any static file server instead.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 AS build WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . # astro.config: output: 'server', adapter: node({ mode: 'standalone' }) RUN npm run build FROM node:22-slim WORKDIR /app ENV NODE_ENV=production HOST=0.0.0.0 COPY --from=build /app/dist ./dist COPY --from=build /app/node_modules ./node_modules COPY --from=build /app/package.json ./package.json EXPOSE 4321 CMD ["node", "./dist/server/entry.mjs"]
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 | 4321 | The Node adapter reads PORT (or HOST/PORT) automatically. |
| HOST | 0.0.0.0 | Makes the SSR server reachable from the proxy. |
| DATABASE_URL | postgres://user:pass@host:5432/db | For SSR endpoints that hit a database. Omit for purely static sites. |
Common gotchas
Use @astrojs/node standalone for a runnable server
A Node server only exists when
output: 'server' (or 'hybrid') and the @astrojs/node adapter in mode: 'standalone' are configured. Otherwise there’s no entry.mjs to run.Static Astro? Skip the Node server entirely
With the default
output: 'static', Astro emits a plain dist/ of HTML/CSS/JS. Serve it with a tiny static server — e.g. a runtime CMD of npx serve dist -l $${PORT} — instead of the Node adapter. Lighter and faster to build.Bind to 0.0.0.0
Set
HOST=0.0.0.0 (done in the Dockerfile) so the SSR server listens on all interfaces — the default localhost bind is unreachable from the proxy.Runtime needs node_modules for SSR
Unlike Nuxt’s bundled output, the Astro Node adapter resolves your server dependencies from
node_modules at runtime — the Dockerfile copies them into the runtime stage. (Not needed for the static path.)Why not Vercel or Netlify?
Static Astro deploys anywhere, and Vercel/Netlify host it well — PreviewDrop is the choice when you run SSR Astro and want to self-host the Node server, need password-protected previews, prefer flat per-workspace pricing, or want Astro previews living next to a backend service in one tool. You bring a Dockerfile; we run it behind HTTPS for every branch.
Preview your Astro app in 5 minutes
Connect a repo, push a branch, get a URL. No credit card, no trial clock.
Start free