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

# Configure External PostgreSQL

## PostgreSQL Setup

PostgreSQL 14 or above.

<Note>
  External PostgreSQL is required for [High Availability](/get-started/self-host/high-availability/). HA mode is not supported with Bytebase's embedded PostgreSQL.
</Note>

### Database

Create a database named `bytebase` with UTF-8 encoding. UTF-8 encoding is required for proper system operation.

### Authentication

Choose one authentication method for the metadata database. The authentication method determines how you create the database user and how you set `PG_URL`.

The connection string must follow the standard PostgreSQL URI format. See the [official PostgreSQL documentation](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING-URIS) for complete syntax details.

#### Password Authentication (Default)

Use password authentication for standard PostgreSQL deployments.

Create a user `bytebase` with a password and one of the following privilege levels:

##### Option 1: Superuser

<Note>
  This option is not available on managed database services like AWS RDS or Google Cloud SQL.
</Note>

Grant PostgreSQL superuser privileges:

```sql theme={null}
ALTER ROLE bytebase SUPERUSER;
```

##### Option 2: Database Owner

Make the user own the database:

```sql theme={null}
ALTER DATABASE bytebase OWNER TO bytebase;
```

##### Option 3: Schema Create Privilege

Grant CREATE privilege on the public schema:

```sql theme={null}
GRANT CREATE ON SCHEMA public TO bytebase;
```

##### Option 4: Database Owner Role

Grant the db\_owner role to the user:

```sql theme={null}
GRANT db_owner TO bytebase;
```

Set `PG_URL` to a PostgreSQL connection URI that includes the password:

```bash theme={null}
PG_URL="postgresql://bytebase:your_password@example.com:5432/bytebase"
```

#### IAM Authentication for Managed PostgreSQL

Use IAM authentication when the metadata database is AWS RDS/Aurora PostgreSQL or GCP Cloud SQL for PostgreSQL. This removes the static PostgreSQL password from `PG_URL`; Bytebase uses the cloud credentials available in its runtime environment to authenticate each metadata database connection.

Only enable one metadata database IAM provider at a time. Keep using password authentication for other PostgreSQL providers.

##### AWS RDS IAM Authentication

Use AWS RDS IAM authentication when Bytebase stores metadata in RDS for PostgreSQL or Aurora PostgreSQL.

Required setup:

* Enable IAM database authentication on the RDS or Aurora PostgreSQL instance.
* Create the PostgreSQL user for Bytebase.
* Grant the user the required Bytebase metadata database privileges, such as database owner, schema `CREATE`, or equivalent privileges.
* Grant the PostgreSQL user the `rds_iam` role.
* Grant the Bytebase runtime AWS principal `rds-db:connect` for that database user.
* Use verified TLS, such as `sslmode=verify-full`, with a trust store that validates the RDS certificate.
* Provide AWS credentials through the standard AWS credential chain, such as EKS IRSA, ECS task roles, EC2 instance profiles, environment variables, or shared AWS config.

Set `PG_URL` without a password and add the AWS RDS IAM parameters:

```bash theme={null}
PG_URL="postgresql://bytebase@RDS_ENDPOINT:5432/bytebase?sslmode=verify-full&bytebase_aws_rds_iam=true&bytebase_aws_region=REGION"
```

Bytebase-specific connection parameters:

| Parameter                      | Description                                                   |
| ------------------------------ | ------------------------------------------------------------- |
| `bytebase_aws_rds_iam=true`    | Enables AWS RDS IAM authentication for the metadata database. |
| `bytebase_aws_region=<region>` | AWS region used to sign RDS IAM authentication tokens.        |

##### GCP Cloud SQL IAM Authentication

Use GCP Cloud SQL IAM authentication when Bytebase stores metadata in Cloud SQL for PostgreSQL.

Required setup:

* Enable Cloud SQL IAM database authentication on the Cloud SQL PostgreSQL instance.
* Add the Google service account as a Cloud SQL IAM database user. For PostgreSQL, use the IAM database username format without the `.gserviceaccount.com` suffix, for example `bytebase@PROJECT_ID.iam`.
* Grant the IAM database user the required Bytebase metadata database privileges, such as database owner, schema `CREATE`, or equivalent privileges.
* Grant the Bytebase runtime Google principal the Cloud SQL permissions it needs, such as `Cloud SQL Client` and `Cloud SQL Instance User`.
* Provide Google credentials through Application Default Credentials, such as GKE Workload Identity, a GCE attached service account, or `GOOGLE_APPLICATION_CREDENTIALS`.

Set `PG_URL` without a password and add the GCP Cloud SQL IAM parameters. The example percent-encodes `@` in the username as `%40` because `@` is a URI delimiter:

```bash theme={null}
PG_URL="postgresql://bytebase%40PROJECT_ID.iam@localhost:5432/bytebase?bytebase_gcp_cloud_sql_iam=true&bytebase_gcp_cloud_sql_instance_connection_name=PROJECT_ID:REGION:INSTANCE_ID"
```

Bytebase-specific connection parameters:

| Parameter                                                                   | Description                                                         |
| --------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `bytebase_gcp_cloud_sql_iam=true`                                           | Enables GCP Cloud SQL IAM authentication for the metadata database. |
| `bytebase_gcp_cloud_sql_instance_connection_name=<project:region:instance>` | Cloud SQL instance connection name used by the Cloud SQL connector. |

#### File Path (Kubernetes & Secret Management)

For Kubernetes deployments and secret manager integration, set `PG_URL` to a file path containing either a password-based or IAM-enabled connection string. Bytebase automatically picks up the updated connection string when the file content changes, enabling seamless secret rotation.

```bash theme={null}
PG_URL="/path/to/connection/file"
```

## Running with Docker

This bash script demonstrates how to add an external PostgreSQL database as the metadata store when running the bytebase container.

<Note>
  When connecting to a PostgreSQL instance running on the same host machine, use [host.docker.internal](https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host) as the hostname.
</Note>

```bash theme={null} theme={null} theme={null}
docker run --rm --init \
  -e PG_URL=postgresql://user:secret@host:port/dbname \
  --name bytebase \
  --publish 8080:8080 --pull always \
  --volume ~/.bytebase/data:/var/opt/bytebase \
  bytebase/bytebase:latest
```

## Running with Kubernetes

### Direct Configuration

Configure the PostgreSQL connection directly in your deployment manifest:

```yaml theme={null}
env:
  - name: PG_URL
    value: 'postgresql://<<user>>:<<secret>>@<<host>>:<<port>>/<<dbname>>'
```

### Secret-Based Configuration

For enhanced security, store your PostgreSQL connection string in a Kubernetes Secret:

#### Using Secret as Environment Variable

Add the following environment variable configuration to your deployment's `spec.templates.spec.containers.env` section:

```yaml theme={null}
env:
  - name: PG_URL
    valueFrom:
      secretKeyRef:
        name: secret_name
        key: secret_key
```

#### Using Secret as File Mount

Mount the secret as a file and point `PG_URL` to the file path. This approach supports automatic secret rotation - when the Kubernetes Secret is updated, the mounted file content is automatically refreshed, and Bytebase will pick up the new connection string without requiring a restart:

```yaml theme={null}
spec:
  containers:
    - name: bytebase
      env:
        - name: PG_URL
          value: "/var/secrets/pg-connection/url"
      volumeMounts:
        - name: pg-secret
          mountPath: "/var/secrets/pg-connection"
          readOnly: true
  volumes:
    - name: pg-secret
      secret:
        secretName: bytebase-pg-secret
        items:
          - key: connection-string
            path: url
```

<Note>
  When using file-based secrets, Kubernetes automatically updates the mounted file content when the Secret is updated (typically within a minute). Bytebase monitors the file for changes and automatically reloads the connection string, enabling seamless secret rotation without downtime.
</Note>
