Fly.io, Render, Railway, AWS, Cloud Run
Deployment Targets
Fastify deploys anywhere Node runs. Pick a target by latency, scaling model, and cost.
What you'll learn
- Deploy as a container to Cloud Run, Fly, Render, or Railway
- Self-host on a VM with Hetzner, EC2, or similar
- Set NODE_ENV=production and trustProxy correctly
Fastify runs on plain Node, so anything that hosts Node hosts Fastify. The choice is mostly about scaling model and cost.
Containers (Cloud Run, Fly.io, Render, Railway)
If you already have a Dockerfile, these platforms are mostly “push, get a URL”. Cloud Run scales to zero; Fly keeps a small machine warm; Render and Railway are in between.
# Fly
fly launch --dockerfile Dockerfile --name my-api
fly deploy
# Render and Railway pick up Dockerfile automatically on push. Self-Hosted (Hetzner, EC2, VPS)
Build the Docker image, push to GHCR, then docker run on the box with --restart unless-stopped.
Or skip Docker and use systemd directly (covered in the next lesson).
Required Environment
const app = Fastify({
logger: true,
trustProxy: true,
});
await app.listen({
host: '0.0.0.0',
port: Number(process.env.PORT) || 3000,
}); NODE_ENV=production— strips dev-only behaviors, disablespino-pretty.trustProxy: true— required behind any load balancer, otherwiserequest.ipis the LB IP.host: '0.0.0.0'— bind on all interfaces inside a container.
Graceful Shutdown
Most platforms send SIGTERM before killing the process. Drain in-flight requests:
for (const sig of ['SIGTERM', 'SIGINT'] as const) {
process.on(sig, async () => {
await app.close();
process.exit(0);
});
}