Skip to content

Choose a runtime and configure access

There are two separate choices when hosting Ficus: where its API and worker run, and where agents execute commands. Installing the app on a server does not automatically choose a safe agent runtime or make the browser interface publicly reachable.

Every instance needs FICUS_SANDBOX_RUNTIME. Ficus refuses to start if it is missing or invalid. The current choice applies to the instance; per-squad runtime switching is not part of this setup flow.

RuntimeAgent environmentWhat you need
hostCommands run as Ficus’s user on its own machine. There is no isolation from that user’s files or network access.Bash; a local Chromium-family browser for browser tools; tmux for local deployments.
docker-socketContainer workspaces with the host’s Docker socket available inside. Docker access can control the host.A working Docker daemon and sandbox image.
docker-sysboxContainers with user namespaces and their own Docker daemon.Linux, Docker and the Sysbox runtime.
vmA box runs as a dedicated Unix user on a registered machine. Multiple boxes can share one machine.An SSH-accessible machine fleet, bootstrap and box provisioning.
k8sSandboxes run as Kubernetes pods.A configured cluster, storage and sandbox deployment resources.

The local installer prepares host, docker-socket, docker-sysbox or local k3d. Its k3d choice writes k8s as the runtime and configures local cluster access. VM fleets and existing Kubernetes clusters are advanced deployments; selecting their environment value alone does not create the infrastructure.

Host mode is suited to trusted personal work. It does not provide container toolchains or container-log streaming. Docker-socket is useful for compatibility, but its container boundary should not be treated as protection against an agent with Docker access.

Changing the runtime is not a workspace migration tool. Before changing an established instance, finish active work and preserve files from the existing environment. Remote VM files may not live in the local data directory.

Fresh local setup uses one browser address, normally http://localhost:3000. Core serves the built web app, API and WebSockets together. Outside Kubernetes, the API and worker bind to loopback by default.

Check the actual address and runtime with:

Terminal window
ficus server status

Use the URL from setup consistently when registering and using passkeys. A different hostname is a different browser origin, even when it reaches the same computer.

For browser access from another device, use a hostname you control and an HTTPS reverse proxy. This example assumes the proxy and Ficus run on the same machine, with Core listening on port 3000.

  1. Point your hostname at the server and arrange an HTTPS certificate with your proxy.
  2. Make sure FICUS_SERVE_WEB=1 is set in the Ficus checkout’s .env (setup sets it).
  3. Proxy the whole hostname to http://127.0.0.1:3000. Forward ordinary HTTP requests and WebSocket upgrades for both /ws and /ws/*, including terminal connections, and for /api/app/*, where squad local apps open their own WebSockets (for example, dev-server hot reload).
  4. Sign in at the server’s current address as an administrator, open Settings → Administration → Server address, and set the Public address to https://ficus.example.com. Review the confirmation, which lists the passkey, Ficus account and integration callback changes, and save. It takes effect immediately; no restart is needed.
  5. Open the HTTPS address and test login, live task updates and a terminal session.

If you manage configuration as files instead, set the address in .env and restart with ficus server restart. An environment value locks the setting, and Settings shows it as Set by the server environment:

APP_URL=https://ficus.example.com
FICUS_WEB_ORIGIN=https://ficus.example.com

With Caddy, the single-origin proxy portion is:

ficus.example.com {
reverse_proxy 127.0.0.1:3000
}

FICUS_WEB_ORIGIN must be a bare origin: scheme, host and optional port, without a path. Passkey registration depends on it. APP_URL controls user-facing links; FICUS_API_URL serves other API-client/runtime connections and does not need to be changed to the public hostname for this same-machine proxy example.

To serve Ficus at a path such as https://ficus.example.com/ficus, set the Public address (or APP_URL) to that address, path included. The same web build serves every path, so nothing needs to be rebuilt, and the server’s local address (for example Ficus Desktop’s http://localhost:<port>/) keeps working at the root at the same time. Links, phone pairing, integration OAuth callbacks and webhook URLs use the path. This documentation is served under the path too, at https://ficus.example.com/ficus/docs/, with working links and search.

Your reverse proxy can either remove the prefix before forwarding or forward it unchanged; Ficus accepts both. With Caddy:

# Prefix removed: Ficus sees /squads/1 and recognizes the address from the Host header.
ficus.example.com {
handle_path /ficus/* {
reverse_proxy 127.0.0.1:3000
}
}
# Or prefix forwarded unchanged: Ficus sees /ficus/squads/1 and removes it itself.
ficus.example.com {
handle /ficus/* {
reverse_proxy 127.0.0.1:3000
}
}

When the proxy removes the prefix, it must keep the original Host header (Caddy and nginx’s proxy_set_header Host $host do) or send X-Forwarded-Host; otherwise Ficus cannot tell the request came through the prefixed address. A proxy that forwards the prefix needs neither.

With a prefix configured, /ficus/… reaches every Ficus route exactly as the unprefixed path does, on every listener. Any proxy path rule (blocks, authentication, rate limits, IP allow-lists) must cover both forms, or forward only the prefixed form to Ficus.

When you move an existing server to a new path:

  • Open tabs and installed home-screen apps at the old path must be reopened or re-added from the new address.
  • Squad apps that Ficus runs restart automatically so their links use the new path. Apps you started yourself and attached must be restarted by hand.
  • A path that is also a Ficus page or API path (such as /settings or /api) works only behind a proxy that removes the prefix. Settings warns about this.

APP_BASE_PATH is no longer needed when the public address carries the path. Servers that set it keep working: it still sets the build-time path of the web app and is the path for origins listed in FICUS_WEB_ORIGIN.

Ficus uses one public address for links, sign-in, integration OAuth callbacks, webhooks and the Ficus app. It is resolved in this order:

SourceLocks the settingNotes
APP_URL environment variableYesShown as Set by the server environment. Remove it to manage the address in Settings.
PUBLIC_URL environment variableYesOlder name, used only when APP_URL is unset.
Public address in Settings → Administration → Server address—Changed by administrators; takes effect without a restart. Every change is recorded with who made it.
FICUS_LOCAL_APP_URL environment variableNoThe local address a launcher (Ficus Desktop, ficus setup) provides. It is used only when nothing above is set, and stays allowed for sign-in after a public address is set.

On the first start after upgrading, a non-local APP_URL or PUBLIC_URL is also copied into the setting once, so the server keeps its address if you later remove the variable. Ficus Cloud servers are always managed by Ficus Cloud.

Ficus checks the address format only (scheme, host, optional port and path; no credentials, query or fragment). It does not check that the address reaches the server.

After a change:

  • Passkeys don’t carry over to a new hostname. Existing passkeys keep working at the local address (FICUS_LOCAL_APP_URL, for example Ficus Desktop’s http://localhost:<port>) and at the hostname they were made on while it stays allowed; you can keep signing in and pairing phones from there.

  • To use a passkey at the new address, add one from an address where your passkeys still work (the address you used to make the change, or the local address):

    1. Open Settings → Account → Passkeys and choose Add a passkey for another address.
    2. Confirm with one of your passkeys. Ficus shows a one-time link and a code, valid for 15 minutes.
    3. Open the link at the new address, or go to https://<new address>/add-passkey and type the code, then create the passkey. You’re signed in there.

    This adds a passkey. Your other passkeys and sessions stay as they are. Each person adds their own. A code works once, only for the account that created it, and creating another code cancels the previous one.

  • Lost your passkey? on the sign-in page is a last resort. It needs email delivery from the server, and it replaces all of your existing passkeys and signs out every session. Without email it sends nothing.

  • If the address you were using stops being allowed and you can’t sign in, set APP_URL in the server environment and restart Ficus; the environment value overrides the setting.

  • Ficus account (Mobile & Pro): connect the account again. Pending approvals for the old address are cancelled. Devices and Instance Pro slots stay with the old address in your Ficus account and do not move.

  • Integrations: update OAuth redirect URLs and GitHub or Linear webhook URLs with your providers. The confirmation lists the old and new values.

  • Links that were already sent keep the old address. Agents and sandboxes see the new address on their next command or session.

  • If the address has a path (for example /ficus), the web app is served under it without a rebuild. See Serve Ficus under a path prefix.

The worker and internal event ports are not browser endpoints. Keep them on the private side of the deployment. If your proxy runs in another container or machine, configure a reachable private API bind address and firewall rules for that topology; 127.0.0.1 in the proxy then refers to the proxy itself.

  • The app loads but task updates or terminals disconnect: check WebSocket forwarding, including the bare /ws route.
  • Passkey registration fails: check the exact HTTPS origin, the Public address (or APP_URL/FICUS_WEB_ORIGIN), and whether you switched hostnames after registration.
  • An API responds but the page is missing: ensure the web build exists and FICUS_SERVE_WEB is enabled.
  • A host-mode agent cannot browse: install a supported browser or configure FICUS_BROWSER_EXECUTABLE_PATH.

Use the configuration reference for the relevant settings and troubleshooting for diagnostic steps.