> ## 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.

# External Connections

<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>

<img src="https://mintcdn.com/fly-io/v-XOGeVK6s4rQ-4y/images/factory.png?fit=max&auto=format&n=v-XOGeVK6s4rQ-4y&q=85&s=0e43fe532c0050985adcc761c6a2e0ad" alt="Illustration by Annie Ruygt of bird workers on a factory assemmbly line" width="1200" height="1214" data-path="images/factory.png" />

Fly Postgres databases can be used by applications outside their Fly.io [internal private network](/networking/private-networking); this means in a different private network belonging to your organization, in another Fly organization, or outside Fly.io altogether.

We don't expose Postgres apps to the internet by default. To get this working, you'll need to make two adaptations: configuring your Postgres app to accept connections from the Fly proxy, and providing a publicly-resolvable hostname to your app.

## Allocate an IP address

If you haven't already, you will need to allocate a public IP address to your Postgres app. You can view your list of IPs by running the following command from your application directory:

```bash theme={null}
fly ips list --app <pg-app-name>
```

You can allocate an IPv4 address by running the following:

```bash theme={null}
fly ips allocate-v4 --app <pg-app-name>
```

If your network supports IPv6:

```bash theme={null}
fly ips allocate-v6 --app <pg-app-name>
```

## Configure an external service

Now that you have an IP address, it's time to configure your app to accept connections on an external port, and direct incoming requests to your Postgres instance.

Pull down a `fly.toml` configuration file for your Postgres app, if you don't have it:

```bash theme={null}
fly config save --app <pg-app-name>
```

Note that this could overwrite a `fly.toml` in the current directory, so be careful!

Open up your `fly.toml` file.

This may come with a default `services` section for `internal_port` 8080. Replace that with the following to configure your port mappings to work with Postgres:

```toml theme={null}
[[services]]
  internal_port = 5432 # Postgres instance
  protocol = "tcp"

[[services.ports]]
  handlers = ["pg_tls"]
  port = 5432
```

Note the use of the `pg_tls` [handler](/networking/services#connection-handlers) to manage the specific requirements of Postgres connections.

For additional information on services and service ports:
[The services sections](/reference/configuration#the-services-sections)

## Deploy with the new configuration

Once your service has been set up in `fly.toml`, it's time to deploy with the new configuration.

Verify the version of Postgres you are running.  **This step is important, because [there can be changes in the internal storage format between major versions of Postgres](https://www.postgresql.org/docs/current/upgrading.html).**

Figure out which image and tag (Postgres version) you’re on:

<CodeGroup>
  ```bash cmd theme={null}
  fly image show --app <pg-app-name>
  ```

  ```out out theme={null}
  Image Details
    Registry   = docker-hub-mirror.fly.io
    Repository = flyio/postgres-flex
    Tag        = 16.4
    Version    = v0.0.62
  ```
</CodeGroup>

Deploy your cluster, using `--image` with the `image:tag` found in the previous step:

```bash theme={null}
fly deploy . --app <pg-app-name> --image flyio/postgres-flex:<major-version>
```

As an example, if you are running Postgres 16.x you would specify `flyio/postgres-flex:16` as your target image.

After the deployment completes, you can verify your `services` configuration by running the `fly services list` command:

<CodeGroup>
  ```bash cmd theme={null}
  fly services list
  ```

  ```output output theme={null}
  Services
  PROTOCOL        PORTS                   FORCE HTTPS
  TCP             5432 => 5432 [PG_TLS]   False
  TCP             5433 => 5433 [PG_TLS]   False
  ```
</CodeGroup>

You should then be able to access your Postgres cluster via psql like:

<CodeGroup>
  ```bash cmd theme={null}
  psql "sslmode=require host=<pg-app-name>.fly.dev dbname=<db name> user=<username>"
  ```

  ```out out theme={null}
  Password for user <username>:
  psql (14.5 (Homebrew), server 13.6 (Debian 13.6-1.pgdg110+1))
  SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
  Type "help" for help.

  <db name>=#
  ```
</CodeGroup>

## Adapting the connection string

The connection string that `fly pg create` outputs for use in consuming apps is in the form:

```
postgres://{username}:{password}@{hostname}:{port}/{database}?options
```

where the `hostname` is an internal one. Substitute your newly publicly reachable hostname (`<pg-app-name>.fly.dev`) here to get a connection string an external app can use.
