# Back up PostgreSQL

Back up the Syntho PostgreSQL databases. They store users, workspaces, and platform state.

{% hint style="info" %}
Syntho stores platform state in PostgreSQL databases. You can back them up using either an external PostgreSQL instance or the bundled PostgreSQL. Official PostgreSQL guidance: [Backup and Restore](https://www.postgresql.org/docs/current/backup.html).
{% endhint %}

Use your managed PostgreSQL backups.

{% stepper %}
{% step %}

#### Back up

1. Enable automated backups.
2. Enable the ability to restore to an earlier point in time (if your provider supports it).
3. Pick a retention period that matches your business needs.
4. Keep `syntho-core` and `syntho-backend` on the **same** PostgreSQL instance.
   {% endstep %}

{% step %}

#### Restore

1. Restore the PostgreSQL instance to the same point in time for both databases.
2. Start Syntho and validate login/workspaces.
   {% endstep %}
   {% endstepper %}

Use this when you prefer file-based backups. This works for external PostgreSQL and bundled PostgreSQL. You only need network access to the database. Official documentation [`pg_dump`](https://www.postgresql.org/docs/current/app-pgdump.html).

{% stepper %}
{% step %}

#### Back up

Run `pg_dump` for **both** databases:

```bash
pg_dump -h <db-host> -p 5432 -U <db-user> -Fc -f syntho-backend.dump -d syntho-backend
pg_dump -h <db-host> -p 5432 -U <db-user> -Fc -f syntho-core.dump    -d syntho-core
```

<details>

<summary>What the <code>pg_dump</code> options mean</summary>

* `-h <db-host>`: PostgreSQL host name or Internet Protocol address.
* `-p 5432`: PostgreSQL port.
* `-U <db-user>`: database user name.
* `-F c` (shown as `-Fc`): output format “custom”. It is designed for `pg_restore`.
* `-f <file>`: output file path.
* `-d <database>`: database name to back up.

</details>

Store both dump files together (same run).
{% endstep %}

{% step %}

#### Restore

1. Stop Syntho.
2. Restore both databases:

```bash
pg_restore -h <db-host> -p 5432 -U <db-user> -d syntho-backend --clean syntho-backend.dump
pg_restore -h <db-host> -p 5432 -U <db-user> -d syntho-core    --clean syntho-core.dump
```

3. Start Syntho and validate.
   {% endstep %}
   {% endstepper %}

{% hint style="info" %}
`pg_dump` is consistent per database, but it does not automatically keep both databases in sync. If you need `syntho-backend` and `syntho-core` to represent the same moment, stop Syntho while dumping. Alternatively, use a backup method that restores the whole PostgreSQL instance to a single point in time.
{% endhint %}

#### Method 3: Docker volume backup (bundled PostgreSQL)

Use this only when you run the bundled `database` container. The Docker Compose bundle stores PostgreSQL data in a Docker volume (by default named `database-data`).

{% stepper %}
{% step %}
**Back up**

1. Find the volume name:

   ```bash
   docker volume ls
   ```
2. Stop the stack to avoid writes:

   ```bash
   docker compose down
   ```
3. Create a tarball from the volume:

   ```bash
   docker run --rm \
     -v <volume-name>:/volume:ro \
     -v "$(pwd)":/backup \
     alpine \
     sh -c 'cd /volume && tar -czf /backup/database-data.tar.gz .'
   ```
4. Start the stack:

   ```bash
   docker compose up -d
   ```

{% endstep %}

{% step %}
**Restore**

1. Stop the stack:

   ```bash
   docker compose down
   ```
2. Restore into a **new or empty** volume:

   ```bash
   docker run --rm \
     -v <volume-name>:/volume \
     -v "$(pwd)":/backup \
     alpine \
     sh -c 'rm -rf /volume/* && tar -xzf /backup/database-data.tar.gz -C /volume'
   ```
3. Start the stack:

   ```bash
   docker compose up -d
   ```

{% endstep %}
{% endstepper %}

{% hint style="warning" %}
Do not copy PostgreSQL data files while the database is actively writing.
{% endhint %}

### Switch Docker Compose to external PostgreSQL

Optional. Use this when you want Syntho to connect to a PostgreSQL instance outside the cluster.

* Bundled service name: `database`
* Default databases: `syntho-core`, `syntho-backend`
* Root `.env` variables: `DB_USER`, `DB_PASSWORD`

{% stepper %}
{% step %}
**Provision PostgreSQL**

Run this SQL as a PostgreSQL admin:

```sql
CREATE ROLE syntho WITH LOGIN PASSWORD '<strong-password>';

CREATE DATABASE "syntho-core" OWNER syntho;
CREATE DATABASE "syntho-backend" OWNER syntho;
```

{% endstep %}

{% step %}
**Create databases and user**

Make sure Syntho can reach your PostgreSQL host:

1. PostgreSQL is reachable from the cluster / node network.
2. Firewall / security groups allow inbound traffic (usually `5432`).
3. TLS is enabled if required by your security policy.

{% hint style="info" %}
This uses `syntho` as the DB user to match the default `DB_USER=syntho` in the Compose templates.
{% endhint %}
{% endstep %}

{% step %}
**Update root `.env`**

Add these variables:

```bash
DB_HOST=<external-postgres-hostname-or-ip>
DB_PORT=5432
```

Set credentials to match the role you created:

```bash
DB_USER=syntho
DB_PASSWORD=<strong-password>
```

{% endstep %}

{% step %}
**Remove the bundled `database` service**

Create a production Compose variant (for example `docker-compose.external-db.yaml`) and:

1. Remove the `database:` service.
2. Remove `depends_on: database` from:
   * `backend`
   * `backend-worker`
   * `core-api`
   * `core-api-worker`
     {% endstep %}

{% step %}
**Start the external database and verify**

Bring up the new configuration and remove orphaned containers:

```bash
docker compose -f docker-compose.external-db.yaml up -d --remove-orphans
```

Verify pods/containers are healthy, UI is accessible, you can log in and workspaces are visible (or can be created).
{% endstep %}
{% endstepper %}

{% hint style="warning" %}
Do not delete embedded volumes until the external database is verified working.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.syntho.ai/deploy-syntho/deploy-syntho-using-docker/back-up-postgresql.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
