# Quickstart

> First successful mount (postgres:// or tiger:), explore with ls/cat, demo.sh workflows, and expected success signals.

- Repository: timescale/tigerfs
- GitHub: https://github.com/timescale/tigerfs
- Human docs: https://grok-wiki.com/public/docs/timescale-tigerfs-60719456a5c3
- Complete Markdown: https://grok-wiki.com/public/docs/timescale-tigerfs-60719456a5c3/llms-full.txt

## Source Files

- `docs/quickstart.md`
- `scripts/demo/demo.sh`
- `scripts/demo/README.md`
- `internal/tigerfs/cmd/mount.go`
- `test/integration/setup.go`

---

---
title: "Quickstart"
description: "First successful mount (postgres:// or tiger:), explore with ls/cat, demo.sh workflows, and expected success signals."
---

`tigerfs mount` connects to PostgreSQL (direct URI, `PG*` environment variables, or `tiger:` / `ghost:` backend prefixes) and exposes the default schema as a directory tree at a mountpoint. A successful first mount returns table names from `ls`, row payloads from `cat`, and registry entries visible to `tigerfs status`.

## Prerequisites

| Requirement | Notes |
|-------------|-------|
| TigerFS binary | `curl -fsSL https://install.tigerfs.io \| sh`, `go install github.com/timescale/tigerfs/cmd/tigerfs@latest`, or build from source (`go build -o bin/tigerfs ./cmd/tigerfs`) |
| PostgreSQL | Reachable database with at least one user schema and tables |
| Linux | FUSE support (typically pre-installed) |
| macOS | No extra kernel extensions; TigerFS uses an in-process NFS v3 server |
| Demo only | Docker with Compose v2; macOS native demo also needs Go 1.21+ |

<Note>
Remote connections require TLS (`sslmode=require`) unless you pass `--insecure-no-ssl` or set `InsecureNoSSL` in config. Localhost and Unix sockets default to `sslmode=disable` when no `sslmode` is in the URI.
</Note>

## Fastest path: demo environment

From the repository root, `scripts/demo/demo.sh` starts PostgreSQL, mounts TigerFS, seeds file-first apps, and prints exploration commands.

<Tabs>
<Tab title="Auto-detect">
```bash
cd scripts/demo
./demo.sh start          # Darwin → --mac; Linux → --docker
./demo.sh status
./demo.sh shell          # cwd = mount root
ls
cat users/1.json
./demo.sh stop
```
</Tab>
<Tab title="Docker (any platform)">
```bash
cd scripts/demo
./demo.sh start --docker
./demo.sh shell          # inside container at /mnt/db
ls
cat users/1.json
cat products/1.json
ls orders/.first/10/
./demo.sh stop
```
</Tab>
<Tab title="macOS native">
```bash
cd scripts/demo
./demo.sh start --mac
ls /tmp/tigerfs-demo
cat /tmp/tigerfs-demo/users/1.json
cat /tmp/tigerfs-demo/blog/hello-world.md
./demo.sh stop
```
</Tab>
</Tabs>

### Demo lifecycle

```text
demo.sh start
  ├─ docker compose up (postgres; + tigerfs container in --docker mode)
  ├─ wait_for_postgres (init.sql → data-first tables)
  ├─ tigerfs mount postgres://demo:demo@… [--insecure-no-ssl]
  ├─ seed.sh <mount> → .build/blog|docs|snippets + sample files
  └─ print success + example commands

demo.sh stop
  ├─ unmount / kill tigerfs
  └─ docker compose down
```

| Command | Action |
|---------|--------|
| `start` | Build/start containers, mount, run `seed.sh` |
| `stop` | Unmount TigerFS, tear down containers |
| `status` | Report container and mount state |
| `restart` | `stop` then `start` |
| `shell` | Interactive session at mount root (`/mnt/db` in Docker, `/tmp/tigerfs-demo` on macOS) |

<ParamField body="--docker" type="flag">
Both PostgreSQL and TigerFS run in containers. Mount inside the `tigerfs` container at `/mnt/db`. Connection: `postgres://demo:demo@postgres:5432/demo`.
</ParamField>

<ParamField body="--mac" type="flag">
PostgreSQL in Docker on `localhost:5432`; TigerFS runs natively on the host at `/tmp/tigerfs-demo`. Connection: `postgres://demo:demo@localhost:5432/demo`.
</ParamField>

<ParamField body="--debug" type="flag">
Passes `--log-level debug` to the mount command.
</ParamField>

### Demo seed data

**Data-first** (from `init.sql` at PostgreSQL startup): `users` (~1,000 rows), `categories` (10, TEXT PK), `products` (~200), `orders` (~8,000, UUIDv7 PK), views, and indexes for `.by/` navigation.

**File-first** (from `seed.sh` after mount):

| Path | Format | History |
|------|--------|---------|
| `blog/` | Markdown, 5 posts | Yes |
| `docs/` | Markdown, 4 pages | Yes |
| `snippets/` | Plain text, 3 files | Yes |

## Mount your own database

<Steps>
<Step title="Verify connectivity">
```bash
tigerfs test-connection postgres://user:password@localhost:5432/mydb
```
<ResponseExample>
```text
Connected to PostgreSQL 16.x ...
Database:   mydb
User:       user
Schemas:    N
Tables:     M
```
</ResponseExample>
</Step>
<Step title="Create mountpoint and mount">
```bash
mkdir -p /mnt/db
tigerfs mount postgres://user:password@localhost:5432/mydb /mnt/db &
```
Or with standard PostgreSQL environment variables (no URI argument):
```bash
export PGHOST=localhost PGPORT=5432 PGUSER=user PGPASSWORD=password PGDATABASE=mydb
tigerfs mount /mnt/db &
```
</Step>
<Step title="Explore">
```bash
ls /mnt/db
ls -la /mnt/db/users
cat /mnt/db/users/1.json
cat /mnt/db/users/.info/schema
cat /mnt/db/users/.info/count
```
</Step>
<Step title="Unmount">
```bash
tigerfs unmount /mnt/db
```
</Step>
</Steps>

### Connection argument patterns

`mount` accepts one or two positional arguments. Resolution order:

| Args | Interpretation |
|------|----------------|
| `CONN MOUNT` | Explicit connection and mountpoint |
| `tiger:ID` or `ghost:ID` | Backend prefix; mountpoint defaults to `<default_mount_dir>/<ID>` (config default `/tmp`) |
| `MOUNT` only | Mountpoint; connection from `PG*` env or config |

<CodeGroup>
```bash title="postgres:// URI"
tigerfs mount postgres://user:pass@host:5432/db /mnt/db &
```
```bash title="PG* environment"
export PGHOST=localhost PGDATABASE=mydb PGUSER=user PGPASSWORD=secret
tigerfs mount /mnt/db &
```
```bash title="Tiger Cloud (auto mountpoint)"
tiger auth login   # prerequisite
tigerfs mount tiger:abcde12345
# → /tmp/abcde12345 by default
```
```bash title="Ghost"
ghost login
tigerfs mount ghost:fghij67890 /mnt/cloud &
```
</CodeGroup>

<Warning>
Demo and local Docker Postgres use `--insecure-no-ssl` because the sample connection strings omit TLS. Do not use that flag against production hosts.
</Warning>

### Useful mount flags

| Flag | Purpose |
|------|---------|
| `--foreground` | Run in foreground (default daemonizes) |
| `--read-only` | Disallow writes |
| `--schema` | Override default PostgreSQL schema |
| `--insecure-no-ssl` | Allow non-TLS remote connections |
| `--log-level debug` | Verbose structured logging to stderr |

## Explore with ls and cat

Each table in the default schema appears as a directory. Row IDs are files; extensions select serialization.

| Path | Result |
|------|--------|
| `/mnt/db/` | Table directories |
| `/mnt/db/users/123` | Row as TSV (default) |
| `/mnt/db/users/123.json` | Row as JSON object |
| `/mnt/db/users/123/email` | Single column value |
| `/mnt/db/users/.info/schema` | `CREATE TABLE` DDL |
| `/mnt/db/users/.info/columns` | Column names, one per line |
| `/mnt/db/users/.info/count` | `SELECT COUNT(*)` |
| `/mnt/db/users/.first/100/` | First 100 rows (directory listing) |
| `/mnt/db/users/.by/email/alice@example.com/` | Index lookup |

<RequestExample>
```bash
ls /mnt/db
cat /mnt/db/users/1.json
```
</RequestExample>

<ResponseExample>
```text
categories/  orders/  products/  users/

{"id":1,"name":"Alice Smith","first_name":"Alice","last_name":"Smith",...}
```
</ResponseExample>

Dot-directories (`.info`, `.filter`, `.by`, `.export`, …) are hidden from plain `ls` but visible with `ls -a` or `ls -la`.

### Minimal file-first workspace

```bash
echo "markdown,history" > /mnt/db/.build/notes
cat > /mnt/db/notes/hello.md << 'EOF'
---
title: Hello
---
Body text.
EOF
ls /mnt/db/notes/
cat /mnt/db/notes/hello.md
```

Writes go through PostgreSQL transactions; concurrent readers on other mounts see updates immediately (no row-content caching).

## Expected success signals

Use these checks to confirm the mount is healthy before deeper workflows.

### Filesystem probes

| Check | Success signal |
|-------|----------------|
| `ls <mountpoint>` | Lists table (and workspace) directories without errno |
| `cat <mountpoint>/users/1.json` | Valid JSON for an existing row |
| `cat <mountpoint>/users/.info/count` | Non-empty integer string |
| `ls -a <mountpoint>/notes` | Shows `.history/`, `.savepoint/`, `.undo/` when `history` was enabled |

### CLI registry and connectivity

```bash
tigerfs status
tigerfs status /mnt/db
tigerfs test-connection postgres://...
```

<ResponseField name="status table" type="object">
Columns: `MOUNTPOINT`, `DATABASE` (password-redacted), `PID`, `STATUS` (`active` / `stale`), `UPTIME`. Empty table means no registered mounts.
</ResponseField>

<ResponseField name="test-connection" type="object">
Prints PostgreSQL version, `current_database()`, `current_user`, and counts of accessible schemas and tables. Exit code 0 only when the pool connects and queries succeed.
</ResponseField>

### Demo launcher output

After `./demo.sh start`:

```text
==> PostgreSQL is ready
==> Connection string: postgres://demo:demo@...
==> Mounting TigerFS at ...
==> Seeding file-first apps...
==> TigerFS mounted successfully!
```

`./demo.sh status` on a healthy run:

| Mode | Containers | Mount |
|------|------------|-------|
| `--docker` | `RUNNING` | `MOUNTED` at `/mnt/db` (inside container) |
| `--mac` | Postgres running | `MOUNTED` at `/tmp/tigerfs-demo` |

Failure paths exit non-zero with `Failed to mount TigerFS` or `PostgreSQL init did not complete after 60 seconds`.

### Process and OS mount table

```bash
# macOS / Linux
mount | grep tigerfs-demo    # macOS demo path
pgrep -f "tigerfs.*mnt/db"   # tigerfs process

# Docker demo
docker compose -f scripts/demo/docker/docker-compose.yml exec tigerfs mount | grep /mnt/db
```

On successful `tigerfs mount`, the daemon logs `Filesystem mounted successfully` (warn-level in production, debug with `--log-level debug`). `tigerfs unmount` prints `Successfully unmounted <path>`.

## demo.sh exploration cheat sheet

Inside the mount root (via `./demo.sh shell` or `cd /tmp/tigerfs-demo`):

<CodeGroup>
```bash title="Data-first"
cat users/1.json
cat products/.by/category/electronics/.export/json
ls orders/.sample/10/
cat categories/.export/tsv
```
```bash title="File-first"
ls blog/
cat blog/hello-world.md
cat docs/getting-started/installation.md
cat snippets/todo.txt
ls docs/.history/getting-started/installation.md/
```
</CodeGroup>

## Common first-mount failures

| Symptom | Likely cause | Mitigation |
|---------|--------------|------------|
| `connection failed` from `test-connection` | Wrong host, credentials, or `sslmode` | Fix URI; use `--insecure-no-ssl` only for known-local/demo DBs |
| `Failed to mount TigerFS` in demo | Postgres not ready, port conflict, stale mount | `./demo.sh stop`; on macOS check `lsof -i :5432` |
| Empty `ls` at mountpoint | Wrong `--schema`, empty database, or mount not active | `tigerfs status`; confirm tables exist in target schema |
| `tigerfs mount tiger:ID` errors | Tiger CLI not authenticated | `tiger auth login`; verify service ID |
| Mount already exists | Prior demo or manual mount | `./demo.sh stop` or `tigerfs unmount <path>` |

Structured hints for filesystem operations appear on stderr as JSON when TigerFS returns errno (for example invalid synth task numbers). Run mounts with `--log-level debug` when diagnosing.

## Related pages

<CardGroup>
<Card title="Installation" href="/installation">
Install paths, platform prerequisites (FUSE vs NFS), and verification before your first mount.
</Card>
<Card title="Demo environment" href="/demo-environment">
Full demo architecture, `init.sql` / `seed.sh` split, and Docker vs macOS troubleshooting.
</Card>
<Card title="Filesystem as API" href="/filesystem-as-api">
Mount hierarchy, dot-directory control surface, and path-to-SQL mapping.
</Card>
<Card title="Cloud backends" href="/cloud-backends">
`tiger:` and `ghost:` prefixes, `create` / `fork`, and CLI credential requirements.
</Card>
<Card title="Connection reference" href="/connection-reference">
`postgres://` URIs, `PG*` variables, TLS rules, and pool settings.
</Card>
<Card title="Troubleshooting" href="/troubleshooting">
Stale mounts, force unmount, and errno recovery.
</Card>
</CardGroup>
