---
title: "Deploy PostgreSQL"
description: "PostgreSQL 17 with persistent storage and extensions preinstalled."
category: "Storage"
url: https://railway.com/deploy/postgresql-2
---

# Deploy PostgreSQL

PostgreSQL 17 with persistent storage and extensions preinstalled.

**[Deploy PostgreSQL on Railway](https://railway.com/template/postgresql-2)**

Machine-readable deploy manifest (JSON, validated by TemplateCI): https://railway.com/deploy/postgresql-2/manifest.json

- **Creator:** wotonews
- **Category:** Storage

## Template content

### postgres

- **Image:** wotonews/postgres:v17.11-2

## Documentation

# Deploy and Host PostgreSQL with Railway

PostgreSQL is the world's most advanced open-source relational database. This template deploys a single-node PostgreSQL 17 server with a persistent volume and five widely-used contrib extensions preinstalled on first boot.

## About Hosting PostgreSQL

Hosting PostgreSQL on Railway runs the official `postgres:17.11-alpine` image (plus a thin extension layer) as a private-network service with a persistent volume at `/var/lib/postgresql/data`. Data survives redeploys and restarts. The superuser password is auto-generated at deploy time via Railway's `secret()` function, and a `DATABASE_URL` variable is composed from the service's private hostname so other services in the same project can connect with a single reference — no public exposure required.

Extensions `pgcrypto`, `pg_trgm`, `unaccent`, `citext`, and `uuid-ossp` are created on first boot into your database and into `template1`, so databases created later inherit them too.

This is a single-node deployment without replication — the building block most self-hosted apps need. For automated failover and a streaming read replica, see our `Postgres HA Read Replica` template instead.

## Why Deploy PostgreSQL on Railway?

- **One platform:** host your database next to your apps, APIs, and AI agents with private networking between them.
- **Zero-config secrets:** the superuser password is generated at deploy time; nothing is hardcoded.
- **Persistent by default:** the data volume is attached out of the box.
- **Scale when needed:** vertical scaling takes seconds; no cluster YAML required.

## Common Use Cases

- Backend database for self-hosted web apps and APIs (works out of the box with our Paperclip and Multica templates).
- Trigram search (`pg_trgm`) for search features without extra infrastructure.
- UUID-primary-key schemas via `pgcrypto` / `uuid-ossp`.
- Scratch/analytics database for agents and cron jobs on the private network.

## Dependencies for PostgreSQL Hosting

- Docker image: [`postgres:17.11-alpine`](https://hub.docker.com/_/postgres) (official, pinned)
- Extensions: PostgreSQL contrib — `pgcrypto`, `pg_trgm`, `unaccent`, `citext`, `uuid-ossp`

### Deployment Dependencies

- Source: https://github.com/postgres/postgres (upstream)
- Image source of truth: this repository's `Dockerfile`
- Docs: https://www.postgresql.org/docs/17/

## Environment Variables

| Name | Required | Default | Description |
| :--- | :---: | :--- | :--- |
| `POSTGRES_PASSWORD` | **yes** | *generated* | Superuser password — auto-generated via `${{secret(20)}}` at deploy time. |
| `POSTGRES_USER` | no | `app` (image default) | Database owner and superuser name (first boot only). Override by setting the variable. |
| `POSTGRES_DB` | no | `app` (image default) | Database created on first boot; extensions installed into it. Override by setting the variable. |

&gt; **Note:** `POSTGRES_USER` / `POSTGRES_DB` / `POSTGRES_PASSWORD` only take effect on **first boot**, before any data exists — after that, manage users and databases with SQL.

## Connect From Another Service

In the same Railway project, add a variable to your app service. With the defaults, compose:

```
DATABASE_URL = postgres://app:${{postgres.POSTGRES_PASSWORD}}@${{postgres.RAILWAY_PRIVATE_DOMAIN}}:5432/app
```

Traffic stays on Railway's private network (`postgres.railway.internal`). No public domain is generated for the database by default — keep it that way unless you have a specific need, and restrict any exposed domain accordingly.

## Local Setup

```bash
cp .env.example .env   # edit POSTGRES_PASSWORD
docker build -t wotonews/postgres:v17.11-2 .
docker run -d --name postgres -p 5432:5432 --env-file .env \
  -v pgdata:/var/lib/postgresql/data wotonews/postgres:v17.11-2
psql postgres://app:change-me@localhost:5432/app
```

## Deploy to Railway

Deploy this template from the Railway marketplace, or from the repository root:

```bash
railway init --name my-postgres
railway add --service postgres
railway variables set POSTGRES_PASSWORD=$(openssl rand -hex 12)
railway deploy --image wotonews/postgres:v17.11-2
railway volume add --mount-path /var/lib/postgresql/data --service postgres
```



## Backups

This template does not include managed backups. Use `pg_dump` over `railway ssh` on a schedule, or enable Railway's database backup features available on plans that include them.


## Similar templates

- [Garage S3 Storage](https://railway.com/deploy/garage-s3-storage) — Ultra-light S3 server: fast, open-source, plug-and-play.
- [Redis](https://railway.com/deploy/redis-1) — Self Host Latest Redis with Railway
- [EasyImg](https://railway.com/deploy/easyimg) — Simple self-hostable Nuxt.js personal image hosting system.

Open this page in a browser: https://railway.com/deploy/postgresql-2
