Astro deploys on Hangar in either of its modes. A static site is built once and served as files. With server rendering, Astro runs as a Node.js server in a container, so on-demand pages, API endpoints and sessions work.
Before you start
- An Astro project in a Git repository, with its lockfile.
- A Hangar account.
1. Choose the output
A static site needs nothing: it is Astro's default output.
For server rendering, add the Node adapter in standalone mode:
npx astro add node
// astro.config.mjs
import node from "@astrojs/node";
export default defineConfig({
output: "server",
adapter: node({ mode: "standalone" }),
});
2. Create the service
Create a project, add a service and pick your repository and branch. Leave the builder on Automatic. It installs dependencies with the package manager of your lockfile, runs astro build and then:
- for a static site, serves the
distfolder with the Caddy web server, with gzip and zstd compression and clean URLs, so/aboutservesabout.htmlorabout/index.html; - with the Node adapter, builds a Node.js server and makes it listen on every interface.
3. Start the server
Skip this step for a static site.
With server rendering, set the start command in Settings → Runtime:
node ./dist/server/entry.mjs
The standalone server listens on PORT, which Hangar sets to the domain's container port.
4. Deploy and add a domain
Deploy the service. In Settings → Networking, add a domain with HTTPS on and leave the container port at 3000. Both outputs listen on PORT, which follows the container port, so any port works as long as you don't set PORT yourself.
A static site changes only when you deploy. With server rendering, variables your pages read at request time, such as API keys, come from the environment when the server runs; values used during astro build must be set before the deploy that builds them.
Adding a database
With server rendering, add a PostgreSQL service in the same project and region, copy its internal connection URL and set it as DATABASE_URL on the site. Read it in server code with process.env.DATABASE_URL. See Databases.
Troubleshooting
- 502 on the domain: a
PORTvariable you set differs from the container port. Remove it, or make the two match. - The server does not start: the start command is missing, or the adapter is not in standalone mode.