@@PRODUCT@@

Tools on a server

A machine carries its roles — web, mail, dns, db, backup, ftp — and beside them it carries tools: the things your customers need in a shell but that none of the roles installs by itself. git to deploy from a repository, Composer to resolve

Written for: Administrator

A machine carries its roles — web, mail, dns, db, backup, ftp — and beside them it carries tools: the things your customers need in a shell but that none of the roles installs by itself. git to deploy from a repository, Composer to resolve PHP dependencies, WP-CLI to drive a WordPress install, imapsync to pull somebody else's mailboxes, a Node or Python series a customer's application was written against, and Valkey for sessions and object caching.

Open it in the panel under Servers → the server → Quick actions → Manage tools, or reach the screen directly at /nodes/<server>/tools.

What a tool is

Three things, and nothing else:

  • a package on your own mirror,
  • a name in the server's tools: list in /etc/corecp/node.yaml,
  • and a render, which is corectl reconcile making the machine match the list.

That is why installing one is not a script that downloads something: the list is the truth, a machine rebuilt from its state file comes back with the same tools, and a tool taken off the list is really gone from the disk at the next reconcile.

root@web1:~# corectl tool list
Tools:
  on git              Git — clone and deploy from a repository
  on composer         Composer — PHP dependency manager
  on wp-cli           WP-CLI — manage a WordPress installation from the shell
  on valkey           Valkey — one shared instance for sessions and object caching
     imapsync         imapsync — the universal IMAP fallback for migrations
     node (22, 24)    Node.js — the two active LTS series
     python (312, 313) Python — extra series beside the distribution's
     docker           Docker — containers, single-tenant nodes only  — this node is not marked single-tenant

`on` is installed, `!` is listed in node.yaml but missing on disk.
This node is shared: docker is refused (corectl tool single-tenant on).

Two columns say two different things. Listed means the name is in node.yaml; present means the binary is on the disk. They differ for as long as one reconcile takes, and when they differ for longer than that, something on the machine needs looking at — which is what the ! marker is for.

Installing and removing

root@web1:~# corectl tool add git
tool git is available (/usr/bin/git)
git installed — /usr/bin/git

root@web1:~# corectl tool remove imapsync
tool imapsync removed
imapsync removed

Removing only removes what CoreCP installed. The machine keeps a ledger in /etc/corecp/rendered/tools.yaml of the tools this engine put there, so a git that was already on the server when CoreCP adopted it is never uninstalled by a reconcile — it was not ours to remove.

What comes with a role

Installing a role writes its own tools into node.yaml, once:

RoleTools
webgit, composer, wp-cli, valkey
mailimapsync

They are a starting point, not something that grows back: a tool you remove afterwards stays removed.

Valkey is deliberately one instance per server, not one per customer. An account reaches it through the PHP policy — session.save_handler and session.save_path are in the customer set — so there is no second socket to hand out and no per-account daemon to supervise.

Node and Python

These carry more than one version at a time. They install under /opt/corecp/node/<XY> and /opt/corecp/python/<XY>, exactly like the CoreCP PHP builds under /opt/corecp/php/<XY>:

root@web1:~# corectl tool add node@24
installing node@24 (corecp-node24)
tool node@24 is available (/opt/corecp/node/24/bin/node /opt/corecp/node/24/bin/npm)

root@web1:~# su - customer1 -c 'node --version && npm config get prefix'
v24.19.0
/home/customer1/.npm-global

Two Node LTS lines are active at a time. Adding the other one replaces the first: two series on the same PATH would mean node is whichever one sorted last, which is nobody's decision.

npm's global prefix and Python's user base are the customer's own home (~/.npm-global, ~/.local), set by /etc/profile.d/corecp-tools.sh. A shared global prefix on a machine with several customers would mean one account's npm install -g writes a binary every other account then runs.

Reachable inside the cage

Nothing extra is needed. The filesystem cage replaces /home, /etc/corecp and /proc and touches nothing else, so a binary under /usr/bin or /opt/corecp is visible inside a caged session by construction. What it needs is PATH, which the profile snippet above provides — including inside the cage, because the cage does not replace /etc.

Docker

Docker installs only on a server explicitly marked as carrying one customer. Its daemon runs as root and its socket is a root shell for whoever can open it, so it does not belong beside shared accounts and it is never given to an account in the cage.

root@single1:~# corectl tool add docker
error: docker may only be installed on a node marked single-tenant …

root@single1:~# corectl tool single-tenant on
node single-tenant

root@single1:~# corectl tool add docker
docker installed — /usr/bin/docker

The mark is an assertion about the machine, and the machine can contradict it: a server with more than one hosting account refuses it and names them. Taking the mark off again removes what it unlocked.

A package that is not there

On a server with the CoreCP OS mirror on (corectl update --os-mirror on), a tool whose package nobody put on a mirror list simply is not installable. The refusal says which list to add it to:

error: git could not be installed: … — check that git is on this node's mirror
(infra/build-server/packages/tools.list, then bash infra/build-server/mirror-upstream.sh)

The two runtimes are built by us rather than mirrored: infra/build-server/build-node.sh 24 --publish and infra/build-server/build-python.sh 313 --publish.

Addons: software from other vendors

The catalogue above is what the platform can install. Addons underneath it is what a vendor installs: JetBackup for backups, Installatron for one-press application installs, Releem for database tuning advice, cPGuard for malware scanning and a website firewall. Each comes with its own licence, and most come with a port of their own.

Four states, and only two of them are good news:

  • Running — installed, its service is up, and its licence is not refused.
  • Installed, not running — the record is there and the service is not. This is the state worth spotting, and it is why this is a table and not a row of switches.
  • Not installed — with, underneath the name, the reason it cannot be. The server runs its own check — the role, the PHP version, the licence — and answers "why can I not have this" in the same breath as "how is it doing".
  • Licence — Valid, Refused, or Only the vendor knows, which is the honest answer for the two whose licence is checked by a service rather than by a file on the machine.

Installing one

The dialog asks one thing: Reachable from. Addon ports install shut, which is right for an administrative port on a machine full of customers, and the row prints "reachable from nobody" rather than leaving the cell empty. Fill in the vendor's portal addresses, or your office, or leave it empty and open it later.

The install runs the vendor's own installer and takes as long as it takes, so you get a task to follow rather than a spinner.

Installing and removing ask you to confirm who you are if you have not done so in the last ten minutes. Changing an addon's allowlist does not: it is the same act the firewall screen offers with no such question, and it is narrower.

Removing one

The service, the ports and the record go together. The switch in the confirmation — Leave the software installed — stops after the record and the firewall, which is what you want when you are repairing a half-finished install by hand.

Not here

No Supervisor. Every hosting account already runs inside its own systemd slice with its own limits, and a second process manager beside it would be two places to look for one crashed worker.

No per-customer tool list. What a machine carries is an operator decision. A customer who needs a runtime the server does not have asks for it; a reseller narrows what their customers get through a package, never through the machine.