> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fly.io/llms.txt
> Use this file to discover all available pages before exploring further.

# App Connection Examples

<Warning>
  **This page is archived.** Fly Postgres (unmanaged) is no longer maintained, and Fly.io Support is not able to provide support or guidance for it. We now offer [Fly.io Managed Postgres](/postgres), our fully-managed database service that handles all aspects of running production PostgreSQL databases.

  These pages are kept for reference and are not listed in the navigation. The full set is indexed on the [Fly Postgres (Unmanaged)](/unmanaged-postgres) page.
</Warning>

These examples demonstrate connections from within the same Fly.io internal IPv6 private network . To adapt them for external connections, substitute the internal hostname for one that's reachable over the public Internet.

## psql

If you have an active [WireGuard tunnel](/networking/private-networking#private-network-vpn) to your organization's private network, you can connect from a local machine to your Postgres cluster the same way you would from a Fly app within the same private network. For example, the following command would start an interactive terminal session on the cluster leader with `psql`:

```bash theme={null}
psql postgres://postgres:secret123@appname.internal:5432
```

You can, of course, run psql from a shell on a Fly app as well (as long as that app has psql installed).

## Connecting with Ruby

[docs](https://github.com/ged/ruby-pg)

Ruby apps use the `pg` gem to connect to postgres.

```ruby theme={null}
require 'pg'

# Output a table of current connections to the DB
conn = PG.connect("postgres://postgres:secret123@postgresapp.internal:5432/yourdb")
conn.exec( "SELECT * FROM pg_stat_activity" ) do |result|
  puts "     PID | User             | Query"
  result.each do |row|
    puts " %7d | %-16s | %s " %
      row.values_at('pid', 'usename', 'query')
  end
end
```

## Connecting with Rails

[docs](https://guides.rubyonrails.org/configuring.html#configuring-a-database)

Rails apps automatically connect to the database specified in the `DATABASE_URL` environment variable.

You can set this variable manually with `flyctl secrets set`

```bash theme={null}
flyctl secrets set DATABASE_URL=postgres://postgres:secret123@postgresapp.internal:5432/yourdb
```

or by attaching the Postgres database to your Fly app.

## Connecting with Python

[`psycopg`](https://www.psycopg.org/psycopg3/) is the recommended driver for connecting
to postgres:

```python theme={null}
import psycopg

conninfo = "postgres://postgres:secret123@postgresapp.internal:5432/yourdb"
with psycopg.connect(conninfo) as connection:
    with connection.cursor() as cursor:
        cursor.execute(...)
        results = cursor.fetchall()
```

## Connecting with Django

[docs](https://docs.djangoproject.com/en/stable/ref/settings/#databases)

[`psycopg`](https://www.psycopg.org/psycopg3/) is the recommended driver for connecting
to postgres. You can use the [`django-environ`](https://pypi.org/project/django-environ/)
package to translate the `DATABASE_URL` environment variable into Django database
configuration. First, install both packages:

```bash theme={null}
python -m pip install psycopg django-environ
```

Now we can define `DATABASES` in our `settings.py` file.

```python theme={null}
import environ  # ← Added

...

env = environ.Env()  # ← Added
environ.Env.read_env(BASE_DIR / ".env")  # ← Added

DATABASES = {
    # env.db() reads the DATABASE_URL environment variable.
    "default": env.db(),  # ← Updated
}
```

You can set the `DATABASE_URL` manually with `flyctl secrets set`:

```bash theme={null}
flyctl secrets set DATABASE_URL=postgres://postgres:secret123@postgresapp.internal:5432/yourdb
```

or by adding it to the `.env` file:

```
# .env
SECRET_KEY=06\Rd75]S.vzZtrZoxc3!*~JR*/te[8BR%L-7~I7eFsGCqk,ze
DATABASE_URL=postgres://postgres:secret123@postgresapp.internal:5432/yourdb  # ← Added
```

## Connecting with Go

[docs](https://github.com/jackc/pgx/wiki/Getting-started-with-pgx-through-database-sql)

`pgx` is the recommended driver for connecting to postgres. It supports the standard `database/sql` interface as well as directly exposing low level / high performance APIs.

First, add `github.com/jackc/pgx/v4` as a module dependency.

```bash theme={null}
go get github.com/jackc/pgx/v4
```

The following program will connect to the database in `DATABASE_URL` and run a query.

```go theme={null}
package main

import (
  "database/sql"
  "fmt"
  "os"

  _ "github.com/jackc/pgx/v4/stdlib"
)

func main() {
  db, err := sql.Open("pgx", os.Getenv("DATABASE_URL"))
  if err != nil {
    fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
    os.Exit(1)
  }
  defer db.Close()

  var greeting string
  err = db.QueryRow("select 'Hello, world!'").Scan(&greeting)
  if err != nil {
    fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err)
    os.Exit(1)
  }

  fmt.Println(greeting)
}
```

## Connecting with Node.js

[docs](https://node-postgres.com)

You'll use the `pg` npm module to connect to Postgres from a Node.js app.

```javascript theme={null}
const { Client } = require('pg')
const client = new Client({connectionString: process.env.DATABASE_URL})

await client.connect()
const res = await client.query('SELECT $1::text as message', ['Hello world!'])
console.log(res.rows[0].message) // Hello world!
await client.end()
```

<h2 id="connecting-with-prisma-node-js">
  Connecting with Prisma – Node.js
</h2>

[docs](https://www.prisma.io/)

Prisma is an open-source object-relational mapper (ORM) for Node.js and works with both JavaScript and TypeScript. It consists of 3 components:

* Prisma Client - a type-safe query builder
* Prisma Migrate - a data modeling and migration tool
* Prisma Studio - a modern intuitive GUI for interacting with your database

<Accordion title="Set up Prisma in your project">
  Install the Prisma CLI and Prisma Client dependencies in your project

  ```
  npm i --save-dev prisma
  npm i @prisma/client
  ```

  Initialize Prisma in your project:

  ```
  npx prisma init
  ```

  This command does the following:

  * Creates a folder called `prisma` at the root of your project
  * Creates a `.env` file at the root of your project if it doesn't exist
  * Creates a `schema.prisma` file inside the `prisma` folder. This is the file that you will use to model your data

  Update the `DATABASE_URL` in the `.env` to your PostgreSQL database

  ```
  DATABASE_URL="postgres://postgres:secret123@postgresapp.internal:5432/yourdb"
  ```

  If you are working in a brownfield project, you can introspect your database to generate the models in your `schema.prisma` file:

  ```
  npx prisma db pull
  ```
</Accordion>

Assuming you have the following model in your `schema.prisma` file:

Add a model to your `schema.prisma` file:

```groovy theme={null}
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider  = "prisma-client-js"
}

model Post {
  id       Int     @id @default(autoincrement())
  title    String
  content  String?
}
```

You can query your database using Prisma as follows:

```typescript theme={null}
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
  const posts = await prisma.post.findMany()

  const newPost = await prisma.post.create({
    data: {
      title: 'PostgreSQL on Fly',
      content: 'https://fly.io/docs/reference/postgres'
    }
  })
}

main()
  .catch((e) => {
    throw e
  })
  .finally(async () => {
    await prisma.$disconnect()
  })
```

<h2 id="connecting-with-sequelize-node-js">
  Connecting with Sequelize – Node.js
</h2>

[docs](https://sequelize.org)

Sequelize is an open-source object-relational mapper (ORM) for Node.js and works with JavaScript and TypeScript.

<Accordion title="Set up Sequelize inside your project">
  Install the Sequelize dependencies and CLI into your project

  ```
  npm install --save sequelize
  npm install --save-dev sequelize-cli
  ```

  Initialize Sequelize into your project:

  ```
  npx sequelize init
  ```

  This will create the following folders:

  * config, contains config file, which tells CLI how to connect with database
  * models, contains all models for your project
  * migrations, contains all migration files
  * seeders, contains all seed files

  [Docs: Create your first model](https://sequelize.org/docs/v6/other-topics/migrations/#creating-the-first-model-and-migration)
</Accordion>

After initializing you will need to show the CLI how to connect to the database inside of `config/config.js`

```javascript theme={null}
const fs = require('fs');

module.exports = {
  development: {
    username: 'database_dev',
    password: 'database_dev',
    database: 'database_dev',
    host: '127.0.0.1',
    port: 3306,
    dialect: 'mysql',
    dialectOptions: {
      bigNumberStrings: true
    }
  },
  test: {
    username: process.env.CI_DB_USERNAME,
    password: process.env.CI_DB_PASSWORD,
    database: process.env.CI_DB_NAME,
    host: '127.0.0.1',
    port: 3306,
    dialect: 'postgres',
    dialectOptions: {
      bigNumberStrings: true
    }
  },
  production: {
    database: process.env.DATABASE_URL,
    host: process.env.PROD_DB_HOSTNAME,
    dialect: 'postgres'
  }
};
```

Create a new file named `.sequelizerc` , this allows the CLI to be able to read your `config.js` file

```javascript theme={null}
const path = require('path');

module.exports = {
  'config': path.resolve('config', 'config.js')
}
```

Next pass the `DATABASE_URL` from the env into the Sequelize constructor in `models/index.js` to be able to connect to your fly postgres app and confirm the new Sequelize connection with the async function below

```javascript theme={null}
// Connect to fly postgres app
let sequelize = new Sequelize(process.env.DATABASE_URL);

// Confirms the connection to the database
(async () => {
  try {
    await sequelize.authenticate();
    console.log('Connected to the database!');
  } catch (err) {
    console.error('Error connecting to the database:', err);
  }
})();
```

<Accordion title="Configure Sequelize to connect with your read replica databases">
  [Fly docs: How to add Read Replica database with flyctl](/unmanaged-postgres/advanced-guides/high-availability-and-global-replication)

  Set the Sequelize constructor in `model/index.js` to conditionally connect to the primary/read-replica database depending on the `primary region` value set in `fly.toml`.

  ```javascript theme={null}
  let sequelize;
  if (config.use_env_variable) {
    const primary = process.env.PRIMARY_REGION;
    const current = process.env.FLY_REGION;
    let db_url = process.env.DATABASE_URL;

    if (!primary || !current || primary === current) {
      sequelize = new Sequelize(process.env.DATABASE_URL);

      // Check Fly logs to confirm that your primary database is connected
      console.log("DB connected in Region: ", current)
    } 
    else{
      const u = new URL(db_url);
      u.port = "5433";

      // Check Fly logs to confirm that your read replica database is connected
      console.log(`Read Rep DB connected in ${current}`)

      sequelize = new Sequelize(u.toString());
    }
  ```
</Accordion>
