# Oasis PUB Deployment Guide

This guide walks you through deploying an **Oasis PUB** on a VPS using the Oasis launcher (`sh oasis.sh server`). A PUB needs a static, publicly-reachable IP address and an open TCP port (default `8008`).

---

## 1) Prepare the server

Install the basics:

```
sudo apt-get update
sudo apt-get install -y git curl build-essential
```

Install Node.js (Oasis is tested on Node 22; older LTS versions also work for server-only mode):

```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install 22
nvm use 22
nvm alias default 22
```

## 2) Clone Oasis

```
cd ~
git clone https://code.03c8.net/krakenslab/oasis oasis
cd oasis
```

## 3) Install dependencies

The `install.sh` script installs Node deps and applies the bundled patches. **You can skip the AI model download** — a PUB does not need it.

```
bash install.sh
```

If the AI model download fails or you skipped it, that's fine. The PUB will run without it.

## 4) Configure the PUB

Two example config files live in `docs/PUB/`:

- [`server-config.json.example`](./server-config.json.example) — the Oasis Sbot config (cap, friends graph, gossip, incoming/outgoing ports). Goes into `src/configs/server-config.json`.
- [`oasis-config.json.example`](./oasis-config.json.example) — the GUI/module config tuned for a PUB (AI/wallet/market/jobs/shops off; LAN broadcasting off). Goes into `src/configs/oasis-config.json` if you ever run the GUI on the same host.

Copy them:

```sh
cp docs/PUB/server-config.json.example src/configs/server-config.json
cp docs/PUB/oasis-config.json.example src/configs/oasis-config.json   # only if you run the GUI here
```

The reference `server-config.json`:

```json
{
  "logging": { "level": "notice" },
  "caps": { "shs": "H5EC+V5BU9s0lWxCkt4z8a095Sj8a6TgiLKPYi1JD7s=" },
  "pub": true,
  "local": false,
  "friends": { "dunbar": 300, "hops": 3 },
  "gossip": {
    "connections": 50,
    "local": false,
    "friends": true,
    "seed": true,
    "global": true
  },
  "replicationScheduler": {
    "autostart": true,
    "partialReplication": null
  },
  "autofollow": {
    "enabled": true,
    "feeds": [
      "@0qSCyK3xyL71X4qKkmf84Cb2riP6OeUqxCvbP2Z6HWs=.ed25519"
    ]
  },
  "connections": {
    "seeds": [],
    "incoming": {
      "net": [
        {
          "scope": ["device", "local", "public"],
          "transform": "shs",
          "port": 8008,
          "external": "pub.example.com"
        }
      ],
      "unix": [
        {
          "scope": ["device", "local", "private"],
          "transform": "noauth"
        }
      ]
    },
    "outgoing": {
      "net": [{ "transform": "shs" }],
      "tunnel": [],
      "onion": [],
      "ws": []
    }
  }
}
```

**Three values to know:**

- **`connections.incoming.net[].external`** — the externally-reachable hostname of this PUB (e.g. `pub.example.com`). This is what gets embedded into invite codes generated by `sh oasis.sh invite` and into pub announce messages for the `public` scope. If it's missing, multiserver falls back to the first non-loopback IPv4 address it finds, which means invites will hand out the raw VPS IP instead of your domain. Set it on the public listener before you generate any invites. Note: this is a per-listener field — the top-level `host` does **not** affect invite codes.

- **`caps.shs`** — the network-level secret handshake cap. The Oasis network uses `H5EC+V5BU9s0lWxCkt4z8a095Sj8a6TgiLKPYi1JD7s=` (set in the example above). All PUBs and clients on this network must hold the **same** value — nodes with a different cap silently can't connect. If you're bootstrapping a separate isolated network instead, generate your own with:

  ```sh
  node scripts/generate_shs.js
  ```

- **`autofollow.feeds`** — the upstream PUB(s) this node will automatically follow on first boot. The example seeds from `solarnethub.com`'s PUB (`@0qSCyK3xyL71X4qKkmf84Cb2riP6OeUqxCvbP2Z6HWs=.ed25519`), the default seed of the Oasis network. Once your PUB connects to it, gossip propagates the rest of the network's pub list. Replace this id only if you're bootstrapping from a different network root.

Everything else is the standard PUB shape: `pub: true`, no LAN discovery, dunbar 300, three friend hops, replication scheduler running on autostart, port `8008` open for SHS on every scope (device/local/public), and a `noauth` unix socket for the CLI.

## 5) Launch the PUB (server-only)

In server-only mode Oasis runs **only the Oasis Sbot**, not the web GUI or AI service. `aiMod` is forced off automatically when launched this way.

The repo ships a ready-to-use systemd unit at `docs/PUB/oasis-pub.service`. Copy it, edit the `YOUR_USER` placeholder, then enable it:

```
sudo cp ~/oasis/docs/PUB/oasis-pub.service /etc/systemd/system/oasis-pub.service
sudo nano /etc/systemd/system/oasis-pub.service     # replace YOUR_USER
sudo systemctl daemon-reload
sudo systemctl enable --now oasis-pub
sudo journalctl -u oasis-pub -f
```

Data is written to `~/.ssb/`.

## 6) PUB admin: `sh oasis.sh <command>`

All admin actions go through the launcher itself, which talks to the running Oasis Sbot via the local unix socket (`~/.ssb/socket`). No external CLI install is needed — just keep the systemd unit `oasis-pub` active.

```
sh oasis.sh whoami                  # print this PUB id
sh oasis.sh invite [N]              # create invite code (N = uses, default 1)
sh oasis.sh name "<text>"           # set PUB display name
sh oasis.sh announce <host> [port]  # publish pub address (default port 8008)
sh oasis.sh follow <feedId>         # follow another PUB / feed
sh oasis.sh status                  # peer / replication overview
sh oasis.sh gossip                  # known gossip peers
```

## 7) Get your PUB ID

```
sh oasis.sh whoami
```

Example response:

```
{ "id": "@mGrevRCSX4E5dLgmflWBc50Qkn/1RXUAtDaGHOJ8xB4=.ed25519" }
```

## 8) Set the PUB profile name

```
sh oasis.sh name "My PUB Name"
```

## 9) Create invite codes

```
sh oasis.sh invite        # uses=1 (default)
sh oasis.sh invite 500    # uses=500 (open PUB)
```

The output is a single-use (or N-use) invite code you can hand out. Clients redeem it in their `/invites` page.

## 10) Announce the PUB

So peers can discover the PUB by hostname:

```
sh oasis.sh announce mypub.example.com
sh oasis.sh announce mypub.example.com 8008
```

## 11) Follow another PUB (federation)

Federate so both replicate each other:

```
sh oasis.sh follow "@mGrevRCSX4E5dLgmflWBc50Qkn/1RXUAtDaGHOJ8xB4=.ed25519"
```

## 12) Health checks

```
sh oasis.sh status                # peer / replication overview
sh oasis.sh gossip                # known gossip peers with state
ls -la ~/.ssb/                    # confirm flume/, blobs/, gossip.json, conn.json exist
sudo journalctl -u oasis-pub -f   # tail service logs
```

## 13) Disabling the AI module (only relevant if also running the GUI)

`sh oasis.sh server` does **not** load the GUI or AI service, so `oasis-config.json` is ignored in server-only mode. Only `server-config.json` matters.

If you also run the GUI on the same VPS (`sh oasis.sh` without `server`), set `aiMod` to `off` in `src/configs/oasis-config.json` to skip the AI model:

```
sed -i 's/"aiMod": *"on"/"aiMod": "off"/' src/configs/oasis-config.json
```

## 14) Joining the Oasis network

The default seed PUB at `solarnethub.com` is included in `autofollow.feeds` above. As soon as your PUB connects to it (or to any peer that knows about it), gossip propagates the rest of the network's pub list.
