# Auto-start on Boot

> Configure pgcli to automatically start PostgreSQL instances and services after a host reboot

---

LLMS index: [llms.txt](/llms.txt)

---

pgcli can automatically start PostgreSQL instances, backup containers, PgBouncer services, and etcd members after a host reboot. This feature uses system service managers:
- **Linux**: systemd user units
- **macOS**: launchd LaunchAgents

## How It Works

When you enable auto-start, pgcli creates a system service that runs `pg start --autostart` at boot time (or user login). The `--autostart` flag starts only the instances and services marked with `autostart: true` in your configuration.

Auto-start is **config-driven**: if you run `pg stop` (or `pg stop --all`) on an instance, it will still be started automatically at the next boot. To prevent auto-start, use `pg autostart disable`.

**Default behavior**: The backup container has `autostart: true` by default in new configurations. Instances, PgBouncer, and etcd members default to `autostart: false` and must be explicitly enabled.

## Enable Auto-start

### For a Single Instance

```bash
pg autostart enable -i <instance-name>
```

Example:
```bash
pg autostart enable -i default
```

This adds `autostart: true` to the instance configuration and creates/updates the boot service.

### For the Backup Container

```bash
pg autostart enable --backup
```

Enables auto-start for the shared pgBackRest backup container.

### For PgBouncer

Enable auto-start for a PgBouncer associated with a specific instance:
```bash
pg autostart enable --pgbouncer -i <instance-name>
```

Or for a remote PgBouncer:
```bash
pg autostart enable --pgbouncer --pg-name <remote-name>
```

### For an etcd Member

Enable auto-start for an etcd member installed via `pg addon install etcd`:
```bash
pg autostart enable --etcd --name <member-name>
```

The member name defaults to `etcd` when `--name` is omitted:
```bash
pg autostart enable --etcd
```

Repeat for each member of a cluster (`m1`, `m2`, `m3`, …) — autostart is
per-member. On a cross-host cluster, run the command on each host for that
host's member(s).

**Boot is start-only.** At boot pgcli just brings the member's existing
container up (`podman start`, recreating the container from config only if it
is missing or stuck in an improper state). It never re-registers membership —
a data-dir-initialized etcd member reloads its cluster from disk and rejoins
on a plain start, so it must have been installed while the cluster was
reachable first. Starting members before quorum forms briefly reports
`etcdserver: no leader`; that is normal and resolves once enough members are
up.

## Disable Auto-start

```bash
pg autostart disable -i <instance-name>
pg autostart disable --backup
pg autostart disable --pgbouncer -i <instance-name>
pg autostart disable --pgbouncer --pg-name <remote-name>
pg autostart disable --etcd --name <member-name>
```

When all auto-start targets are disabled, the boot service is automatically removed.

## Check Status

```bash
pg autostart status
```

Shows:
- Which instances and services have auto-start enabled
- The boot service unit name and state
- Linger status (Linux) — required for rootless podman to start services at boot time

## Platform-Specific Behavior

### Linux (systemd)

The boot service is created as a systemd user unit: `pgcli-autostart-<hash>.service`

**Important**: Rootless podman requires `loginctl enable-linger` to start containers at boot time (before the user logs in). pgcli attempts this automatically but will print a hint if it fails.

Without linger, the service starts at user login instead of at system boot.

#### Systemd Unit Configuration

The systemd unit generated by pgcli includes the following key settings:

```ini
[Service]
Type=oneshot
Delegate=yes
RemainAfterExit=yes
```

- **Delegate=yes** - Delegates cgroup control to the service process, allowing rootless podman to properly manage container cgroup hierarchies
- **RemainAfterExit=yes** - Keeps the service in `active` state after execution completes, rather than immediately transitioning to `inactive`
- **Type=oneshot** - Executes `pg start --autostart` once and exits

#### Cgroup Isolation and Automatic Fallback

**Problem**: When containers are started by a systemd user unit, accessing them from SSH sessions or other contexts may encounter cgroup permission errors:

```
Error: crun: writing file `/sys/fs/cgroup/.../cgroup.procs`: Permission denied: OCI permission denied
```

**Cause**: Containers started by systemd user units reside in the `user@1000.service/app.slice` cgroup subtree, while SSH sessions are in `session-N.scope` - different cgroup scopes.

**Solution**: pgcli automatically detects cgroup permission errors and re-executes the command via `systemd-run --user --scope`. This creates a transient scope that can join the container's cgroup subtree.

**Affected commands** (automatic fallback):
- `pg exec` - Execute SQL or container commands
- `pg psql` - Interactive psql sessions
- `pg status` - Check container status
- `pg backup` - Backup operations
- `pg extension` - Extension management
- All other `podman exec` operations

**Unaffected commands**:
- `pg start` - Start containers (uses systemd-run itself)
- `pg stop` - Stop containers
- `pg restart` - Restart containers

#### Viewing Service Status

`pg autostart status` now displays detailed systemctl information:

```bash
pg autostart status
```

Output includes:
- Enable status of all auto-start targets
- systemd unit name, load state, active state
- Service logs and recent execution records
- Linger status

Example output:
```
=== Auto-start targets ===
  instance default         enabled
  backup                 enabled
  etcd m1                  enabled

=== Boot service ===
  Unit:      pgcli-autostart-554d14ed
  Installed: yes
  Enabled:   enabled
  Running:   active
  Linger:    yes

=== Service status ===
     Loaded: loaded (/home/user/.config/systemd/user/pgcli-autostart-554d14ed.service; enabled)
     Active: active (exited) since Mon 2026-09-07 14:30:00 CST; 2h ago
    Process: 1234 pg -c /home/user/.config/pgcli/pg.yaml start --autostart (code=exited, status=0/SUCCESS)
   Main PID: 1234 (code=exited, status=0/SUCCESS)
```

### macOS (launchd)

The boot service is created as a LaunchAgent: `com.pgcli.autostart-<hash>.plist`

**Note**: macOS LaunchAgents run at user login, not at system boot. This is a macOS limitation — rootless podman cannot start services before the user logs in.

## Configuration File

The `autostart: true` flag appears in your pgcli configuration file:

```yaml
instances:
  default:
    # ... other settings ...
    autostart: true

backup:
  # ... other settings ...
  autostart: true

addons:
  # For PgBouncer
  pgbouncer:
    default:
      # ... other settings ...
      autostart: true
  # For etcd members
  etcd:
    m1:
      # ... other settings ...
      autostart: true
```

## Boot Service Behavior

The boot service runs `pg start --autostart`, which:
1. Starts all instances with `autostart: true`
2. Starts the backup container if `backup.autostart: true`
3. Starts PgBouncer services with `autostart: true`
4. Starts etcd members with `autostart: true` (start-only; see above)

If no auto-start targets are configured, the service exits successfully (no error).

Each manager (PostgreSQL, backup, PgBouncer, etcd) self-heals stale rootless
podman state at startup — after a reboot the pause-process record is dead, so
the service transparently runs `podman system migrate` before touching
containers. This means boot works even when only addons (no PG instance) are
marked for auto-start.

## Troubleshooting

### Service Failed to Start

Check the boot service logs:

**Linux (systemd)**:
```bash
journalctl --user -u pgcli-autostart-<hash>.service
```

**macOS (launchd)**:
```bash
cat ~/Library/Logs/pgcli-autostart-<hash>.log
```

### Linux: "XDG_RUNTIME_DIR is not set"

This error occurs when systemd user units are not available. Ensure you have a proper user session:
- SSH sessions should support systemd --user by default
- Terminal sessions in desktop environments support systemd --user
- Cron jobs and other non-interactive contexts do not support systemd --user

### Linux: Auto-start Only Works After Login

Run `loginctl enable-linger <your-username>` to allow rootless podman to start services at boot time.

### macOS: Auto-start Only Works After Login

This is expected behavior. macOS LaunchAgents cannot run before user login due to rootless podman constraints.

## Examples

Enable auto-start for a complete production setup:

```bash
# Enable the default instance
pg autostart enable -i default

# Enable the backup container
pg autostart enable --backup

# Enable PgBouncer for the default instance
pg autostart enable --pgbouncer -i default

# Enable etcd members m1 and m2 (names from pg addon list / pg.yaml)
pg autostart enable --etcd --name m1
pg autostart enable --etcd --name m2

# Check the status
pg autostart status
```

After the next reboot, all these services will start automatically.

---

Backlinks:

- [Documentation](/docs/)
- [Etcd](/docs/addon/etcd/)
- [HAProxy](/docs/addon/haproxy/)
- [MinIO](/docs/addon/minio/)
- [PgDog](/docs/addon/pgdog/)
- [Silo](/docs/addon/silo/)
- [Patroni HA](/docs/ha-cluster/ha/)
- [Platform Support](/docs/platform/)
- [Quick Start](/docs/quickstart/)
