VxCloud
⚡Intermediate15 minBackend

Deploy a FastAPI service with managed Postgres

Ship a FastAPI app, provision a MetalDB Postgres alongside it, and wire DATABASE_URL through Vault so the credential never lives in your code or the deploy form.

What you'll build

  • A FastAPI service on port 8000 behind Nginx
  • A managed Postgres instance provisioned in the same flow
  • DATABASE_URL injected from Vault — zero secrets in Git or the UI

Before you begin

  • A registered node with room for Postgres (1 GB RAM minimum)
  • A FastAPI repo (or a .zip) with requirements.txt and app/main.py
  • Completed “Provision your first node”
1

Provision MetalDB Postgres first

Provision the database before the app so its connection string exists when the API boots. Go to Databases → Postgres and fill the form. The credential is written to Vault at workspaces/<org>/<workspace>/metaldb/<db_id>/connection_string — you never copy/paste it.

app.prodxcloud.com/dashboard/development

MetalDB Postgres

1
2
appdb
app
postgres · 14.9▾
20
7
A db.t3.micro with 7-day backups is plenty for a first service.

It posts to the provisioner

Under the hood this is POST /api/v1/infrastructure/services/tenant/provision/databases/; status streams over WebSocket until COMPLETED.
2

Point the FastAPI wizard at your code

Open Development → Deploy → FastAPI. Step 2 accepts either a Git repo or a .zip upload — handy when the code isn’t in a repo yet.

app.prodxcloud.com/dashboard/development

Deploy FastAPI — Application source

2
3
4
orders-service.zip
https://github.com/acme/orders
main
Step 2 — upload a .zip or clone from Git; both land the same way on the node.
3

Wire DATABASE_URL from Vault

Step 3 sets the entry point, requirements file, port, and env. Instead of pasting the password, reference the Vault path the database wrote. The platform resolves it on the node at start time.

app.prodxcloud.com/dashboard/development

Deploy FastAPI — Application settings

3
4
app/main.py
requirements.txt
DATABASE_URL=vault:metaldb/appdb#connection_string PYTHONUNBUFFERED=1
8000 / 80
Step 3 — DATABASE_URL points at a Vault path, not a literal secret.

Why the vault: prefix

Anything starting vault: is resolved on the node at runtime. The plaintext password is never in the deploy request, the database, or your repo.
4

Deploy and verify connectivity

Allocate resources and deploy. Watch both halves come together:

Deployment progress100%
  • Resolve DATABASE_URL from Vault15%
  • pip install -r requirements.txt50%
  • Start uvicorn on :8000 + Nginx proxy80%
  • DB connection check100%
The DB connection check fails fast if the Vault path or network is wrong — no silent half-deploys.
verify
$ curl -s https://orders.<node>/healthz
{"db":"connected","version":"PostgreSQL 14.9"}
FastAPI ↔ MetalDB Postgres wired through Vault

App + database, no leaked secrets

You have a stateful service whose only secret lives in Vault. Add scheduled backups and a read replica in the dedicated MetalDB tutorial.

Nice work — you're done!

You completed Deploy a FastAPI service with managed Postgres. Keep the momentum going with the next walkthrough, or jump back to the full catalog.