Install

You are the person who runs the machine. People who only sign in want the other guide.

Installing the PocketContext server

This guide is for the person who runs the machine. You install the server, then you attach an application to it.

You are not installing the CRM, the wiki, or the other apps as part of the server download. Each app is set up on its own. The server is the program they all run on. It stores data, checks login, and gives coding assistants a read-only SQL door. PocketBase, the open-source product inside the server, supplies the database, login, and the records API. The admin screen is at /_/ on whatever address you serve.

People who only sign in and use an app should follow the end-user guide.

What you are choosing

There are four ways to get a running server. They differ by who owns the computer and how the app gets onto it.

flowchart TB
  you[You, the admin]
  you --> own[A computer you already have]
  you --> cloud[A new cloud machine]

  own --> binary[Release binary]
  own --> source[Build from source]
  binary --> oneapp[Run one app on that computer]
  source --> oneapp

  cloud --> deploy[PocketDeploy]
  deploy --> vps[Ubuntu machine plus the app container]
Way Use it when
Release binary You want the published server on Linux or an Apple Silicon Mac, without compiling.
Build from source You are developing, or you need the exact commit an application pins.
One app on that same computer You want a private server on localhost for one application.
PocketDeploy You want a cloud machine, DNS, and the application container created from a config file.

A release install does not create application data. pocketcontext --version only prints the version. The database appears when you serve an application and point --dir at a data folder.

The shape of a running app

flowchart LR
  binary[pocketcontext program]
  app[Application folder]
  data[(pb_data on disk)]
  person[Browser or assistant]

  app --> binary
  binary --> data
  person --> binary

The application folder holds three things the server loads:

Piece What it is
pb_migrations The tables.
pb_hooks Extra checks when records change.
pocketcontext.json Which tables SQL may see.
POCKETCONTEXT_VERSION The server commit that application was tested with.

Each application gets its own process, its own data folder, and its own Google login settings. Serving the wiki does not serve the CRM.

Keep pb_data outside Git. It holds the database and credentials.

1. Release binary on a computer you have

This is the path for Linux on 64-bit Intel or ARM, and for macOS 15 or later on Apple Silicon. The published Mac build is not for Intel Macs. Linux packages are tested on Ubuntu 24.04, Alpine 3.23, and Debian 12. That is the set the release was exercised on.

You need curl, tar, and either sha256sum or shasum. You do not need sudo. The installer does not edit your shell profile.

curl -fsSL https://pocketcontext.com/pocketcontext/install.sh | sh

The script downloads the archive for this release, checks its SHA-256 checksum, and installs the program at ~/.local/bin/pocketcontext. It replaces an older copy only after that download checks out. Run it again later to move to the newer release. Stop any server you already have running before you replace the binary, and back up pb_data first. Installing a new binary does not migrate an application's tables.

If ~/.local/bin is not on your PATH, add this to your shell configuration and open a new terminal:

export PATH="$HOME/.local/bin:$PATH"

Then:

pocketcontext --version

You should see the PocketContext version, the embedded PocketBase version, and a source commit. A version line means the program is installed. It does not mean an application is running.

If you want to read the installer first

The website script always installs the latest published release. To pin your eyes on one version, download that version's install.sh and checksums.txt from GitHub Releases, read the script, then run it. The v0.9.1 example in the server README is:

curl -fL -o install.sh https://github.com/pocketcontext/pocketcontext/releases/download/v0.9.1/install.sh
# Read install.sh, then:
sh install.sh

To remove the program, delete ~/.local/bin/pocketcontext. Application data stays where you put it.

2. Build from source

Use this when an application README tells you to build the commit in POCKETCONTEXT_VERSION, or when you are changing the server.

You need Go 1.27 or later and a C compiler. The SQL reader uses SQLite through CGO. Build with the math, percentile, and full-text tags. A plain go test without those tags fails because SQLite is missing features the server expects.

git clone https://github.com/pocketcontext/pocketcontext.git
cd pocketcontext
git checkout THE_COMMIT_THE_APP_PINS
make build

make build writes bin/pocketcontext. Call that binary by its path when you serve an app. A source build reports dev as its version until it is a release build. If your existing server checkout has other work in it, use a second checkout or a Git worktree for the pinned commit. Do not point an application at whatever commit happens to be checked out.

3. Run one application on that computer

Put the server checkout and the application checkout side by side. DealContext is the example the server README uses. The same shape fits the other apps: WikiContext, TaskContext, NotifyContext, and the rest.

somewhere/
├── pocketcontext/
└── dealcontext/

From the application directory, with the pinned binary:

../pocketcontext/bin/pocketcontext serve \
  --dir ./pb_data \
  --http 127.0.0.1:8090

Always pass --dir. PocketBase's default data location depends on how the program was started, and an absolute path to the binary can place data beside the binary. Migrations and hooks are read from ./pb_migrations and ./pb_hooks when you start in the application directory. Use --migrationsDir, --hooksDir, and --contextConfig when those files are somewhere else.

The first start applies migrations. Nobody is seeded. You create the first operator yourself.

sequenceDiagram
  participant Admin
  participant Server as pocketcontext serve
  participant Disk as pb_data

  Admin->>Server: serve on 127.0.0.1:8090
  Server->>Disk: apply migrations
  Admin->>Server: open /_/ and create a superuser
  Admin->>Server: create an ordinary account

Create the operator with the server's superuser upsert command, using the same --dir and migration paths. Sign in at POST /api/collections/_superusers/auth-with-password, or use the dashboard at http://127.0.0.1:8090/_/. Then create an ordinary account for daily work. The collection name depends on the app. DealContext and PeopleContext use agents. Most of the others use PocketBase's default users collection. The app README is the list that matters.

Use the ordinary account for the assistant. Leave the superuser for maintenance. Superuser tokens are not a shortcut through the SQL door.

The server README's rule for the port is: keep the database on local disk, and bind to localhost unless you have configured network access and TLS. A laptop server for yourself should stay on 127.0.0.1.

Google login is optional and per application. Each app wants its own Google Web client, the matching client id and secret in that app's environment variables, and the Workspace domain when you want first sign-in to create an account. The callback the command-line tools use is http://127.0.0.1:8765/callback. The browser callback is https://YOUR-APP-ORIGIN/api/oauth2-redirect. Both id and secret are set together. One without the other stops startup on the apps that check this.

Restart the server after you change pocketcontext.json, hidden fields, or collection definitions. SQL learns the allowed columns at startup.

Several apps on one computer

Give each app its own data directory and its own port. Two apps cannot share pb_data. LinkContext and NetworkContext both document port 8095 for a local run, so start only one of them on that port, or change the port for the second.

flowchart TD
  crm["CRM on 127.0.0.1:8090"]
  wiki["Wiki on 127.0.0.1:8091"]
  crmdb["crm pb_data"]
  wikidb["wiki pb_data"]

  crm --> crmdb
  wiki --> wikidb

4. A cloud machine, through PocketDeploy

PocketDeploy is how this project creates a server on a cloud account and puts an application on it. You run PocketDeploy from your own computer. It talks to the cloud, then to the new machine over SSH.

It can use Oracle Cloud, DigitalOcean, Google Cloud, or Hetzner. It creates one Ubuntu 24.04 machine with a public IPv4 address, plus the firewall rules it owns. On that machine it installs Docker and ONCE. ONCE is Basecamp's app runner, pinned here at v0.3.3. The application arrives as a container image. That image already contains the PocketContext server build the app was published with. You do not copy ~/.local/bin/pocketcontext onto the cloud machine yourself.

sequenceDiagram
  participant Admin
  participant PD as PocketDeploy on your computer
  participant Cloud as Cloud account
  participant VPS as New Ubuntu machine
  participant Vault as VaultContext

  Admin->>PD: plan, then converge
  PD->>Cloud: create the machine and firewall
  PD->>VPS: install ONCE and the app container
  Admin->>PD: vault-save
  PD->>Vault: store the deployment diary

Google Cloud and DigitalOcean have passed disposable checks in the PocketDeploy notes, including HTTPS, updates, reboot, and a mail connection. Hetzner has passed the first machine creation. Application checks on Hetzner were still pending when that README was written. Read pocketdeploy/docs/verification.md before you treat a provider as finished.

What you prepare

PocketDeploy wants Nix and devenv on the computer you operate from, then:

devenv shell
uv sync --locked --extra test
pocketdeploy --help

The devenv shell provides Python 3.12, uv, the Oracle and Google Cloud command-line tools, OpenSSH, Git, the GitHub CLI, curl, jq, and SQLite. Hetzner's hcloud command is separate. You install it yourself and put it on PATH.

For a new deployment, copy an example colors.yml into a repository of its own. Use examples/colors.yml for Oracle Cloud, or examples/colors-digitalocean.yml, examples/colors-gcp.yml, or examples/colors-hcloud.yml for the others. The colors.yml already in the PocketDeploy checkout belongs to a test deployment that was deleted on 10 October 2026. Do not reuse that identity.

Set provider-compute to oci, digitalocean, gcp, or hcloud. The networks, cloud projects, and routing that already exist stay yours. PocketDeploy does not adopt a stranger's production stack by guessing.

There is also a portable launcher. From the skill install:

npx skills add pocketcontext/pocketdeploy --skill pocketdeploy --agent codex --yes

Copy that skill's pocketdeploy program into the deployment repository and keep it next to colors.yml. Commands read colors.yml in the current directory only. Private values go in .envrc.private, which is not committed. The local diary is .colors.sqlite. SSH keys stay in .ssh/. Those three stay out of Git.

The commands, in order

pocketdeploy init
pocketdeploy vault-save
pocketdeploy converge
pocketdeploy vault-save

init creates local identity and keys. converge makes the cloud match the file. plan shows what would change, and it is worth running before converge on anything you already care about. vault-save stores an encrypted copy of the diary, the private bindings, and the SSH authority in VaultContext. You need a VaultContext login and an unlocked session for that. The checkpoint can rebuild the diary. It does not contain the application's database or uploaded files. Those need their own backup.

One operator at a time. The lock is on the computer running PocketDeploy. It does not coordinate two people on two computers.

Switching provider-compute later does not move the machine. You create a new deployment, restore application data by the app's own backup steps, and cut DNS over.

flowchart LR
  yml[colors.yml]
  diary[(.colors.sqlite)]
  machine[Cloud machine]
  appdb[(Application database)]
  vault[VaultContext checkpoint]

  yml --> machine
  diary --> vault
  appdb -.-> backup[Separate backup]

The dotted line is on purpose. Restoring the checkpoint does not restore appdb.

What you give an end user

When the app answers on its address, hand the person three things:

  1. The https:// origin, or http://127.0.0.1:PORT if it is only on their machine.
  2. The email address their account should use.
  3. A pointer to the end-user guide.

They do not need the superuser password. They do not need a copy of pb_data.