Static sites
Deploy a static site on Ruust: Vite, Create React App, Astro, Hugo or plain HTML, built to a folder and served over HTTPS.
A static site is a folder of .html, .css and .js files with no server code of its own. Ruust has no bare-directory file server, so a static Egg still runs a long-lived web server process (for example npx serve -s dist -l $PORT) that hands out the built output, and Ruust reverse-proxies it. Ruust builds your repo, and your start command serves the output folder your tool produces (dist, build or public, depending on the framework). This covers Vite, Create React App, an Astro static build, Hugo and hand-written HTML.
Ruust detects the stack with Nixpacks and runs the right build. If your repo has a Dockerfile, Ruust builds that instead and ignores auto-detection. Either way the result is one Egg that serves your files.
Deploy it
- Push your site to a Git repo.
- Choose New Egg, then the Type: a Web App (add it to a Coop, or start a new one).
- Choose the Source: connect the repo, or deploy a demo. Nixpacks auto-detects the build (or a
Dockerfilein the repo is used); the detected buildpack card is read-only, there is nothing to confirm. - Choose the Region (London or Virginia), then the Size, and lay the Egg.
Common build commands and output folders: Vite runs npm run build into dist; Create React App runs npm run build into build; Astro runs npm run build into dist; Hugo runs hugo into public. Plain HTML needs no build, so point your start command (for example serve) at the folder holding your index.html.
The port
A static Egg still runs a long-lived web server that hands out your files, and that server must obey the port contract. Ruust sets a PORT env var; the server has to 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. Whichever server you use (for example serve), make sure its start command honours PORT.
web: npx serve -s dist -l $PORTClient-side routing (SPA fallback)
A single-page app (React Router, Vue Router and similar) renders routes in the browser, so a deep link like /dashboard has no matching file on disk. Without a fallback the server returns 404. The fix is to serve index.html for any path that does not map to a real file, and let the client router take over. This is a property of the serve package in your repo, not a Ruust feature: the serve -s flag above does exactly this (-s means single-page). Ruust itself does no index.html rewriting.
Environment variables
Set variables on the Egg. They are available at build and run time, encrypted at rest, and never printed in logs. For a static site the values you want in the browser are baked in at build time, so they need the framework public prefix: VITE_ for Vite, REACT_APP_ for Create React App, PUBLIC_ for Astro. Anything without the prefix is not exposed to the client bundle.
Always on and on HTTPS
A static Egg is a long-running server, so there are no cold starts, the first request is as fast as the rest. Every Egg gets a <name>.<region>.ruust.run URL with TLS. Add your own domain, point the DNS record shown, and Ruust issues and renews the certificate automatically. Egress is unmetered on every size, so a busy static site never runs up a bandwidth bill.