Deploy Next.js + FastAPI + Postgres
Deploy a full-stack application with a React frontend, Python API, and managed database.
This tutorial walks through deploying a complete full-stack application from the howl-cloud/awesome-hostess examples repo: a Next.js frontend, a FastAPI backend, and a managed PostgreSQL database.
Prerequisites
- A Hostess account — sign up at hostess.sh if you don't have one
- Hostess CLI installed and authenticated (
hostess login) - Git installed locally
- Docker installed for local Compose testing and image builds
What You'll Deploy
- Frontend — Next.js app rendered with data from the API
- API — FastAPI backend with a small Postgres migration
- Database — Hostess-managed PostgreSQL with persistent storage
The frontend talks to the API through Hostess service discovery. The API connects to Postgres using the generated ${database.url} connection string. A migration runs before the API starts.
Clone the example app
Clone the Hostess examples repo and move into the full-stack app:
git clone https://github.com/howl-cloud/awesome-hostess.git
cd awesome-hostess/simple-full-stackThe example includes both services, local Compose wiring, and Hostess config:
Test locally with Docker Compose
Run the whole stack locally:
docker compose up --buildCompose starts Postgres first, runs the API migration, starts FastAPI, and then starts the Next.js frontend.
Open the frontend:
open http://localhost:3000Check the API directly:
curl http://localhost:8000/api/statusExpected response:
{
"api": "ok",
"database": "ok",
"event_count": 1,
"latest_event": "First full-stack deployment"
}Review the Hostess config
The example's hostess.yml declares all three services:
version: "1.0"
name: simple-full-stack
description: Minimal Next.js, FastAPI, and Postgres app for the Hostess guide.
services:
database:
type: postgres
resources:
preset: small
storage: 10Gi
retention: permanent
api:
type: fastapi
public: true
build:
source: ./backend
dockerfile: Dockerfile
env:
DATABASE_URL: ${database.url}
CORS_ORIGINS: ${frontend.external_url}
depends_on:
- database
resources: small
lifecycle:
migrate:
command: ["python", "-m", "app.migrate"]
on_failure: abort
timeout: 5m
health:
http: /health
frontend:
type: nextjs
build:
source: ./frontend
dockerfile: Dockerfile
env:
API_URL: ${api.url}
depends_on:
- api
resources: smallKey points:
${database.url}injects the generated Postgres connection string into the API.lifecycle.migraterunspython -m app.migratebefore the API rollout.${api.url}gives the Next.js server an internal API URL for server-side rendering.public: trueexposes the API as well as the frontend, so you can test both services after deploy.
Validate the config
From awesome-hostess/simple-full-stack, run:
hostess validateYou should see:
✓ Configuration is validDeploy
Deploy all three services together:
hostess deployIf this is your first deployment, Hostess will prompt you to create a project:
No project found. Create one?
? Project name: simple-full-stack
✓ Project "simple-full-stack" created
Environment: preview
✓ Deployment complete (dep_abc123)
frontend: https://simple-full-stack-frontend-k7xm9p2q.hostess.run
api: https://simple-full-stack-api-a3x9d2m1.hostess.runHostess deploys in dependency order:
databasestarts first.apiwaits for the database, runs the migration, then starts FastAPI.frontendwaits for the API, then starts Next.js.
Test the deployment
Open the frontend URL from the deploy output:
https://simple-full-stack-frontend-k7xm9p2q.hostess.runCheck the API:
curl https://simple-full-stack-api-a3x9d2m1.hostess.run/api/statusCreate another database-backed event:
curl -X POST https://simple-full-stack-api-a3x9d2m1.hostess.run/api/events \
-H "Content-Type: application/json" \
-d '{"message": "Hello from Hostess"}'Refresh the frontend. The event count should increase.
View in Studio
Open hostess.sh to inspect the deployment in Studio. You can:
- View the frontend, API, and database services
- Inspect logs and deployment history
- Monitor CPU and memory usage
- Connect to Postgres for debugging
How the Pieces Fit
Frontend
The Next.js app is a server-rendered frontend. It reads API_URL at runtime and fetches /api/status from the FastAPI service:
frontend:
type: nextjs
env:
API_URL: ${api.url}Use ${api.url} here because the request is server-to-server inside Hostess. If browser-side JavaScript needs to call the API directly, use a public API URL and CORS intentionally.
API
The FastAPI service receives the Postgres URL and runs a migration before rollout:
api:
type: fastapi
env:
DATABASE_URL: ${database.url}
lifecycle:
migrate:
command: ["python", "-m", "app.migrate"]
on_failure: abortIf the migration fails, the deployment stops before replacing the running API.
Database
The Postgres service uses persistent storage:
database:
type: postgres
resources:
preset: small
storage: 10Gi
retention: permanentHostess provisions credentials, service DNS, storage, health checks, and the ${database.url} magic variable.
What's Next
- Database Migrations — Deep dive into migration strategies
- Custom Domains — Add branded frontend and API domains
- Deploy Specific Services — Deploy only the frontend or backend independently
- Managing Secrets — Add API keys and environment-specific secrets