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

# Quickstart

> Connect a PostgreSQL database in a closed network to Concatflow, end to end.

By the end of this page, Concatflow lists the schemas of your database. The database itself accepts no new inbound connection.

## Before you start

You need:

* A machine that can reach your database and run Docker. It needs outbound access to port 443. No inbound port is required.
* A database account you can create, or a database administrator who can create one.
* A Concatflow workspace.

**1. Create a read-only account**

The agent refuses to start with an account that can write. Create one that can only read. On PostgreSQL, run this as an administrator, replacing `app` with your database name:

```sql theme={"system"}
CREATE ROLE concatflow_reader LOGIN PASSWORD 'change-me';
GRANT CONNECT ON DATABASE app TO concatflow_reader;
GRANT USAGE ON SCHEMA public TO concatflow_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO concatflow_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO concatflow_reader;
```

Pick a real password. To expose more schemas, or for MySQL and MariaDB, see [Create a read-only account](https://docs.concatflow.com/private-databases/guides/read-only-account.md).

**2. Create the dataset**

In the dashboard, open **Datasources**, then **New dataset**. If the team intro appears, choose **Start with Orbo**. Pick your database engine, and select **Through an agent**. Name the dataset and select **Continue**.

> [!NOTE]
>
> The connection type is set once. To move an existing dataset behind an agent, create a new dataset.

**3. Generate an enrollment token**

Select **Generate a token**. The dashboard shows a `docker run` command with the token filled in.

The token works once and expires after 7 days. Generating a new one cancels the previous one.

**4. Run the agent**

On the machine that can see the database, run the command. Fill in `DATABASE_URL` yourself, in your terminal. Never paste the password into the dashboard.

```bash theme={"system"}
docker run -d --name cubit-agent --restart unless-stopped \
  --hostname db-agent-1 \
  -e CUBIT_ENROLL_TOKEN=<your-token> \
  -e CUBIT_API_URL=https://api.concatflow.com \
  -e DATABASE_URL="postgresql://concatflow_reader:<password>@<host>:5432/app" \
  -v cubit-agent:/data \
  ghcr.io/usecubit/source-client:0.1.0
```

> [!WARNING]
>
> Keep the `/data` volume. The agent stores its credentials there after enrolling. Without the volume, a restart starts from scratch, and the used token is refused.

`--hostname` sets the name the dashboard shows for this agent. Without it, Docker uses the container ID.

**5. Check the logs**

```bash theme={"system"}
docker logs cubit-agent
```

A healthy agent prints these two lines:

```text theme={"system"}
INFO source_client enrolled on dataset 70c16a4e-8a43-4df5-b881-c31ea790319a
INFO source_client serving dataset 70c16a4e-8a43-4df5-b881-c31ea790319a
```

If the agent exits instead, the last line says why. See [Troubleshooting](https://docs.concatflow.com/private-databases/troubleshooting.md).

**6. Pick your schemas**

Back in the dashboard, the agent shows as **Online**. Within a few seconds the flow moves on to the schemas the agent found. Pick the ones to expose and continue.

## Next steps

> **[Run two agents](https://docs.concatflow.com/private-databases/guides/high-availability.md)**
>
> Keep the dataset online when one machine goes down.

> **[Open the right ports](https://docs.concatflow.com/private-databases/guides/network.md)**
>
> The two hostnames your firewall must allow.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.