> ## Documentation Index
> Fetch the complete documentation index at: https://docs.panofx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Run on a server

> Run the app where there is no screen, and set it up from a browser anywhere.

On a server or a container host such as Railway there is no screen for the app's interface. Pair a browser
with the node instead. The node and your browser talk end-to-end encrypted through the Panofx relay, which
passes the traffic along but cannot read it. The protocol and threat model are under
[Remote console](/protocol/remote-console).

<Steps>
  <Step title="Start the app on the server">
    <Tabs>
      <Tab title="Docker or Railway">
        Run the `ghcr.io/panoflow/panofx-node` image with `PANOFX_MODE=app`, and attach a volume at `/data`.
        Settings, the wallet and paired browsers live there. Without a volume a restart would lose them, so the
        app refuses to create a wallet.

        On Railway, add the volume to the service and set `RAILWAY_RUN_UID=0` so the node can write to it. On a
        Docker host of your own, the commands are under [Install → Docker](/resolvers/install).
      </Tab>

      <Tab title="A server of your own">
        Run `panofx-node app --open=false --remote on --data-dir /var/lib/panofx` under your supervisor, as the
        user that owns that directory. [Install → Linux](/resolvers/install) has a systemd unit for it.
      </Tab>
    </Tabs>
  </Step>

  <Step title="Open the pairing link">
    While nothing is paired, the log prints the node's fingerprint and a link that works once, for 15 minutes:

    ```
    Remote console: node fingerprint abcd-efgh (node id …)
    Pair a browser with this node (the link works once, until 14:32 UTC): https://…/remote#pair=…
    ```

    Open it in your browser. **Check that the page shows the same fingerprint.** Choose **Pair this browser**.

    If you miss the 15 minutes, restart the service for a new link, or run `panofx-node remote pair` inside
    the container (`railway ssh`, `docker exec`) as the same user.

    <Tip>
      To keep the link out of your logs, set `PANOFX_REMOTE_PAIR_SECRET` to a long random value (at least 20
      characters) in your platform's secrets instead. The log then shows only the node id; enter the id and the
      secret in the console's **Pair with a server** form. The secret works only until the first browser pairs.
    </Tip>
  </Step>

  <Step title="Set a console passphrase">
    Every paired browser asks for it, so a lost or borrowed device cannot control your node on its own.
  </Step>

  <Step title="Follow the same seven steps as in the app">
    See [Set up your node in the app](/resolvers/app-setup). A wallet this browser creates shows its recovery
    phrase here, until you confirm you wrote it down. After that the phrase, the private key and the backup
    never leave the server.
  </Step>

  <Step title="Pair your phone or another browser">
    From **Advanced → Remote access**. The same panel lists every paired device with **Revoke**;
    `panofx-node remote devices` and `panofx-node remote revoke ID` do the same from a shell.
  </Step>
</Steps>

## What a paired browser cannot do

By design, a paired browser cannot:

* show the recovery phrase or private key after setup;
* download the backup;
* switch wallets or bring balances over;
* remove the console passphrase.

Large price or limit changes ask for the passphrase again and raise an alert. The app on your Mac or PC
pairs browsers the same way, from **Advanced → Remote access**.

## Pass a Solana keyfile to a container

A policy-driven container that quotes Solana takes its Solana keyfile as `PANOFX_SOLANA_KEYFILE_JSON`. The
entrypoint writes it to `$PANOFX_RUNTIME_DIR/solana-keyfile.json` (default `/tmp/panofx`), which is where
`solana_signer.keyfile` should point. This needs the 0.10.0 image or later. See
[Containers](/resolvers/runbook/containers).
