@@PRODUCT@@

Server profiles

A profile is the shape of a machine, written down once instead of typed out per server: which roles it serves, which tools it carries, how its database and its cache are tuned, and what a new WordPress site on it starts with.

Written for: Administrator

A profile is the shape of a machine, written down once instead of typed out per server: which roles it serves, which tools it carries, how its database and its cache are tuned, and what a new WordPress site on it starts with.

You set a machine up from one:

root@new:~# corectl setup --profile wordpress

and you can move an existing machine onto one, which is where the interesting rules are.

What a profile decides

Rolesthe exact set — web, db, mail, dns, ftp, backup
Webserverwhich provider, and whether LSCache is on
Toolsgit, Composer, WP-CLI, imapsync, Redis, a Node or Python series
Settingsthe config drop-ins it brings, sized to this machine
PHP ceilingsthe directives whose limit this kind of machine moves
WordPressthe plugins and the object cache a new site inherits

The lists are exact, not minimums. That matters most for what a profile leaves out: the WordPress profile has no mail role, and that absence is a decision, not an oversight.

The six profiles

root@web1:~# corectl profile list
Profiles:
     backup-target   Backup node — restic and its timers, tuned for large sequential transfers
     db-dedicated    Database server — MariaDB alone, InnoDB sized for a machine that runs nothing else
     dns-edge        Nameserver — PowerDNS authoritative alone, tuned for UDP bursts
     mail-dedicated  Mail server — Postfix, Dovecot and Rspamd alone, with the IP reputation to itself
     shared          Shared hosting — websites, databases, mail, DNS and FTP on one machine
  on wordpress       WordPress hosting — LiteSpeed with LSCache, Redis object cache, MariaDB tuned for InnoDB

This node carries wordpress. `corectl profile status` shows how far it has drifted.
Own presets go in /etc/corecp/profiles/<name>.yaml and win over the built-in one.

Two of them are machines that do everything; four are machines that do one thing.

shared — the all-in-one machine

Websites, their databases, their mail, their DNS and FTP, on one server. This profile used to tune nothing at all. That has been revised: it does tune things now, but only things that are a fact about the machine rather than a guess about what your customers run.

WhatWhy it assumes nothing about the workload
The size of the PHP bytecode cache (OPcache), derived from memoryWhat fills that cache is the number of PHP files a site has, not what those files do — every application benefits equally. PHP's own default is 128 MB per process, and on a shared node every account runs its own PHP: with forty accounts that default promises five gigabytes
More room for the number of files in the cacheAlso a count, not an assumption. When the counter is full PHP quietly stops caching new files, and you notice nothing except slowness
Checking file timestamps stays onThis is the one OPcache setting whose "faster" position does assume something: turning it off belongs on a server where a deploy restarts PHP. On shared hosting the deploy is a customer with an FTP client, who expects their change to show up
A ceiling on the number of PHP worker processes, derived from memoryThis is not a package's worker limit — that stays per account. This is what the machine can carry if every process hit its memory limit at once. The honest outcome is a request that waits rather than a process the kernel kills
More restraint about swap and about flushing to diskThe defaults let one large upload make every other customer on the machine wait. On a shared machine nobody should be waiting for somebody else's write

What it still does not touch: the PHP ceilings your customers work within, and MariaDB's own defaults. A ceiling is a question about what a customer may ask for, and a shared node's database serves work nobody has seen.

The four one-job machines

Roles are the building blocks, a profile is the shape of a machine, and a server group is what couples them. That is how a fleet is built: placement picks, per role, the machine that carries it — so a customer's websites can live on one server and their databases on another without either of them knowing.

What these profiles tune is paid for by what they leave out. A buffer pool may take two thirds of the memory on a machine where nothing else wanted it — which is also why switching a busy server to one of them is refused rather than sized down.

ProfileRoleWhat it does
db-dedicateddbInnoDB buffer pool at 65% instead of the 30% a shared machine gets, write behaviour and redo log matched to SSD, and a default per-database-user limit on simultaneous connections
mail-dedicatedmailMail only, with the IP address — and so the reputation — to itself. Rspamd's storage gets a memory ceiling that discards temporary data and not what the spam filter has learned. The kernel is tuned for many short connections, which is a property of email and not of your email
dns-edgednsA nameserver and nothing else. Everything it tunes is a queue or a buffer the kernel would otherwise quietly overflow — it says nothing about how many zones you have
backup-targetbackupThe machine that keeps the copies. It walks millions of paths and writes long streams, and its filesystem and network behaviour are matched to that. It does not configure the destination: the repository target and its password are the one thing no preset can carry

Applying backup-target installs restic and its timers; they run and fail visibly until you point them somewhere:

root@bk1:~# corectl profile apply backup-target
root@bk1:~# corectl role add backup --target sftp \
    --endpoint backup@storage.example.net --repo /srv/restic/bk1
root@bk1:~# corectl backup init

Profile or Releem?

Short version: a profile is the floor a machine boots with, Releem is the tuning of a database that is already running. A profile reasons from the machine's memory and from what its role set makes safe, before a single request has been answered. Releem watches the running server and proposes numbers no preset could know.

They do not compete. Applying a Releem recommendation shows up as drift from the profile — reported, never undone. If you want that value to be the floor from now on, copy the profile into /etc/corecp/profiles/ and put the number in it.

wordpress — a machine for one kind of application

If a machine runs one kind of application, it can be tuned for it:

  • LiteSpeed with LSCache, so the cache sits in the web server in front of PHP;
  • Redis with a memory ceiling and an eviction policy, so a plugin that caches every query cannot take the machine down;
  • an InnoDB buffer pool sized to this machine instead of MariaDB's 128 MB default — this is the single biggest difference between a slow WordPress and a fast one;
  • no mail role. A WordPress host is not a mail host. Sites send through a relay and port 25 stays shut.

A new WordPress site on such a machine gets the LiteSpeed Cache and Redis Object Cache plugins and has its object cache switched on for it. Page caching is turned on at the site rather than at the server on purpose: the server does not know which cookie means "logged in" and the cache plugin does, and a server-wide one-second cache is one plugin update away from showing a logged-in visitor's page to somebody else.

To read a profile in full, including why it makes the choices it does:

root@web1:~# corectl profile show wordpress
wordpress — WordPress hosting — LiteSpeed with LSCache, Redis object cache, MariaDB tuned for InnoDB
  source     built into corectl
  roles      web, db
  webserver  litespeed (lscache on)
  tools      composer, git, redis, wp-cli
  drop-in    mariadb (406 bytes, as rendered for this machine)
  drop-in    redis (39 bytes, as rendered for this machine)
  php policy max_input_vars max 30000
  wordpress  object cache redis, new sites get litespeed-cache, redis-cache
  note       Page caching is turned on at the *site*, not at the node. …

corectl profile show wordpress --yaml prints the preset exactly as it is written, which is what you copy to make your own.

Sizes come from the machine

The database and cache settings are not fixed numbers — they are a percentage of the RAM the server actually has, rounded to something a person would have typed:

root@web1:~# corectl profile status
profile   wordpress — WordPress hosting — LiteSpeed with LSCache, Redis object cache, MariaDB tuned for InnoDB
memory    3398 MB (what the profile's drop-ins are sized from)
drift     none — this node matches its profile

3398 MB gives a 960 MB buffer pool and a 320 MB Redis ceiling. Give the machine more memory and it does not resize itself — run corectl profile apply wordpress again and the settings are rewritten with the new numbers.

In the panel: choosing a profile while adding a server

The Add server wizard opens with the profile. Choosing one fills in the roles and the web server below — and nothing else: every checkbox stays yours.

If you then change a role or the web server, the screen says so, and the machine is enrolled with exactly the choices on screen. It is then not stamped with the profile name. That is deliberate: a machine carrying the name of a profile it does not match would report drift from its first minute, warning you about something you did on purpose. You can still apply the profile later, on the Configuration tab.

Pick "Custom" and the wizard works exactly as it always did.

No server in your installation yet, or none reachable right now? The panel cannot fetch the profile catalogue and says so. Tick the roles yourself; the profile can come later.

In the panel: changing a running server's profile

On the server page, Configuration tab, the current profile is shown with a badge saying whether the machine still matches it. Switch profile opens a panel with three things, in this order:

  1. What the profile is — the chosen profile's summary, its roles, and the trade-offs it wrote down itself. Meeting db-dedicated for the first time, that is what you want to read, not only a list of differences.
  2. What it would change — press What would change?. This button changes nothing on the server; it asks the machine what would happen.
  3. What stands in the way, if anything does. See below.

Only after you have looked does Apply profile become active. Applying asks you to prove who you are again — one press of that button can take a role off a server with customers on it. Looking deliberately does not ask: a confirmation you have to give before every glance is a confirmation you learn to click away.

Since this round that confirmation works the same everywhere: type your code and the apply carries on by itself — no reopening the panel, nothing to choose again. Dismiss the dialog and nothing has happened, your choice is still there, and no error appears either.

Changing a machine's profile

Always look before you leap. --dry-run changes nothing and tells you everything:

root@web1:~# corectl profile apply shared --dry-run

Adding is free. A switch that only adds a role or a tool goes through without asking anything.

Taking something away is not. Removing a role means breaking whatever needs it — mailboxes, DNS zones, databases, FTP logins — and a profile switch is not a migration. So CoreCP refuses, and the refusal tells you exactly what stands in the way and how to free each one:

root@web1:~# corectl profile apply wordpress
corectl: switching to profile wordpress would take the mail role(s) off this node, and 33 binding(s) still need it:
  mail      domain   example.nl (account acme)              corectl mail disable example.nl
  mail      mailbox  info@example.nl (account acme)         corectl mailbox delete info@example.nl
  mail      … and 27 more (19 domain, 14 mailbox in total)

Move them to another node first — that is what the panel's service bindings are for, and it keeps the data — or free them with the commands above, or pick a profile that keeps the role. Nothing on this node was changed.

In the panel you see that same list: every mailbox, zone, database and FTP login that would lose its machine, with the command that frees it underneath. While anything is on the list, Apply profile stays disabled. Showing the count and hiding the list would be exactly the "role in use" message this engine exists to replace.

There is no way to force it, and that is deliberate. The way past a binding is to move it — that is what the panel's server placement is for, and it keeps the customer's data. Nothing on the machine is touched by a refused switch: the server is exactly as it was.

If nothing is bound, taking a role off is fine. The rule is about bindings, not about direction.

A profile is a starting point, not a cage

You are free to change a machine after you have given it a profile. Nothing undoes what you did. What CoreCP does is tell you the machine and its profile have moved apart:

root@web1:~# corectl tool add node@24
root@web1:~# corectl profile status
profile   wordpress — WordPress hosting — LiteSpeed with LSCache, Redis object cache, MariaDB tuned for InnoDB
memory    3398 MB (what the profile's drop-ins are sized from)
drift     1 difference(s). A profile is a starting point: these are
          reported, never undone.

  tool        node@24                added    installed here, not part of the profile

Put the node back on its profile with: corectl profile apply wordpress

The same thing shows up in the health check as a warning, never a failure — a machine you deliberately gave an extra tool is not unhealthy:

root@web1:~# corectl doctor | grep profile
[warn] profile            wordpress — 1 difference(s): tool node@24 added — installed here, not part of the profile

And in the panel, on the server's page: the profile name with a badge saying either no drift or how many differences there are, with the list underneath.

Putting a machine back on its profile is something you ask for, and only then: corectl profile apply wordpress.

Writing your own profile

Your own presets live in /etc/corecp/profiles/ and win over the built-in one of the same name, so you can change what "shared" means on your fleet without waiting for us. Start from one that exists:

root@web1:~# mkdir -p /etc/corecp/profiles
root@web1:~# corectl profile show shared --yaml > /etc/corecp/profiles/shared-nl.yaml
root@web1:~# nano /etc/corecp/profiles/shared-nl.yaml

Change the name: field to match the file name — those two have to agree. Everything else is a list you can edit:

name: shared-nl
summary: Our shared platform, with Node for the deploy pipelines
roles: [web, db, mail, dns, ftp]
webserver: nginx_apache
tools: [composer, git, imapsync, node@24, redis, wp-cli]

Everything a profile names is checked before a single package is installed, and you are told about all of it at once rather than one mistake per attempt:

root@web1:~# corectl profile apply shared-nl --dry-run
corectl: profile shared-nl cannot be applied:
  role "mailserver" does not exist (backup, db, dns, ftp, mail, web)
  tool "kubernetes": unknown tool "kubernetes" — `corectl tool list` names the catalogue

Where to look next

  • Tools on a server — what a tool is and how the list works.
  • Config drop-ins — the settings a profile brings, and how to change one by hand afterwards. Since this round that includes the PHP-FPM worker settings and the kernel settings.
  • Adding a server — the wizard where the profile is the first question.
  • Integrations on a server — where a customer's role ends up, and how to move it instead of letting it stand in the way.