# Quickstart

> Shortest local path: build, --initdb with -L, start with required stack and io_method settings, connect with psql, and verify version() and a trivial query.

- Repository: malisper/pgrust
- GitHub: https://github.com/malisper/pgrust
- Human docs: https://grok-wiki.com/public/docs/malisper-pgrust-7e0c8e82bc21
- Complete Markdown: https://grok-wiki.com/public/docs/malisper-pgrust-7e0c8e82bc21/llms-full.txt

## Source Files

- `README.md`
- `crates/backend/main/initdb/src/lib.rs`
- `crates/_support/seam/init/src/bin/postgres.rs`
- `scripts/run-regression`
- `crates/backend/utils/misc/guc_tables/src/tables.rs`

---

---
title: "Quickstart"
description: "Shortest local path: build, --initdb with -L, start with required stack and io_method settings, connect with psql, and verify version() and a trivial query."
---

The `postgres` binary (`crates/_support/seam/init`, `[[bin]] name = "postgres"`) is the single entry shell for postmaster, bootstrap, single-user, and pgrust’s own cluster init. After a release build with `PGRUST_PGSHAREDIR` pointed at the vendored share tree, create `PGDATA` with `postgres --initdb -L …`, start postmaster with `io_method=sync` plus stack overrides, then verify with a Postgres 18 `psql` client.

## Prerequisites

| Requirement | Role |
| --- | --- |
| Rust toolchain + `cargo` | Builds `target/release/postgres` |
| Clone with `vendor/postgres-18.3/share` | Supplies `postgres.bki`, system SQL, config samples, timezone data for `-L` / baked share |
| Host libs (OpenSSL, ICU, …) | Link-time deps for the release binary |
| Postgres 18 `psql` | Only external client; pgrust does not ship a `psql` replacement |
| Non-root OS user | Server and `--initdb` refuse root (`check_root`) |

### Host packages

<Tabs>
  <Tab title="macOS">
```bash
brew install icu4c openssl@3 libpq

export LIBRARY_PATH="$(brew --prefix openssl@3)/lib:${LIBRARY_PATH:-}"
export PKG_CONFIG_PATH="$(brew --prefix openssl@3)/lib/pkgconfig:$(brew --prefix icu4c)/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
export PATH="$(brew --prefix libpq)/bin:$PATH"
```
  </Tab>
  <Tab title="Debian/Ubuntu">
```bash
sudo apt-get update
sudo apt-get install -y build-essential pkg-config libicu-dev libssl-dev \
  libldap2-dev libpam0g-dev postgresql-client-18
```
  </Tab>
</Tabs>

<Note>
If `psql` is not on `PATH`, set `PGRUST_PSQL=/path/to/psql` for scripts, or pass the full path when connecting.
</Note>

## Build

Bake the vendored share path at compile time, then produce the release binary:

```bash
PGRUST_PGSHAREDIR="$PWD/vendor/postgres-18.3/share" \
cargo build --release --locked --bin postgres
```

| Output | Path |
| --- | --- |
| Server binary | `target/release/postgres` |
| Share tree for `-L` | `vendor/postgres-18.3/share` |

`PGRUST_PGSHAREDIR` is compiled into path helpers (`option_env!("PGRUST_PGSHAREDIR")`, default fallback `/usr/local/pgsql/share`). Runtime init still needs an explicit `-L` when the executable is not under a classic install layout.

Optional version check (must-be-first style flag):

```bash
target/release/postgres --version
# postgres (PostgreSQL) 18.3
```

## Initialize a cluster

`--initdb` / `initdb` is intercepted in `pg_main` before normal dispatch and handed to the ported initdb driver. The driver scaffolds `PGDATA`, writes config from share samples, then re-execs the same binary for `--boot` and `--single`.

```bash
target/release/postgres --initdb \
  -D /tmp/pgrust-data \
  -L "$PWD/vendor/postgres-18.3/share" \
  --no-locale \
  --encoding UTF8 \
  -U postgres
```

### Flags used here

| Flag | Meaning |
| --- | --- |
| `-D` / `--pgdata` | Data directory (required) |
| `-L` | Share directory override (must contain `postgres.bki` and related files) |
| `-U` / `--username` | Bootstrap superuser (default: `$USER` or `postgres`) |
| `-E` / `--encoding` | Server encoding; `UTF8` maps to encoding id 6 |
| `--no-locale` | Forces `C` collate/ctype |

<Warning>
initdb argv is **space-separated** (`--opt value`). Unsupported options (for example `-A`, `--data-checksums`, `--pwfile`) fail with `unrecognized initdb option`.
</Warning>

### Success signal

On success, stderr ends with:

```text
Success. You can now start the database server using pgrust/postgres -D /tmp/pgrust-data
```

Phases printed along the way: configuration files → bootstrap script → post-bootstrap initialization.

## Start the server

pgrust requires explicit I/O and stack settings that differ from a stock C Postgres boot.

```bash
ulimit -s 65520

RUST_MIN_STACK=33554432 target/release/postgres \
  -D /tmp/pgrust-data \
  -F \
  -c listen_addresses= \
  -k /tmp \
  -p 5432 \
  -c io_method=sync \
  -c max_stack_depth=60000
```

### Required runtime settings

| Setting | Value used in quickstart / harnesses | Why |
| --- | --- | --- |
| `io_method` | `sync` | GUC boot default is `worker` (`IOMETHOD_WORKER`). Docker, README, and `scripts/run-regression` all force `sync` for a working boot path. |
| `max_stack_depth` | `60000` (kB) | Boot default is raised to `2048` kB vs C’s `100`; regress/harness still pass a much higher override for deep catalog work. |
| `RUST_MIN_STACK` | `33554432` | Rust thread stack floor; default OS stack is too small. |
| `ulimit -s` | `65520` | Process stack size; Docker entrypoint applies the same. |

### Socket-only local flags

| Flag | Effect in this recipe |
| --- | --- |
| `-D` | Data directory from `--initdb` |
| `-F` | Used by the regression harness start line (fsync off for local smoke) |
| `-c listen_addresses=` | Empty list: no TCP listen; Unix socket only |
| `-k /tmp` | Unix socket directory (keep short on macOS `sun_path` limits) |
| `-p 5432` | Port for the socket |

Docker’s entrypoint injects the same `io_method=sync` and `max_stack_depth=60000` (plus image-specific `unix_socket_directories`) on every server start.

## Connect and verify

In another terminal, use a Postgres 18 client against the socket:

```bash
psql -h /tmp -p 5432 -U postgres -d postgres \
  -c "select version(), 1 + 1 as two"
```

### Expected signals

| Check | Pass condition |
| --- | --- |
| Ready | `psql` connects without “connection refused” / “no such file” |
| Version | `version()` reports a PostgreSQL 18.3-shaped banner (binary `--version` is `postgres (PostgreSQL) 18.3`) |
| Query | `two` column is `2` |

Readiness probe used by `scripts/run-regression`:

```bash
psql -h /tmp -p 5432 -U postgres -d postgres -c 'SELECT 1'
```

## End-to-end path (compact)

```text
vendor/postgres-18.3/share  ──-L / PGRUST_PGSHAREDIR──►  postgres --initdb -D PGDATA
                                                              │
                                                              ▼
                         RUST_MIN_STACK + ulimit -s           PGDATA
                         -c io_method=sync
                         -c max_stack_depth=60000
                                                              │
                                                              ▼
                         psql -h <sockdir> -p <port>  ──►  version() / SELECT 1
```

## Common failures

| Symptom | Fix |
| --- | --- |
| Boot fails without `io_method=sync` | Pass `-c io_method=sync` (default is `worker`) |
| Stack overflow / “stack depth limit exceeded” | Raise `ulimit -s`, `RUST_MIN_STACK`, and `-c max_stack_depth=…` |
| initdb cannot find bootstrap files | Pass `-L "$PWD/vendor/postgres-18.3/share"`; rebuild with `PGRUST_PGSHAREDIR` if timezone/share resolution is wrong |
| `unrecognized initdb option` | Drop unsupported C-initdb flags; use only the supported subset |
| `"root" execution of the PostgreSQL server is not permitted` | Run as a non-root user |
| `no psql client found` | Install `libpq` / `postgresql-client-18` or set `PGRUST_PSQL` |

## Docker alternative

If you only need a containerized smoke test (not a source build):

```bash
docker run -d --name pgrust -e POSTGRES_PASSWORD=secret malisper/pgrust:v0.1
# wait for readiness, then:
docker exec -it -e PGPASSWORD=secret pgrust psql -h 127.0.0.1 -U postgres
```

The image entrypoint runs pgrust `--initdb` with `-L` and always injects the stack / `io_method` server opts.

## Optional: regression smoke after local bring-up

With the same binary and a Postgres 18 `psql` on `PATH`:

```bash
PGRUST_BIN="$PWD/target/release/postgres" \
scripts/run-regression
```

The script re-runs `--initdb` against the vendored share, starts postmaster with the same `io_method=sync` / stack pattern, and compares SQL output to vendored expected files.

## Next

<CardGroup>
  <Card title="Build from source" href="/build-from-source">
    Host packages, `PGRUST_PGSHAREDIR` bake-in, release binary location, and wasm notes.
  </Card>
  <Card title="Initialize a cluster" href="/init-cluster">
    Full `--initdb` phases, directory layout, and success text.
  </Card>
  <Card title="Run the server" href="/run-server">
    Postmaster flags, readiness, and connection details beyond the minimal recipe.
  </Card>
  <Card title="Configuration reference" href="/configuration-reference">
    `io_method`, stack GUCs/env, listen/socket settings, and build-time `PGRUST_*` paths.
  </Card>
  <Card title="Docker" href="/docker">
    Official image contract and first-boot entrypoint behavior.
  </Card>
  <Card title="Troubleshooting" href="/troubleshooting">
    Known failure modes for stack, share paths, initdb gaps, root, and clients.
  </Card>
</CardGroup>
