# Server Maintenance and Updates

> How a CorePanel server stays current: dnf update is the whole mechanism, what it converges, what it will never touch, and how to repair a host by hand.

Source: https://www.corepanel.net/docs/maintenance/
Last updated: 2026-09-04
Part of the CorePanel documentation — https://www.corepanel.net/docs

---

CorePanel has no update daemon, no nightly job and no agent phoning home. The mechanism
that keeps a server current is the one already on the box:

```bash
dnf update
```

That is not a simplification for the docs — it is the design. Everything CorePanel needs
to correct on a running server travels in its packages, so the moment you update them the
host converges. This page says exactly what that covers, so you know what an update will
and will not do before you run one.

## What an update converges

| Area | What arrives with the packages |
|---|---|
| **PHP stack** | The base set of PHP versions and extensions, declared by the `corepanel-php` package. Versions and extensions added later from the panel are updated by the same `dnf update`, but they are not part of this set — see [PHP Extensions](https://www.corepanel.net/docs/php/extensions) |
| **SELinux policy** | The `corepanel_app_t`, `corepanel_cron_t` and `corepanel_phpfpm` modules, shipped compiled and reloaded on every upgrade |
| **PHP-FPM pools** | The inert placeholder pool that replaces the stock Remi `www` pool, plus the SELinux booleans and labels PHP needs to serve from `/home` |
| **Runtime directories** | The `tmpfiles.d` entries that recreate `/run/php-fpm` on every boot |

The important consequence is for **servers that have been running a while**. Earlier
CorePanel releases configured some of this from the installer, which runs once when the
server is built and never again — so a correction made later reached only newly built
servers. That is no longer true of anything in the table above.

## What an update will never do

These are guarantees, not current behaviour that might change:

- **It never removes a PHP version.** Accounts run on a version they were given (and can
  be [moved to another one](https://www.corepanel.net/docs/accounts/editing#changing-the-php-version)), and the
  webmail runs on PHP 8.4. Versions are only ever added.
- **It never rewrites configuration you edited.** `main.cf`, `dovecot.conf`, your firewall
  rules and your DNS zones are yours. CorePanel only rewrites files it owns and marks as
  its own.
- **It never touches a PHP version CorePanel does not ship.** If you install a Remi PHP of
  your own, its pool and its service are left exactly as you set them. CorePanel manages
  only the versions listed by `rpm -q --requires corepanel-php`.
- **It never reboots, never prompts and never asks for a password.** Anything needing a
  decision — enabling disk quotas, for instance — stays a deliberate action you take.
- **It never restarts a service that did not need it.** PHP-FPM runs every account's pool
  in one process per version, so a needless restart would drop live requests. A version is
  restarted only when its own configuration actually changed.

## An open panel picks the new version up on its own

Updating `corepanel-ui` replaces the panel's files, which means the build any open
browser tab is running has just been deleted from under it. Until now, the first page
that tab tried to open after the update failed to load and only a hard refresh brought
it back.

That is handled now. A tab that was left open across an update notices that its build is
gone, reloads itself once, and lands on the new panel — no `Ctrl+R`, no lost session.
You may see *"The panel was updated. Reloading…"* for an instant while it happens.

The reload happens at most once. If a page still fails after it, the cause is not a
stale build, and the panel says so with a recovery screen instead of reloading in a
loop.

## The PHP stack is its own package

The PHP versions live in a package called `corepanel-php`. You can see exactly what it
pulls in:

```bash
rpm -q --requires corepanel-php
```

That is the **base** set — what a server starts with. A version added afterwards with
`corepanel php install`, and any extension added from **PHP → Extensions**, is a package of
its own that this list does not mention. It is still kept current by `dnf update` like
everything else; it simply does not hang off `corepanel-php`.

CorePanel *recommends* this package rather than requiring it. That is deliberate: the PHP
packages come from the Remi repository, and if Remi has not yet published a newly added
version for your EL release, that must not stop the panel itself from updating. The
trade-off is visible rather than silent — you see a package transaction fail, instead of a
PHP version quietly arriving unconfigured.

The webmail is the one exception: `corepanel-roundcube` requires PHP 8.4 outright, because
it will not run without it.

Extensions outside that set — the ionCube Loader, for instance, which encoded software
like WHMCS needs — are installed separately and are not touched by updates. See
[PHP Extensions and ionCube](https://www.corepanel.net/docs/php/extensions).

> **Removing it behaves differently on EL8**
>
> On AlmaLinux/Rocky **9 and 10**, if you remove `corepanel-php` it stays removed, and
> `dnf install corepanel-php` brings it back. On **EL8**, dnf re-adds it the next time it
> updates the `corepanel` package. This is dnf's own handling of weak dependencies, not
> something CorePanel controls.
## Repairing a host by hand

There is no special repair command to learn. Because all of this lives in package
scriptlets, reinstalling the package re-runs them:

```bash
# Re-apply the PHP stack configuration: pools, SELinux booleans and labels
dnf reinstall corepanel-php

# Re-load the SELinux policy modules and relabel the application trees
dnf reinstall corepanel corepanel-sys
```

Both are safe to run on a live server. They re-apply what is already correct without
touching it, and restart only what genuinely changed.

To see what a package's scriptlet did, read the transaction output, or afterwards:

```bash
dnf history          # find the transaction
dnf history info <id>
```

## Checking the SELinux policy is loaded

CorePanel confines account applications, account cron jobs and PHP-FPM's access to MariaDB
with its own SELinux modules. A missing module is silent — nothing fails, the confinement
simply is not there — so it is worth knowing how to check:

```bash
semodule -l | grep corepanel
```

You should see `corepanel_app`, `corepanel_cron` and `corepanel_phpfpm`. If one is
missing, `dnf reinstall corepanel corepanel-sys` loads it.

## When a service fails or the server runs out of memory

Every CorePanel service is already restarted by systemd when it fails. Two things it
does not do on its own, and now does:

**It no longer gives up in five seconds.** `Restart=on-failure` with systemd's defaults
allows five restarts in ten seconds, and with a one-second delay that budget is spent
almost immediately — a service that needed a few more moments than something it depends on
was left dead for good. The panel's services now retry ten times over five minutes.

**Somebody is told.** When systemd does stop retrying, `OnFailure=` runs a reporter that
emails the panel's administrator: which service, what systemd says happened, how many times
it restarted on its own, and the last 100 journal lines. It is a separate unit on purpose —
the process that died cannot report its own death, and the panel's notification system
lives inside `corepanel-core`, which is one of the services being watched. The reporter
reads the address straight out of the database and hands the message to `sendmail`, so it
still works when core is the thing that is down. At most one mail per service per hour.

If the mail says systemd has given up, the service will not come back without:

```bash
systemctl reset-failed corepanel-core && systemctl start corepanel-core
```

### Who the kernel kills first

This machine runs other people's PHP, and the Linux OOM killer picks its victim by how
much memory a process is using — so, left alone, it takes the biggest one. On a real
server that was `corehttpd`, scoring higher than anything else on the box: the first thing
the kernel would have taken is the single process serving every site.

The panel's services now carry an `OOMScoreAdjust`, which does not prevent an OOM but
decides the order. A hosting server should lose one site before it loses the panel you
would fix it from:

| Service | Adjust | Why |
|---|---:|---|
| `corepanel-sys` | -900 | The root daemon. Without it nothing can be repaired at all |
| `corepanel-core` | -800 | The data, and the hub that raises notifications |
| `corepanel-api` | -700 | No panel without it, but cheap and quick to restart |
| `corehttpd` | -600 | Losing it takes every site on the server down at once |
| `corepanel-auth` | -100 | Least protected, deliberately — see below |

`corepanel-auth` is the one service where being killed is the right outcome. It grows
steadily while it runs, so protecting it like the others would turn that into the whole
server being taken apart around it, site by site. Killed, it restarts in a second and
comes back at its startup footprint.

`OOMScoreAdjust` is applied when a process starts, so a server picks this up when the
service restarts — which the package upgrade does for you. It is also the only lever of
its kind available on all of RHEL 8, 9 and 10: `OOMPolicy` needs systemd 243 and
`MemoryMin` needs cgroup v2, and RHEL 8 has neither.

## Upgrading the whole server

CorePanel does not restrict `dnf update`, and there is nothing to stop first. Standard
practice applies: update at a quiet hour, and expect PHP-FPM to restart for any version
whose configuration changed in that release.
