# Connect Your App to Managed PostgreSQL with DATABASE_URL (Node.js, Python, Go)

Connect Node.js, Python (Django, FastAPI, SQLAlchemy) and Go apps to managed PostgreSQL with DATABASE_URL: private networking, migrations and backups.

URL: https://blog.dockhosting.dev/connect-app-to-managed-postgresql
Published: 2026-10-31 · Updated: 2026-10-31 · Author: Doughmi ILYAS

## Summary

- Attach a managed PostgreSQL database and its connection string is injected as DATABASE_URL over a private network.
- Node.js (pg, Prisma), Python (Django, SQLAlchemy) and Go (pgx) all read the same variable.
- The Free plan includes 1 database with 500 MB that never pauses or expires; backups start on Hobby.

ort const meta = {
  title: "Connect Your App to Managed PostgreSQL with DATABASE_URL (Node.js, Python, Go)",
  seoTitle: "Connect Your App to PostgreSQL with DATABASE_URL",
  description:
    "Connect Node.js, Python (Django, FastAPI, SQLAlchemy) and Go apps to managed PostgreSQL with DATABASE_URL: private networking, migrations and backups.",
  date: "2026-10-31",
  category: "Guides",
  tags: ["PostgreSQL", "Databases", "Node.js", "Python", "Go", "Tutorial"],
  stack: ["postgresql", "prisma", "sqlalchemy", "go"],
  command: "dock db sql",
  takeaways: [
    "Attach a managed PostgreSQL database and its connection string is injected as DATABASE_URL over a private network.",
    "Node.js (pg, Prisma), Python (Django, SQLAlchemy) and Go (pgx) all read the same variable.",
    "The Free plan includes 1 database with 500 MB that never pauses or expires; backups start on Hobby.",
  ],
  faq: [
    {
      q: "Which PostgreSQL version do managed databases run?",
      a: "PostgreSQL 16 by default, with 15 and 14 available. Minor upgrades are applied for you.",
    },
    {
      q: "Is there a free PostgreSQL database?",
      a: "Yes. The Free plan includes 1 managed database with 500 MB of storage. It doesn't pause when idle and doesn't expire.",
    },
    {
      q: "Can I connect with psql or pgAdmin from my laptop?",
      a: "Public access for tools like psql and pgAdmin is available on Hobby and up. On every plan, your apps reach the database over the private network, and you can run queries from the terminal with dock db sql.",
    },
    {
      q: "Are databases backed up?",
      a: "Paid plans get daily automatic backups, kept 3 days on Hobby, 7 days on Pro and 30 days on Team.",
    },
  ],
};

Hard-coded database credentials are the classic way an app breaks between your laptop and production. The fix is old and simple: read one connection string, `DATABASE_URL`, from the environment, and let the platform fill it in.

This guide shows how that works with a managed PostgreSQL database on DockHosting, with copy-paste code for Node.js, Python and Go.

## How it works

1. Create a PostgreSQL database from the dashboard. It's ready in seconds.
2. Attach it to your project.
3. Its connection string is injected into every connected app as `DATABASE_URL`.

The database is reached over a **private network** through an internal hostname. Nothing is exposed to the internet by default, and your app and database sit in the same region (eu-central-1), so queries don't pay cross-region latency.

A `DATABASE_URL` looks like this:

```text
postgresql://USER:PASSWORD@HOST:5432/DATABASE
```

Never commit it. Locally, put it in a `.env` file that's in `.gitignore`. In production, the platform sets it.

## Node.js

With [node-postgres](https://node-postgres.com/):

```js
import pg from "pg";

export const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });

const { rows } = await pool.query("select id, email from users where id = $1", [userId]);
```

With **Prisma**, point the datasource at the variable:

```prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}
```

Drizzle, Knex, TypeORM and Sequelize take the same string. Always use parameterized queries (`$1`) rather than string concatenation to stay safe from SQL injection.

## Python

### Django

Install `dj-database-url` and read the variable in `settings.py`:

```python
import dj_database_url

DATABASES = {"default": dj_database_url.config(conn_max_age=600)}
```

When `manage.py` is detected, `migrate` runs automatically before traffic switches to the new release, so your schema is always ahead of your code.

### FastAPI / SQLAlchemy

```python
import os
from sqlalchemy import create_engine

url = os.environ["DATABASE_URL"].replace("postgresql://", "postgresql+psycopg://", 1)
engine = create_engine(url, pool_pre_ping=True)
```

The `replace` call selects the psycopg 3 driver. `pool_pre_ping` quietly replaces stale connections, which matters on the Free plan, where apps sleep when idle.

## Go

With [pgx](https://github.com/jackc/pgx):

```go
pool, err := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
if err != nil {
    log.Fatal(err)
}
defer pool.Close()

var now time.Time
err = pool.QueryRow(ctx, "select now()").Scan(&now)
```

Go apps compile to a single static binary on deploy and wake in under a second.

## Running migrations

- **Django**: `migrate` runs automatically on deploy.
- **Rails**: `db:migrate` runs automatically on deploy.
- **Laravel**: `artisan migrate` runs automatically on deploy.
- **Node.js / Go**: run your migration tool as part of your build or start command, for example `"start": "prisma migrate deploy && node dist/server.js"`. You can override the build and start commands per project in the dashboard.

## Querying from your terminal

To check data quickly, `dock db sql` runs a SQL query against one of your managed databases from the CLI. You don't need to open a port or install a client. On Pro and Team you also get a database admin panel in the browser.

## Limits by plan

| | Free | Hobby | Pro | Team |
|---|---|---|---|---|
| Managed databases | 1 | 2 | 6 | 15 |
| Storage per database | 500 MB | 2 GB | 5 GB | 20 GB |
| Daily backups | - | Kept 3 days | Kept 7 days | Kept 30 days |
| Public access (psql, pgAdmin) | - | Yes | Yes | Yes |
| Admin panel | - | - | Yes | Yes |

Free databases don't pause and don't expire. Read more on [managed PostgreSQL hosting](https://dockhosting.dev/postgresql) or [compare plans](https://dockhosting.dev/pricing).

## Using other databases

The same pattern works for every engine. MySQL and MariaDB use `DATABASE_URL`, MongoDB uses `MONGODB_URI`, Redis uses `REDIS_URL` and ClickHouse uses `CLICKHOUSE_URL`. Attach the database, then read the variable.

New to deploying? Start with [deploying a Node.js app in one command](/deploy-nodejs-app-one-command).

**Related:** [Moving a Render free Postgres before it's deleted](/render-free-postgres-expired) · [Free backend hosting with a database that doesn't expire](/free-backend-hosting)

## FAQ

### Which PostgreSQL version do managed databases run?

PostgreSQL 16 by default, with 15 and 14 available. Minor upgrades are applied for you.

### Is there a free PostgreSQL database?

Yes. The Free plan includes 1 managed database with 500 MB of storage. It doesn't pause when idle and doesn't expire.

### Can I connect with psql or pgAdmin from my laptop?

Public access for tools like psql and pgAdmin is available on Hobby and up. On every plan, your apps reach the database over the private network, and you can run queries from the terminal with dock db sql.

### Are databases backed up?

Paid plans get daily automatic backups, kept 3 days on Hobby, 7 days on Pro and 30 days on Team.
