Deploy Astro on Temps
Temps doesn't detect Astro from astro.config.*, so you pick the preset. A static Astro site uses the Vite preset: Temps runs astro build and serves dist/ from its proxy with no container. For on-demand rendering, add @astrojs/node in standalone mode, choose the Autopack (Node.js) preset and start dist/server/entry.mjs from a Procfile.
For an overview of self-hosting Astro, including costs, see Deploy Astro to your own server. Every framework and the preset it needs is listed under Supported platforms.
Quickstart
An astro.config.* is not a detection signal. A project that also has a vite.config.* is detected as a Vite build; otherwise deploying without a preset stops with "Could not auto-detect project type from files". Pick the preset that matches your output:
| Your site | Preset | Command |
|---|---|---|
Static (the default output: 'static', no adapter) | Vite (vite) | up --preset vite |
On-demand rendering with @astrojs/node | Autopack (Node.js) (nixpacks-node) | up --preset nixpacks-node |
You can also set the preset under Project → Settings → Build & deploy → Build → Framework.
# Static site npx @temps-sdk/cli up --preset vite
Static Astro
The Vite preset installs dependencies with the package manager your lockfile points to, runs your build script (astro build) and serves dist/ as static files from the Temps proxy. No container runs.
| Feature | How Temps handles it |
|---|---|
| Build | Your build script (astro build) |
| Output | Serves dist/, or the build.output_dir set in .temps.yaml |
| Routes | /about serves dist/about/index.html |
| Unknown paths | Fall back to the root index.html |
| HTTPS | Let's Encrypt, auto-renewed |
| Cache | Hashed assets get long-lived cache headers |
Don't use astro preview as a production server. It's meant for checking a build locally.
On-demand rendering with the Node adapter
This guide describes how the nightly release channel builds your app, using the Autopack builder. Beta (v0.1.0-beta.56) also builds with Autopack, but some details below may differ. Earlier releases and the stable channel build with Nixpacks and behave differently. To run nightly, see Release channels.
To render pages on request, add the Node adapter in standalone mode:
npx astro add node
// astro.config.mjs
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';
export default defineConfig({
output: 'server',
adapter: node({ mode: 'standalone' }),
});
Choose the Autopack (Node.js) preset (nixpacks-node). Temps runs your build script, but a new Astro project has no start script for the built server, so add a Procfile to the repository root. A web: line takes priority over any start script:
Procfile
web: node ./dist/server/entry.mjs
npx @temps-sdk/cli up --preset nixpacks-node
The standalone server reads the HOST and PORT variables, and Temps sets both (HOST is 0.0.0.0), so it listens where the health check can reach it. It also serves the prerendered pages and assets from dist/client/. The Node.js version comes from .nvmrc, .node-version or engines.node in package.json, and defaults to 24.
Platform behavior
The one requirement: your app must listen on the port in the PORT environment variable and bind to 0.0.0.0 — not localhost or 127.0.0.1. Temps runs your app in a container and routes traffic from the host, so an app bound to localhost only accepts connections from inside the container and will fail its health check.
Health checks
After your container starts, Temps sends HTTP GET requests to verify it is healthy before routing traffic to it.
- Path:
/(the root of your application) by default - Success: 2 consecutive responses with a 2xx, 3xx, 404 or 405 status code
- Timeout: 300 seconds (5 minutes) for the app to become healthy, fixed in v0.1.0-beta.56. If the app answers with error responses (other 4xx, or 5xx) for 60 seconds in a row, the deployment fails sooner. From the next release the timeout is configurable from 30 to 3600 seconds under Project → Settings → Build & deploy
- Retry interval: 2 seconds between successful checks, 5 seconds after an error response or a failed connection
Connection errors and other 4xx or 5xx responses are retried until the timeout; if the app hasn't passed by then, the deployment fails. The check runs once, at deploy time. To check a different path, add a .temps.yaml to your repository root:
health:
path: /healthOnly path is used. Other health fields (status, interval, timeout, retries) are accepted but currently have no effect.
/health endpoint that returns a simple 200. This avoids issues where / requires authentication or returns a redirect.Mixed static and on-demand pages
Astro 5 folded the old hybrid mode into static. With the Node adapter installed and output: 'static', every page is prerendered at build time unless it opts out:
src/pages/dashboard.astro (frontmatter)
export const prerender = false;
Pages that opt out render on each request, so deploy this setup the same way as on-demand rendering: Autopack (Node.js) preset and the Procfile above.
Content collections
Content collections work the same on Temps: Markdown, MDX and JSON content is bundled at build time and served statically or rendered on request, as configured.
Environment variables
npx @temps-sdk/cli environments vars set PUBLIC_SITE_URL "https://yourdomain.com" -e production
PUBLIC_ variables are inlined at build time, so deploy again after changing one. With the Node adapter, server code can read other variables at runtime.
Caching
These headers apply to static Astro sites served by the Temps proxy.
The Temps proxy sends ETags with static files, so a browser that already has an unchanged file gets 304 Not Modified instead of downloading it again. The proxy doesn't compress static files.
Cache-Control headers are set based on the file path:
| Pattern | Cache-Control | Use case |
|---|---|---|
/assets/*, /static/*, /_next/static/*, .chunk.*, .hash.* | public, max-age=31536000, immutable | Hashed assets that never change |
| Everything else | public, max-age=0, must-revalidate | HTML files and non-hashed resources |
Your hashed JS and CSS bundles are cached for a year, while index.html is always revalidated so new deployments are picked up immediately.
Building a documentation site? See Deploy Docusaurus.