PostgreSQL
Deploy fully managed PostgreSQL databases on Hostess with automatic backups, connection management, and scoped databases.
Overview
The postgres service type provisions a fully managed PostgreSQL database. Unlike application services, you do not need to provide a Dockerfile or build configuration — Hostess handles provisioning, configuration, backups, and connection management for you.
services:
database:
type: postgresThat is the simplest possible Postgres service. Hostess provisions a PostgreSQL instance with medium resources (1 CPU, 1Gi memory, 20Gi storage) and makes it available to other services via magic variables.
Defaults
When you use type: postgres, Hostess applies the following defaults:
| Setting | Default Value |
|---|---|
| Port | 5432 |
| Health check | pg_isready |
| Resources | medium (1 CPU, 1Gi memory, 20Gi storage) |
| Backups | Not configured (must be explicitly enabled) |
| Username | postgres |
| Database name | Same as the service name |
Resource Presets and Storage
PostgreSQL databases need CPU, memory, and persistent storage. You can use resource presets or configure resources explicitly.
services:
database:
type: postgres
resources: large| Preset | CPU | Memory | Storage |
|---|---|---|---|
small | 0.5 cores | 512Mi | 10Gi |
medium | 1.0 cores | 1Gi | 20Gi |
large | 2.0 cores | 2Gi | 50Gi |
xlarge | 4.0 cores | 4Gi | 100Gi |
Use a preset for CPU and memory but override the default storage:
services:
database:
type: postgres
resources:
preset: large
storage: 200GiThis gives you the large preset's CPU (2.0 cores) and memory (2Gi) with 200Gi of storage instead of the default 50Gi.
For full control, specify CPU, memory, and storage individually:
services:
database:
type: postgres
resources:
cpu: 2.0
memory: 4Gi
storage: 100GiChoosing the Right Resources
| Use Case | Recommended Preset | Custom Storage |
|---|---|---|
| Development and testing | small | Default (10Gi) |
| Small production app | medium | Default (20Gi) |
| Standard production database | large | 50-200Gi |
| High-traffic, large dataset | xlarge | 200Gi-1Ti |
Storage can be increased after initial deployment but cannot be decreased. Choose a size that gives you room to grow.
Backups
Hostess supports automatic scheduled backups for PostgreSQL databases. Backups are not enabled by default — you must configure them explicitly.
Shorthand Form
The simplest way to enable backups is with a schedule preset:
services:
database:
type: postgres
backups: dailyAvailable schedule presets: daily, weekly, biweekly, monthly.
Full Form
For more control over the schedule and retention:
services:
database:
type: postgres
backups:
schedule: daily
retention: 14 # Keep the last 14 backupsYou can also use a cron expression for custom schedules:
services:
database:
type: postgres
backups:
schedule: "0 3 * * *" # Every day at 3 AM UTC
retention: 30Backup Configuration Reference
| Field | Type | Default | Description |
|---|---|---|---|
schedule | string | - | daily, weekly, biweekly, monthly, or a 5-field cron expression |
retention | number | 7 | Number of backups to keep. Must be between 1 and 365. |
Backups are critical for production databases. Always configure backups for any database that stores data you cannot afford to lose.
Managing Backups
You can view backup history, create manual backups, and restore from backups in Hostess Studio or via the CLI:
# List backups for a service
hostess backups list --service database
# Create a manual backup
hostess backups create database
# Restore from a specific backup
hostess backups restore database --backup 20250326-020003-scheduled.sql.gzSee the CLI backups reference for all available commands and options.
Connecting from Other Services
Other services connect to your Postgres database using magic variables. Hostess automatically generates secure credentials and constructs connection URLs for you.
Magic Variables
When you define a type: postgres service, the following magic variables become available to any service that references it:
| Variable | Description |
|---|---|
${database.url} | Private PostgreSQL connection URL with credentials |
${database.host} | PostgreSQL hostname |
${database.port} | PostgreSQL port number |
${database.user} | Username |
${database.database} | Database name |
${database.password} | Auto-generated password |
Replace database with your actual service name. If your service is called pg, use ${pg.url}. If it is called main-db, use ${main-db.url}.
Basic Connection Example
services:
api:
type: fastapi
build:
source: ./backend
env:
DATABASE_URL: ${database.url}
depends_on:
- database
database:
type: postgres
resources: mediumThe ${database.url} magic variable resolves to a full private PostgreSQL connection string. Your application just reads it from the DATABASE_URL environment variable — no manual configuration needed.
Connection Options
| Scenario | Variable | Why |
|---|---|---|
| Backend connecting to database | ${database.url} | Internal URL — stays inside the Hostess network, lowest latency |
| Passing individual fields to an ORM | ${database.host}, ${database.port}, etc. | Some ORMs require individual connection parameters |
Local Access
To connect to your Postgres database from your local machine (for development, debugging, or running queries), use the hostess connect command:
hostess connect databaseThis establishes a secure tunnel to your database and prints a local connection URL plus a psql command. You can also choose a local port for external tools like pgAdmin or TablePlus:
# Bind the local tunnel to a specific port
hostess connect database --local-port 15432Then connect your database client to the local host and port shown in the command output.
See the CLI connect reference for all available options.
Scoped Databases
By default, all services that reference ${database.url} share the same database. If you need database isolation between services — for example, keeping your auth service's data separate from your analytics service — use scoped databases.
Explicit Group Map
Define named groups that map to lists of consuming services:
services:
api:
type: fastapi
env:
DATABASE_URL: ${postgres.url}
depends_on:
- postgres
worker:
type: custom
image: my-worker:latest
env:
DATABASE_URL: ${postgres.url}
depends_on:
- postgres
scheduler:
type: custom
image: my-scheduler:latest
env:
DATABASE_URL: ${postgres.url}
depends_on:
- postgres
postgres:
type: postgres
databases:
main: [api, worker]
analytics: [scheduler]In this setup:
apiandworkershare a database namedpostgres__mainschedulergets its own database namedpostgres__analytics- The
${postgres.url}magic variable resolves differently per service based on which group the service belongs to
Per-Service Sugar
If every consuming service should get its own isolated database:
services:
postgres:
type: postgres
databases: per_serviceThis automatically creates one database group per service that references ${postgres.url}. For example, if api and worker both reference the database, they each get their own isolated database (postgres__api and postgres__worker).
Scoped Database Rules
- A service that references
${<database>.url}must belong to exactly one group - A service cannot appear in multiple groups for the same database
- Group names must be DNS-safe (lowercase alphanumeric and hyphens)
- When
databasesis configured,${database.database}resolves to the scoped database name (e.g.,postgres__main)
Complete Examples
Simple Database
version: "1.0"
services:
api:
type: fastapi
build:
source: .
env:
DATABASE_URL: ${database.url}
depends_on:
- database
database:
type: postgresProduction Database with Backups
version: "1.0"
name: my-app
services:
api:
type: fastapi
build:
source: ./backend
env:
DATABASE_URL: ${database.url}
depends_on:
- database
lifecycle:
migrate:
command: ["alembic", "upgrade", "head"]
database:
type: postgres
resources:
preset: large
storage: 100Gi
backups:
schedule: daily
retention: 30Scoped Databases for Microservices
version: "1.0"
name: microservices-platform
services:
auth-service:
type: fastapi
build:
source: ./services/auth
env:
DATABASE_URL: ${postgres.url}
depends_on:
- postgres
user-service:
type: fastapi
build:
source: ./services/users
env:
DATABASE_URL: ${postgres.url}
depends_on:
- postgres
analytics-service:
type: custom
build:
source: ./services/analytics
env:
DATABASE_URL: ${postgres.url}
depends_on:
- postgres
postgres:
type: postgres
resources:
preset: large
storage: 200Gi
databases:
auth: [auth-service]
users: [user-service]
analytics: [analytics-service]
backups:
schedule: daily
retention: 14Multiple Postgres Instances
You can define multiple Postgres services in the same project if you need completely separate database instances:
version: "1.0"
name: multi-db
services:
api:
type: fastapi
build:
source: ./backend
env:
MAIN_DB_URL: ${main-db.url}
ANALYTICS_DB_URL: ${analytics-db.url}
depends_on:
- main-db
- analytics-db
main-db:
type: postgres
resources: large
backups: daily
analytics-db:
type: postgres
resources: xlarge
backups: weekly