# Linux server

Run Patterm as a systemd user service on a Linux machine, so your agents keep working when no window or browser is open.

The service is the same Patterm you get from the desktop app, without a window. You open it from a browser, either on the same machine or from another device (see [Browser and phone access](https://patterm.com/docs/browser-and-phone.md)).

## Requirements

- Linux on x64 or arm64, with systemd and user services.
- Patterm installed with the release installer (see [Installation](https://patterm.com/docs/installation.md)). The release bundles its own Node, so you do not need to install Node.
- The agent CLIs you want to use, installed and signed in on the server, under the same account that runs the service.

Patterm runs agents with your user account's permissions. Run the service under the account that owns your repositories and CLI logins.

## Start the service

```sh
patterm --headless
```

The first time you run this, Patterm writes the service files and starts `patterm.service`. Later runs start the same service and do not restart it or interrupt its agents. Open `http://localhost:8787` on that machine.

A new service accepts connections from the machine it runs on only. To open it from your phone or laptop, change **Open from** in **Settings › Remote access**. See [Browser and phone access](https://patterm.com/docs/browser-and-phone.md).

`patterm --headless` does not start the service at login or after a reboot. To do that, enable the unit and turn on lingering, which keeps your user services running after you log out:

```sh
systemctl --user enable patterm.service
sudo loginctl enable-linger "$USER"
```

### Check on it

```sh
systemctl --user status patterm.service
journalctl --user -u patterm.service -f
curl --fail http://127.0.0.1:8787/health
```

Startup and shutdown messages go to the journal. `/health` reports whether the service is ready, including whether its terminal engine is available. Use your own port in the URL if you changed `PATTERM_PORT`.

If the terminal engine exits, the service stops itself and systemd starts it again. Your agents are not affected, because they run in separate terminal host units (see below).

## Where things live

| What                                    | Where                                                                                  |
| --------------------------------------- | -------------------------------------------------------------------------------------- |
| Installed versions                      | `~/.local/share/patterm/versions/<version>`, with `current` pointing at the one in use |
| Launcher                                | `~/.local/bin/patterm`                                                                 |
| Service unit and terminal host template | `~/.config/systemd/user/patterm.service` and `patterm-terminal@.service`               |
| Service settings                        | `~/.config/patterm/patterm.env`                                                        |
| Server data                             | `~/.local/share/patterm-server`                                                        |

Patterm follows `XDG_CONFIG_HOME` and `XDG_DATA_HOME` when they are set. Set `PATTERM_HOME` before installing to put the installed versions somewhere other than `~/.local/share/patterm`.

The data directory must be outside the installation, so updates never touch your databases. See [Data and privacy](https://patterm.com/docs/data-and-privacy.md) for what is inside it.

## Service settings

The service reads `patterm.env`. It uses systemd's `KEY="value"` syntax, so do not source it from a shell. The installer writes `PATH`, `HOME` and `SHELL` from the account that installed it, so agents started by the service can find your CLIs.

| Setting                 | Default                         | What it does                                                                                                                          |
| ----------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `PATTERM_PORT`          | `8787`                          | The port. The listener is always on `127.0.0.1`, plus the address you choose if you select **Network**.                               |
| `PATTERM_DATA_DIR`      | `~/.local/share/patterm-server` | Where Patterm keeps its data.                                                                                                         |
| `PATTERM_OWNER_LOGIN`   | not set                         | A Tailscale login. Requests that Tailscale says come from anyone else are refused.                                                    |
| `PATTERM_PUBLIC_ORIGIN` | not set                         | Only for servers set up before **Settings › Remote access** existed. A server with a Remote access setting works out its own address. |

Choose **Open from**, the password and **Only me** in **Settings › Remote access**. Applying a change restarts the web server only. Agents and terminals keep running and open pages reconnect.

To set things from the command line instead, run the service installer with the bundled Node. Stop the service first: the installer refuses to change access settings while Patterm is using the data directory.

```sh
systemctl --user stop patterm.service
~/.local/share/patterm/current/runtime/node \
  ~/.local/share/patterm/current/scripts/install-service.mjs \
  --remote-access tailscale
systemctl --user daemon-reload
systemctl --user start patterm.service
```

| Flag                                        | Meaning                                                                      |
| ------------------------------------------- | ---------------------------------------------------------------------------- |
| `--remote-access local\|tailscale\|network` | Where browsers can open Patterm from.                                        |
| `--bind ADDRESS`                            | The machine address to listen on. Required with `network`.                   |
| `--password` or `--password-stdin`          | Ask for a password, or read one from standard input. `network` requires one. |
| `--owner-login LOGIN`                       | Refuse tailnet requests from any other Tailscale login.                      |
| `--data-dir PATH`                           | Use a different data directory.                                              |
| `--output-dir PATH`                         | Write preview files to a directory and change nothing live.                  |

Keep the data directory fixed while agents are running. To move it, use **Quit Patterm** first and check that every `patterm-terminal@` unit has stopped.

## Desktop and server do not share data

The desktop app and the server each have their own data directory. The desktop app keeps its data in `~/.config/patterm-desktop`.

Only one Patterm can use a data directory at a time. Patterm takes a lock on it before opening the databases or starting anything. If you point a second Patterm at a directory that is in use, it stops with:

```txt
Patterm is already using <directory>, or its runtime lock is unavailable
```

To use both the desktop app and a server, pair them as hosts. See [Multiple hosts](https://patterm.com/docs/multiple-hosts.md).

## What survives a restart

An installed service runs each terminal in its own `patterm-terminal@` unit, separate from `patterm.service`. This means:

- Stopping or restarting `patterm.service` does not stop your agents or commands. A native `sleep` keeps sleeping.
- When the service starts again it reconnects to the same terminals.
- Closing a browser, losing the network or putting your laptop to sleep does not stop anything.
- Patterm timers keep their deadlines. If one expires while the service is down, the callback is delivered after it reconnects.
- Tool calls an agent makes while the service is down can fail, and Patterm does not replay them.

A reboot, or a failure of a terminal host, ends the processes it was running. Patterm does not resume agents after a reboot. Resume each conversation yourself from the project's history. See [Conversation history](https://patterm.com/docs/conversation-history.md).

## Stop everything

`systemctl --user stop patterm.service` stops the web service and leaves agents running.

To stop agents too, open the command palette and choose **Quit Patterm**. Its confirmation tells you how many agents and commands across all projects will stop, including sleeps and Patterm timers. Quit stops every terminal host, including hosts from older versions. Saved conversations remain available to resume.

## Update

Rerun the installer with `--update`, as described in [Installation](https://patterm.com/docs/installation.md#update). It stops the service, switches `current` to the new version, restarts the service and waits for `/health`. It keeps the new version and the one before it.

Running agents keep the version they started with. New sessions use the new version. Refresh your browser afterwards.

> [!WARNING]
> Never run an older Patterm against databases a newer one has migrated. Patterm refuses to open them and names the migrations it does not know.

### Backups before migrations

When an update has database migrations to run, Patterm first copies both databases into `backups/pre-migration-<time>/` in the data directory. The last two sets are kept. If the backup fails, for example because the disk is full, Patterm does not start rather than migrate without one. Uploads and images are not included.

To roll back an update that migrated the databases:

1. Use **Quit Patterm** and check that `patterm.service` and every `patterm-terminal@` unit are inactive.
2. Move `app.db`, `history.db` and their `-wal` and `-shm` files out of the data directory, and keep them until you have checked the rollback.
3. Copy `app.db` and `history.db` from the newest `backups/pre-migration-*` set into the data directory. `manifest.json` in the set lists a SHA-256 hash for each copy.
4. Install the previous version by running the installer with `--version <version> --allow-downgrade`, adding `--update` if the service is active.

## Uninstall

Run the uninstaller described in [Installation](https://patterm.com/docs/installation.md#uninstall). It stops every Patterm agent and terminal, then removes the services, launcher and installed versions.

## Related

- [Browser and phone access](https://patterm.com/docs/browser-and-phone.md)
- [Multiple hosts](https://patterm.com/docs/multiple-hosts.md)
- [Troubleshooting](https://patterm.com/docs/troubleshooting.md)

---

This is one page of the Patterm documentation. The index of every page is at https://patterm.com/llms.txt.
