---
title: "Deploy PostGIS"
description: "PostgreSQL 17 with PostGIS 3.5 for maps, geocoding and spatial queries."
category: "Storage"
url: https://railway.com/deploy/postgis-postgres
---

# Deploy PostGIS

PostgreSQL 17 with PostGIS 3.5 for maps, geocoding and spatial queries.

**[Deploy PostGIS on Railway](https://railway.com/template/postgis-postgres)**

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

- **Creator:** blueorange
- **Category:** Storage

## Template content

### PostGIS https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/postgres.svg

- **Image:** postgis/postgis:17-3.5

## Documentation

# Deploy and Host PostGIS on Railway

![PostgreSQL with the PostGIS spatial extension](https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/postgresql.png)

PostGIS turns PostgreSQL into the most widely used open-source spatial database. It adds geometry and geography types, spatial indexes and hundreds of functions for distance, intersection, buffering, projections and geocoding. This template runs the official PostGIS image (PostgreSQL 17 with PostGIS 3.5) on Railway, with the spatial extensions enabled, a generated password and your data on a persistent volume. Supabase's free tier pauses after a week of inactivity and its Pro plan starts at $25/month. A dedicated PostGIS server on Railway costs about $3–8/month and never sleeps.

---

## What This Template Deploys

| Service | Purpose |
|---|---|
| **PostGIS** | The official `postgis/postgis:17-3.5` image: PostgreSQL 17 with PostGIS 3.5, topology, fuzzy string matching and the TIGER geocoder enabled in `postgis_db`. |
| **Persistent Volume** | Mounted at `/var/lib/postgresql/data`. Tables, spatial indexes and roles survive redeploys and restarts. |

It's a single database service. Other services in your Railway project connect over the private network with `DATABASE_URL`. For desktop GIS tools such as QGIS, turn on a TCP proxy to get a public connection.

---

## About Hosting PostGIS

Plain PostgreSQL can't answer "which stores are within 5 km of this customer?" or "which parcels intersect this flood zone?" efficiently. PostGIS can, with GiST spatial indexes and functions like `ST_DWithin`, `ST_Intersects` and `ST_Transform`. Installing it yourself means matching PostGIS, GEOS, PROJ and GDAL versions to your Postgres build, which is where many managed databases fall short or lag behind.

This template uses the PostGIS project's own Docker image, so every library is compiled and tested together. On Railway, you get a persistent volume, a generated password, private networking for your apps, and one-click backups from the volume settings. Unlike serverless databases, it's always on, so there are no cold starts in the middle of a map render.

**Enabling outside access.** The template doesn't expose the database publicly by default. To connect from QGIS, DBeaver or psql on your laptop, open the PostGIS service's **Settings, Networking**, add a **TCP Proxy** on port `5432`, then use `DATABASE_PUBLIC_URL`.

Typical cost: **~$3–8/month** on Railway for a small spatial database, plus storage as your datasets grow. Supabase Pro starts at $25/month, and Neon bills compute by the hour once you pass its free tier.

---

## Deploy PostGIS in Under 3 Minutes

1. Click **Deploy on Railway**. PostgreSQL initialises and enables PostGIS (about a minute).
2. Copy `DATABASE_URL` into the app that will query it, or reference it from another Railway service.
3. Optionally add a TCP proxy on port `5432` for access from QGIS or a local SQL client.
4. Load data with `shp2pgsql`, `ogr2ogr` or QGIS's database manager.
5. Run spatial queries, for example `SELECT name FROM places WHERE ST_DWithin(geom, ST_MakePoint(-0.12, 51.5)::geography, 5000);`.

No compiling GEOS or PROJ. No extension version mismatches. No idle shutdowns.

---

## Common Use Cases

- **Location search.** Find the nearest stores, drivers, listings or events with indexed distance queries.
- **Delivery and logistics.** Geofences, service areas and route-related lookups for dispatch apps.
- **Map backends.** Serve vector tiles to MapLibre or Leaflet with tools like Martin or pg_tileserv.
- **GIS analysis.** Run QGIS workflows against a shared, always-on database instead of local files.
- **Real estate and urban planning.** Parcel boundaries, zoning layers and spatial joins.
- **IoT and fleet tracking.** Store GPS points and query trips, dwell times and areas visited.
- **US address geocoding.** The TIGER geocoder extension is enabled for address-to-coordinate lookups.
- **Geospatial APIs.** Back a REST or GraphQL API (PostgREST, Hasura, your own code) with spatial filters.

---

## Configuration

| Variable | Required | Description |
|---|---|---|
| `POSTGRES_USER` | ✅ Set | `postgis_admin`, the superuser created on first boot. |
| `POSTGRES_PASSWORD` | 🔐 Auto-generated | Superuser password. |
| `POSTGRES_DB` | ✅ Set | `postgis_db`, the database with PostGIS extensions enabled. |
| `DATABASE_URL` | ✅ Auto-injected | Private connection string for services in the same project. |
| `DATABASE_PUBLIC_URL` | Optional | External connection string. It works once you add a TCP proxy on port 5432. |
| `PGDATA` | ✅ Set | `/var/lib/postgresql/data/pgdata`, a subfolder of the volume. Leave it as is. |

**Extensions included.** `postgis`, `postgis_topology`, `fuzzystrmatch` and `postgis_tiger_geocoder` are created in `postgis_db` on first boot. For raster data, run `CREATE EXTENSION postgis_raster;`. To use PostGIS in another database, run `CREATE EXTENSION postgis;` in it.

**Connecting from another Railway service.** Add a variable such as `DATABASE_URL=${{PostGIS.DATABASE_URL}}` to your app service. It resolves to the private hostname, so traffic never leaves Railway's network and doesn't count as public egress.

---

## PostGIS on Railway vs. Alternatives

| | PostGIS on Railway | Supabase | Neon | AWS RDS for PostgreSQL |
|---|---|---|---|---|
| **Monthly cost** | ~$3–8 usage | Free tier, Pro from $25 | Free tier, then usage-based | Instance-hour pricing |
| **PostGIS included** | ✅ 3.5, enabled | ✅ Extension | ✅ Extension | ✅ Extension |
| **Always on, no cold starts** | ✅ Yes | ⚠️ Free tier pauses after a week | ⚠️ Scales to zero on free | ✅ Yes |
| **Free tier storage** | Pay for usage | 500 MB | 1 GB | ⚠️ 12-month free tier only |
| **Superuser access** | ✅ Yes | ❌ No | ❌ No | ❌ No |
| **Private networking to your apps** | ✅ Built in | ⚠️ Public endpoint | ⚠️ Public endpoint | ✅ VPC |
| **License** | ✅ GPL-2.0 PostGIS, PostgreSQL License | ✅ Open-source core, hosted | ✅ Open-source core, hosted | ❌ Proprietary hosting |

---

## Dependencies for PostGIS Hosting

- Railway account. The Hobby plan ($5/month including $5 of usage) covers small datasets; add storage as you grow.
- A client: your app's Postgres driver, QGIS, DBeaver, psql or GDAL's `ogr2ogr`.
- Optional: a TCP proxy for connections from outside Railway.

### Deployment Dependencies

- [PostGIS Documentation](https://postgis.net/documentation/): functions and guides
- [PostGIS Docker image](https://github.com/postgis/docker-postgis): the image this template runs
- [PostgreSQL Documentation](https://www.postgresql.org/docs/17/): core database reference
- [Railway Volumes Documentation](https://docs.railway.com/volumes): persistence and backups

### Implementation Details

The image is the PostGIS project's official build on PostgreSQL 17, with GEOS, PROJ and GDAL bundled. On first boot, its init script creates the spatial extensions in `postgis_db`, and in `template_postgis` for new databases. Data lives in a subfolder of the volume, so the volume's root `lost+found` folder never blocks initialisation.

The image tag is pinned to `17-3.5`. Upgrading PostGIS within PostgreSQL 17 means changing the tag and running `ALTER EXTENSION postgis UPDATE;`. A PostgreSQL major upgrade needs a dump and restore. Back up first.

**Performance tips.** Create a GiST index on every geometry column you filter on (`CREATE INDEX ON places USING gist (geom);`), store data in one SRID and use `geography` for metre-based distances, and run `ANALYZE` after bulk loads. For large imports, give the service more RAM in Railway while loading, then scale it back down.

---

## Frequently Asked Questions

**What is PostGIS?**
PostGIS is an extension that adds spatial types, indexes and functions to PostgreSQL, so you can store points, lines and polygons and query them by distance, area and intersection.

**How much does PostGIS on Railway cost compared to Supabase or Neon?**
About $3–8/month for a small database that's always on. Supabase Pro starts at $25/month, and its free tier pauses after a week. Neon's free tier scales to zero, and paid use is billed per compute hour.

**Why is DATABASE_PUBLIC_URL empty?**
The template doesn't enable public access by default. Add a TCP proxy on port 5432 in the service's Networking settings, and the variable fills in.

**Do I lose data when Railway redeploys?**
No. The database files are on the volume at `/var/lib/postgresql/data`, so redeploys and restarts keep every table and index. Enable volume backups for extra safety.

**Can I connect QGIS to this database?**
Yes. Add a TCP proxy, then create a PostGIS connection in QGIS with the proxy host, port, `postgis_db` and the `postgis_admin` credentials.

**Does it include pgRouting?**
No. The official PostGIS image includes PostGIS, topology, raster and the TIGER geocoder, but not pgRouting. For routing, use a pgRouting image instead.

---

## Why Deploy and Host PostGIS on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.

By deploying PostGIS on Railway, you get an always-on spatial database with full superuser access, private networking to your apps and persistent storage, for a few dollars a month.


## Similar templates

- [RustFS | (Just Updated) S3 Object Store, Public URL and Keys Set](https://railway.com/deploy/rustfs-or-just-updated-s3-object-store-p) — S3-compatible object store, keys and public URL preset, volume kept
- [TimescaleDB](https://railway.com/deploy/timescaledb-railway-template) — A PostgreSQL-based time-series database for analytics on Railway.
- [Garage S3 Storage](https://railway.com/deploy/garage-s3-storage) — Ultra-light S3 server: fast, open-source, plug-and-play.

Open this page in a browser: https://railway.com/deploy/postgis-postgres
