Astro
Deploy a server-rendered Astro app on Ruust with the @astrojs/node adapter in standalone mode, served on HTTPS.
This guide covers Astro in SSR mode, where pages are rendered on request by a long-running Node server. Ruust builds your repo with Nixpacks, which detects an Astro app from the astro dependency in package.json. If you keep a Dockerfile at the repo root, Ruust builds that instead. For a purely static Astro site with no server-rendered routes, follow the Static sites guide instead. Ruust has no bare-directory file server, so a static Astro Egg still runs a long-lived web server (for example npx serve -s dist -l $PORT) that Ruust reverse-proxies.
For SSR, add the @astrojs/node adapter in standalone mode. Run npx astro add node, then check astro.config.mjs has server output and the standalone adapter. Standalone mode produces a self-contained server at ./dist/server/entry.mjs, which is exactly what an Egg needs (a long-running server, always on). Pin the start command with a Procfile at the repo root (web: node ./dist/server/entry.mjs): the web: line is honoured by the Nixpacks build, which bakes it into the image as the start command at build time, not by Ruust itself, and it is ignored when you supply your own Dockerfile.
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
export default defineConfig({
output: 'server',
adapter: node({ mode: 'standalone' }),
});Deploy it
- Add the
@astrojs/nodeadapter, commitastro.config.mjsand theProcfile, then push your app to a Git repo. - In the dashboard, choose New Egg and connect the repo.
- Pick a size and a region (London, Virginia or your own hardware), then lay the Egg.
- Ruust builds your app with Nixpacks, which runs your package.json build script (this does not apply on the Dockerfile path), and, once it hatches, serves your app on its
<name>.<region>.ruust.runURL over HTTPS.
The port
Ruust sets a PORT env var, and your app must listen on it and bind to 0.0.0.0 (not localhost). Binding to the wrong address is the top reason an Egg builds but never hatches. The standalone entry point reads HOST and PORT from the environment, so you set HOST to 0.0.0.0 and leave PORT for Ruust to provide.
# The entry point reads these at run time.
# Ruust supplies PORT; you supply HOST so it binds publicly.
HOST=0.0.0.0Set env vars on the Egg. They are available at build time and run time, encrypted at rest, and never printed in logs. Server-only secrets (such as a database URL) are read at run time with import.meta.env or process.env and never reach the browser.