Servers

A server is a managed Linux machine where MultiAgent deploys agents and tools. Everything is managed over SSH: MultiAgent runs commands, transfers files and reads container statuses, requiring nothing on the server beyond the base system.

Adding a Server

The “Add Server” button opens the form: name, host, SSH port, user, and authentication — a password or a PEM private key. The same form sets the deployment slug — a short name (default agents) that separates this deployment from other MultiAgents on the same machine: the docker network name, the container name prefix and the folder roots are all built from it. Two servers on one machine cannot share a slug. For connections through a bastion host there is a proxy jump: a separate host, port, user and credentials for the hop.

When MultiAgent runs on Windows, the form also shows the “Local WSL” mode: instead of a remote host you pick a WSL distribution on this very computer. No password and no key are needed — MultiAgent works with the distribution from its own service, and the links point at localhost (or at the machine’s network name, when the apps should open from other computers). In Docker deployments this mode is not shown — there, only SSH is available.

After saving, the connection status is available: not checked, OK, or an error. The “Check connection” button tests exactly one thing — SSH reachability: whether a session on the server can be opened. Whether the server is ready for deployments is shown by the checks checklist: it names everything that is missing and offers a fix.

The Server Card

At the top of the page sits the server card with its name, address and connection-state badge. To the left of the badge are live load figures: CPU load, memory used and disk space occupied by all this server’s containers. The numbers refresh by themselves every five seconds, and hovering over the occupied space shows how much data the containers have read and written. While the first measurement is in progress a loading badge stands in place of the numbers; if a poll fails, the last known numbers stay — they do not disappear.

The same card holds a row of actions. “Check and fix” opens the readiness checklist (below), “Management” is shown when a MultiAgent of its own runs on the server and opens it without a password. “Copy login”, “Copy password” and “Login link” are visible only when central login is installed — they are the same credentials for signing into the server. The “Files” button opens access to the server’s folders, and deleting the server sits at the far right of the row.

“Login link” puts a one-time link on the clipboard that takes a person to the server panel without a password. Every click issues a new link, while earlier ones keep working until they expire — you can hand the link to several people safely. If the home page is not installed yet, the button says honestly that it must be installed on the “Home page” tab first; if central login is not installed or protection is off, it reminds you that the link needs central login behind working HTTPS.

There is no separate card with a list of agents on the page any more — a needless copy of what the navigation tree already shows. Rows are created from the server row’s menu, and “Import agents” has moved to the actions row of the “Status” tab — right next to “Add key”.

The Server Row Menu

A right-click on the server row in the navigation tree (or the three-dot button) opens the actions menu. Besides “Open” and “Add agent”, there is “Deploy” — it raises all the server’s rows that have no container yet in one go: first the agents, then the applications, one by one. The item is visible only while such rows exist, and it runs the work through the task queue: its log opens in the “Tasks” section, where the work can also be stopped (a row that has already begun deploying runs to completion). Next to it are “Recreate smoothly” and “Recreate forcibly” for all deployed rows; a forced recreation removes the unneeded Docker images itself at the end — in the same log, no separate “Docker cleanup” click needed.

The Connection to the Server

MultiAgent keeps one persistent connection to the server and reuses it for everything: commands, file transfers, state polls. That is why pages open faster and agent state is refreshed with a single request per server instead of one per agent. There is nothing to configure here — it always works this way: the connection re-establishes itself after a break and switches to new credentials if you have changed them.

Onboarding Checks

The “Server checks” card on the server page opens a checklist: every check is its own row with a green check mark (done), a yellow warning, a red cross (error) or a gray “skipped” mark, and at the bottom a summary — “All checks passed” or “{n} of {m} checks need attention”.

Checklist rows are named after the service’s role, not the product name:

  • SSH connection — whether the connection is reachable;
  • Docker — installed and running, and whether daemon.json is correct;
  • Host folders — the folders for agents, data, home files, projects, tools and temporary files;
  • Agent user (agent, 999:999) — whether the account exists with the right uid/gid;
  • Nginx — the web server for routing;
  • SSL certificate — issued and not expiring (when a secure connection is terminated by an upstream proxy, the check will offer to set the server’s public address);
  • Home page — the app card board at the server’s root (checked after Nginx and skipped when there is no Nginx);
  • Central login (Authelia) — the mandatory single sign-on service;
  • Database (Postgres) — the shared Postgres instance for agents: installed and running;
  • Git service (Forgejo) — the built-in Git server;
  • Backup service (rsyncd) — the backup container.

When a check shows a “Click here to install it” link (or “create” / “request”) — that is a one-click fix: it starts the same one-step install as the matching tab (Docker, folders, agent user, Nginx, a Let’s Encrypt certificate, Postgres, Forgejo, backups, home page, central login). After a successful fix the checks re-run automatically and the row turns green. A check whose prerequisites are missing (for example, no Docker or Nginx) is marked “skipped” — it does not count and offers no fix link. The central login button never touches the certificate or the HTTPS port — only the service itself.

Some rows wait for your input or a simple action. The “SSL certificate” row with no certificates will offer to set the server’s public address of the form https://your-domain/{slug} when a secure connection is terminated by an upstream proxy — or to request a Let’s Encrypt certificate. A Postgres instance that is installed but stopped is fixed with a start button, not a reinstall: the data is not touched.

What MultiAgent can check and fix:

  • SSL certificate — no certificate → a warning with a link offering two paths: set the server’s public address when TLS is terminated by the upstream proxy, or request a Let’s Encrypt certificate (when the host looks like a domain; otherwise it advises making a self-signed one); expiring within 30 days or expired → a warning with no action — enough to renew on the Nginx tab; while no HTTPS port is set, certificates are saved but not served;
  • Central login — a mandatory service: not installed → a warning with an install link; installed but not running → a warning and a redeploy;
  • Forgejo — an external instance (an address not of our shape) is checked by credentials and offers no install; for the built-in install the address is shown automatically — the public subfolder /forgejo/; an empty card is filled in automatically (login agents, auto-creation of repositories, a generated password); the “Company” field sets the organization where agent repositories are created and from which they are visible;
  • Backup service — the check passes only when the container is running and serves all seven modules.
  • Postgres — an installed but stopped instance is a warning with a start button (not “not installed”); after starting, the check itself makes sure the saved credentials work.

Installing Docker

If Docker is missing on the server, MultiAgent installs it itself — one button, with the commands streaming into the interface. In the same place you can edit /etc/docker/daemon.json (registry mirrors or logging, for example) — MultiAgent applies the file and restarts the daemon.

For images from a private registry, the server has a Registry Auth setting: the registry user and token MultiAgent uses when pulling agent and tool images.

Server Folders

MultiAgent keeps agent files in several server folders — all configurable, with these defaults:

  • Agents folder — /root/agents/docker: one subfolder per agent with its compose.yml;
  • Data folder — /root/agents/data: agent data, one subfolder each, mounted into the container at /data;
  • Home folder — /root/agents/home: the agent’s home directory inside the container, /home/agent;
  • Projects folder — /root/agents/projects: the agents’ git repositories, mounted at /project;
  • Tools folder — /root/agents/tools: files of services deployed from the tools library;
  • Temp folder — /root/agents/tmp: the agent’s scratch folder inside the container (/tmp/agent) — temporary model files and anything recreatable land here; it is deliberately excluded from backups.

All the defaults are built from the deployment slug: {slug} is replaced with the slug itself, agents by default. The slug is set when adding the server and can be changed on the “General” tab; it also names the shared docker network and prefixes container names. Changing the slug affects only new deployments: running containers keep their old names, and nothing moves on disk.

The single folder structure simplifies backups: all data of all agents on the server lives in one directory tree. Servers you created earlier keep their old paths — MultiAgent moves nothing on the host.

Ports: private by default

A new agent, app or tool comes up with a private port: it does not answer from the outside and is reachable only through that server’s nginx — via its subfolder — and from the machine itself. That is how deployments on one computer stay invisible to each other: even when several MultiAgent servers live on one host, one’s ports are open neither to the others nor to the internet.

To open a port to the world, flip its “Public port” switch — the Ports tab of an agent or an app, the port row of a tool. Two ports are always public and have no switch: nginx’s own HTTP/HTTPS — the front door to all the server’s apps — and the backup service port, through which other machines pull backups from the server. The shared Postgres, on the contrary, is always closed.

A link to an app with a private port points at its address through nginx, not at the direct http://{host}:{port}: the browser could not reach the direct one anyway. MultiAgent itself manages such apps over its own secure channel to the server, so closed ports never get in the way of chats or checks.

Shared Server Environment Variables

When the same environment variable must be set for every deployment on a server (a time zone or log verbosity, for example), you set it once in the server’s settings — it lands in the configuration of every agent and app on that server. A value set on a specific agent always wins over the shared one: that is how you make an exception for a single deployment. Details on the Agents page.

Shared Postgres

Instead of a separate SQLite database per agent, you can run one shared Postgres on the server: MultiAgent deploys the docker-compose container (port 5432 by default), saves the password and checks the connection. For agents with Postgres enabled, the AGENT_DATABASE connection string is injected into their environment automatically.

The Forgejo Git Server

MultiAgent deploys Forgejo on the server — your own Git server (internal port 3200). It is reachable at the /forgejo/ subfolder on the server’s domain, and MultiAgent shows the address by itself — no need to type it in. For every agent you can link an existing repository or create a new one; MultiAgent issues and stores the SSH keys for access. If you set an organization in the “Company” field, all new agent repositories are created inside it (created automatically when missing), and repository lists show its contents. Details in the Agents section.

Backups

Onboarding installs an rsyncd container on the server with seven read-only modules covering all server folders: docker, home, data, projects, tools, plus two dump modules — postgres and forgejo. The tools module takes what no other module serves: nginx certificates, central-login state and tool compose files; its own postgres/backup and forgejo/backup subfolders are excluded from the upload — those dumps are served by their own modules, so a full download does not copy them twice. Postgres and Forgejo dumps are produced on the server itself (third-party containers drop them into the backup folders). Backups are pulled from the server by your client machines over rsync — for example, a nightly job on the machine with the backup storage:

rsync -avz rsync://backup@server-host:873/data/ /backups/server-host/data/

Ready-to-run commands for downloading all seven modules (Linux and Windows) are collected in the Backup tab of the server page — run them as they are. The server can only pass the backup check when the container is running and serving all seven modules; if one is missing, the check points at a reinstall.

Nginx Routing and Certificates

MultiAgent itself never routes requests: every server runs its own Nginx container (named {slug}-nginx, agents-nginx by default), installed and updated from the Nginx tab of the server page. It is the Debian build of nginx (nginx:1.31), not Alpine: it runs on old kernels where the Alpine build fails to start. The routing configuration is a projection of the database: it is rebuilt and applied automatically on every change (create an agent, product or tool — it immediately gets its own subfolder). Applying happens without dropping connections: the configuration is validated and reloaded inside the already running web server, so open pages and live chats do not break.

  • Five kinds of routes — agents and products (read-only), tools with a web interface (read-only), extra links of agents and products (read-only: a subfolder with a port from the “Links” tab), custom routes to any http(s) address (the only manually managed kind: edit, disable, delete) and, when the central login is installed, its derived auth route (read-only, with no protection toggle);
  • One namespace — a first-level slug of [a-z0-9-]+ per server for all kinds; MultiAgent’s system paths (api, agents, servers, data and others) are reserved;
  • Internal container network — apps are addressed by container names on the shared docker network; a crashed service returns 502 only on its own subfolder, the other routes keep working.

Certificates — three kinds from the same tab: self-signed (becomes the fallback certificate), your own PEM pair, and Let’s Encrypt (ACME through Nginx itself, staging and production CAs, one request at a time). Certificates and keys are stored only on the server — the database keeps just metadata. Expiry is tracked on every configuration update (renewal 30 days before expiration). The HTTPS port is optional: while it is empty, certificates are saved but not served and only HTTP is published. A Let’s Encrypt request with an empty port enables it by itself (443), so the issued certificate is served immediately; a port you have chosen, or an explicitly disabled HTTPS, is never overridden. In local secure mode all HTTP (including route subfolders) is automatically redirected to HTTPS, except the ACME validation path; when the server sits behind an upstream reverse proxy that terminates TLS, the HTTP listener keeps serving routes as usual. Immediately to the right of the Nginx tab sits the Authorization tab — the central login install (see below).

Server Home Page

At the server’s root you can publish a home page — a card board from which every app on the server opens. It is a static board: MultiAgent builds the file itself and uploads it to the server, and nginx serves it at the root. No separate container is needed — the installed Nginx is enough; the page has no login of its own, and when the central login is on, it closes together with the other apps.

MultiAgent maintains the cards from its database: one card per agent, product and tool with its address — with the projects’ real logos, and agent and app cards show badges of their extra links in the corner (the “Links” tab). Common actions are not cards but a row of icon buttons in the top-right corner: “Git” (while Forgejo runs on the server), “QR login” (when central login is on) and always “Logout” on the far right; “Logout” ends the central-login session, signs out of all agents and products (their tokens are deleted) and of the page itself. The corner buttons do not count as applications and are not part of the card count. QR login and the logout page are described further down. The board refreshes itself on every change — deploy an agent or a tool and its card appears; the tab offers a manual apply too. The page’s label language is chosen in the tab: English or Russian, defaulting to the language of MultiAgent itself.

Details on the Server Home Page page.

Central Login (the “Authorization” Tab)

So that a visitor signs in once and gets access to any protected app on the server, you can install the central login on the server — it is the “Authorization” tab (Authelia), sitting right of the Nginx tab. The login is a service container {slug}-auth (agents-auth by default) with the fixed slug auth and portal address /auth/; it publishes no port of its own, so Nginx is installed first. The login is agents, the password is generated automatically and visible in the tab; the install never touches the certificate or the HTTPS port.

When the central login is active, agents and products are locked “behind the central login” by default, and tools with a web interface and custom routes — at your choice (a toggle). One login on the login page opens every protected app on the server — no repeated sign-ins.

The protection works only over a secure connection (HTTPS): either a local certificate and HTTPS port from the Nginx tab, or the server’s public address (or an address template of the form https://{serverHost}/{slug}) when TLS is terminated by the upstream reverse proxy (then no certificate of your own is needed). Otherwise the installed login stays inactive. Reaching an app directly at host:port (when the port is open), bypassing nginx, is not locked — the app keeps its own login. Service machine paths /{slug}/api/… and /{slug}/svelteChatHub also stay open (they have their own JWT or API-key authorization). Apps receive identity headers and the X-SSO-Token secret (checked against SSO_PROXY_TOKEN in the agent’s environment), so they cannot be forged from outside.

The “Apply configuration” button on that tab does more than apply the settings — it also ends every open session: each browser has to sign in again with the current password. A protected app’s manifest file (manifest.json) stays available without a login — the browser requests it separately from the page, and without that the page would show an error.

The auth slug is reserved on every server — you cannot create an agent, tool or route with that name. Forgejo connects to the central login by itself, as soon as the login is installed, protection is working and Forgejo is running: its login page gets a sign-in-through-central-login button, and the first such sign-in creates the account from the central-login identity. The Forgejo administrator’s login and password follow the central login — the Forgejo tab has a “Sync authorization” button for that. When the conditions go away, the button disappears by itself. Deleting the central login reopens the protected routes, and its data and secrets are kept — a reinstall reuses them. More about routes and protection in the Nginx Routing section.

The Agents URL Template

Where the public links to a server’s apps point is decided in order. First — the “Public address” field on the General tab: when it is filled, all links are built from it, and the server’s real address (the Connection tab) stays internal — it is what MultiAgent uses for SSH and tunnels. This is the case when the public domain and the machine itself are different things: say, the server sits in a closed network and an external reverse proxy opens it to the world.

When the public address is empty, the public base becomes the base of the agents’ address template of the form {base}/{slug} — as before. When the template is not set either, links are built from the server’s address: http(s)://{host}[:{nginx port}]/{slug}/. Why keep a separate field, then? The template with the {slug}, {host} and {port} placeholders primarily tells MultiAgent how it itself reaches the APIs of that server’s agents. If you put the public domain into the template, management traffic takes the same path — out through the external proxy and back; the separate field keeps the two jobs apart. Direct access at http(s)://{host}[:{port}] remains the fallback path. Changing the public address, the template or the server name rebuilds the nginx routes at once and syncs the central-login configuration with the new address.

https://apps.example.com/{slug}

Files

Every server has built-in access to files (the “Files” item in the sidebar): browse the directory tree, read and edit files, upload and download, rename in place, and count size and tokens of text files. It lets you fix a config or look at logs on the server without leaving MultiAgent.

The separate “Files” page shows two panels — each with its own server and its own folder. Tick files and folders in the left panel and press “Copy” — they move to the right panel’s folder. The panels can look at one server or at two different ones: MultiAgent itself transfers the files between servers over its own saved accesses — nothing to configure between servers. The transfer runs in the background, the progress percentage is visible right in the button, and the process can be canceled; files with the same name are replaced, folders with matching names merge. While the copy runs, the right panel refreshes itself, so arriving files appear in place.

Next to it is the “Terminal” button: it opens a command line in the folder you are currently in. Commands run on the server, output streams to the screen line by line, and command history and interrupt work as usual. Handy for a quick look at a service’s state or sorting out file permissions.

Handing a Server to a Client

When a server belongs to a client, you can hand management over: the client’s own MultiAgent is deployed on the server, and the records move to it — agents, apps, tools, routes and access keys. The handover is a one-time operation: it starts from the “Handover” tab on the server page, and a preview shows in advance what moves and what stays with you. Running apps are not touched: nothing stops or reinstalls.

After the handover, routing is managed by the client’s instance, while the server itself stays with you: SSH access, checks, folders and Docker cleanup. You can peek into the client’s instance with the “Manage” button in the page header — the sign-in happens by itself, no password needed. Details on the Server Handover page.

← Back to documentation