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, usually within a couple of minutes — SSR via the Node adapter, or a static build served from a container.

TL;DR
For dynamic sites, use @astrojs/node in standalone mode — PreviewDrop detects Astro, builds the image and 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.

What the build needs to do

You don't write this. PreviewDrop detects Astrofrom your repo and builds the container for you — a Dockerfile in your repo is not used. The reference below shows the install, build and start steps a working Astro image needs. If detection gets one wrong, set the matching Install, Build or Start command in Project Settings. Your app must listen on $PORT.

Reference (not read by PreviewDrop)
FROM 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.

VariableExample valueNote
PORT4321The Node adapter reads PORT (or HOST/PORT) automatically.
HOST0.0.0.0Makes the SSR server reachable from the proxy.
DATABASE_URLpostgres://user:pass@host:5432/dbFor 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 Start command 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 (PreviewDrop sets it in the container) 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 — keep them in dependencies, not devDependencies. (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. We detect the app and 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