CentOS Linux 8 reached end of life in December 2021 and CentOS Linux 7 in June 2024, so neither receives security updates any more. Rocky Linux and AlmaLinux are free, community-run rebuilds of Red Hat Enterprise Linux that took CentOS's place, and both provide tools to convert an existing server in place without reinstalling. In this tutorial you will migrate a CentOS Linux 8 server to Rocky Linux 8 or AlmaLinux 8, then see how to move a CentOS 7 server to version 8 with ELevate, and how to verify and clean up afterwards.

Prerequisites

Before you begin, you need:

  • A server running CentOS Linux 8 (the main procedure) or CentOS Linux 7 (covered in its own section).
  • Root access or a user with sudo privileges.
  • At least 5 GB of free space on /.
  • Out-of-band access (a web console or VNC from your provider's panel) in case the server does not come back after the reboot.
  • A recent backup or disk snapshot. The conversion replaces every package on the system.

Choosing between Rocky Linux and AlmaLinux

Both distributions are binary compatible with RHEL, free to use, supported for 10 years per major version and governed by non-profit organisations. For most servers the choice does not matter technically.

Rocky LinuxAlmaLinux
GovernanceRocky Enterprise Software FoundationAlmaLinux OS Foundation
Compatibility goalBug-for-bug compatible with RHELABI compatible with RHEL (may ship extra fixes)
In-place tool from CentOS 8migrate2rocky.shalmalinux-deploy.sh
Tool for CentOS 7 and major upgradesELevate (Leapp) with Rocky dataELevate (Leapp) with AlmaLinux data
Support for version 8Until May 2029Until May 2029

Pick one and use it across your whole fleet. The rest of the guide gives the commands for both.

Step 1 - Identifying your CentOS release

Check exactly what the server runs:

cat /etc/centos-release
CentOS Linux release 8.5.2111
  • CentOS Linux release 8.x: follow Steps 2 to 6.
  • CentOS Linux release 7.x: jump to "Migrating CentOS 7 with ELevate".
  • CentOS Stream release 8 or 9: CentOS Stream is ahead of RHEL rather than a rebuild of it, so converting it is not a supported path for all tools. Check the README of the conversion tool you plan to use, and consider installing a fresh Rocky Linux or AlmaLinux server and moving the workload instead.

Also list third-party repositories and software that you will need to check after the migration:

dnf repolist

Repositories such as EPEL, Docker, or vendor repositories built for "EL8" keep working on Rocky Linux 8 and AlmaLinux 8, because they target the RHEL 8 platform rather than CentOS specifically.

Step 2 - Pointing CentOS 8 at the vault repositories

Since CentOS 8 reached end of life, its packages were moved from the mirror network to vault.centos.org, and the default repository files point to mirrors that no longer serve them. Any dnf command fails with an error similar to this:

Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist

Point the CentOS repository files at the vault so dnf works again:

sudo sed -i -e 's|^mirrorlist=|#mirrorlist=|g' \
  -e 's|^#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' \
  /etc/yum.repos.d/CentOS-*.repo

Refresh the metadata to confirm it works:

sudo dnf makecache
CentOS Linux 8 - AppStream     ...
CentOS Linux 8 - BaseOS        ...
Metadata cache created.

Step 3 - Updating the system and preparing a session

Install the last available CentOS 8 updates so the conversion starts from a consistent system:

sudo dnf update -y

If a kernel was updated, reboot and reconnect:

sudo reboot

The conversion takes 15 to 60 minutes. Run it inside tmux so that a dropped SSH connection does not kill it:

sudo dnf install -y tmux
tmux new -s migrate

If you get disconnected, log back in and reattach with tmux attach -t migrate.

Step 4 - Converting to Rocky Linux 8

Skip this step if you are migrating to AlmaLinux and go to Step 5.

Download the official migrate2rocky.sh script from the Rocky Linux rocky-tools repository:

curl -fsSLO https://raw.githubusercontent.com/rocky-linux/rocky-tools/main/migrate2rocky/migrate2rocky.sh

Read the script before running it as root:

less migrate2rocky.sh

Run the conversion. The -r flag performs the migration:

sudo bash migrate2rocky.sh -r

The script checks the system, installs the Rocky Linux release and repository packages, swaps the CentOS-branded packages for their Rocky equivalents and synchronises all packages with the Rocky Linux repositories. When it finishes, it asks you to reboot and writes a full log to /var/log/migrate2rocky.log.

If it stops with an error, the reason is in /var/log/migrate2rocky.log. Fix it and run the script again; it can be re-run safely.

Continue with Step 6.

Step 5 - Converting to AlmaLinux 8

Skip this step if you converted to Rocky Linux in Step 4.

Download the official almalinux-deploy.sh script:

curl -fsSLO https://raw.githubusercontent.com/AlmaLinux/almalinux-deploy/master/almalinux-deploy.sh

Read it before running it as root:

less almalinux-deploy.sh

Run the conversion:

sudo bash almalinux-deploy.sh

The script verifies the system, imports the AlmaLinux signing key, replaces the CentOS release and branding packages, and reinstalls or updates packages from the AlmaLinux repositories. When it finishes it reports that the migration completed. If it fails, the error printed on screen names the package or check that stopped it; fix it and run the script again.

Step 6 - Rebooting and verifying the migration

Reboot into the new system:

sudo reboot

After reconnecting, check the release. On Rocky Linux:

cat /etc/os-release
NAME="Rocky Linux"
VERSION="8.10 (Green Obsidian)"
ID="rocky"
ID_LIKE="rhel centos fedora"
...

On AlmaLinux the same file shows NAME="AlmaLinux" and ID="almalinux".

Confirm that you booted a kernel from the new distribution and that the enabled repositories are the new ones:

uname -r
dnf repolist
repo id          repo name
appstream        Rocky Linux 8 - AppStream
baseos           Rocky Linux 8 - BaseOS
extras           Rocky Linux 8 - Extras

Look for packages still carrying CentOS branding:

rpm -qa | grep -i centos

An empty output is ideal. Old kernels (kernel-*.el8 built by CentOS) may still appear; they are removed automatically as new kernels are installed. If centos-release or centos-repos packages appear, the conversion did not finish; re-run the script.

Check that no services failed to start and that SELinux is still enforcing:

systemctl --failed
getenforce
  UNIT LOAD ACTIVE SUB DESCRIPTION
0 loaded units listed.
Enforcing

Finally, install the latest updates from the new repositories and test your applications (web server, database, scheduled jobs) the way users reach them:

sudo dnf update -y

Migrating CentOS 7 with ELevate

CentOS 7 cannot be converted directly to version 8 with the scripts above because it is a different major version. The AlmaLinux ELevate project uses Red Hat's Leapp framework to upgrade a CentOS 7 server in place to AlmaLinux 8 or Rocky Linux 8. This is a major upgrade (Python 2 to 3, yum to dnf, new versions of every service), so test it on a clone first and keep the snapshot handy.

Because CentOS 7 is end of life, its repositories are no longer on the mirror network. Replace the base repository file with the archive copy maintained by AlmaLinux and install the last updates:

sudo curl -o /etc/yum.repos.d/CentOS-Base.repo https://el7.repo.almalinux.org/centos/CentOS-Base.repo
sudo yum upgrade -y
sudo reboot

Install the ELevate release package and the Leapp tools:

sudo yum install -y http://repo.almalinux.org/elevate/elevate-release-latest-el7.noarch.rpm

Then install Leapp with the data package for your target distribution. For AlmaLinux 8:

sudo yum install -y leapp-upgrade leapp-data-almalinux

For Rocky Linux 8, install leapp-data-rocky instead of leapp-data-almalinux.

Run the pre-upgrade check. It changes nothing and writes a report:

sudo leapp preupgrade

Read /var/log/leapp/leapp-report.txt. Entries marked as inhibitors block the upgrade and must be fixed first. Two are very common on servers. The first is the obsolete pata_acpi kernel module, which you can unload:

sudo rmmod pata_acpi

The second is a confirmation about removing the pam_pkcs11 module, which you answer with:

sudo leapp answer --section remove_pam_pkcs11_module_check.confirm=True

Run sudo leapp preupgrade again until no inhibitors remain, then start the upgrade and reboot:

sudo leapp upgrade
sudo reboot

The first boot runs the upgrade itself in a special environment and takes a while; watch it from the web console. When the server comes back, verify it as in Step 6, and review /var/log/leapp/leapp-report.txt and /var/log/leapp/leapp-upgrade.log for anything that was skipped.

Troubleshooting

Failed to download metadata for repo on CentOS 8. The repository files still point to the retired mirrors. Repeat Step 2 and check that no other .repo file references mirrorlist.centos.org.

The migration script stops because of a third-party package. Packages that depend on exact CentOS package versions can block the swap. The log names the package. Remove it with sudo dnf remove package_name, run the migration again, and reinstall the package from its vendor afterwards.

SELinux denials after the migration. Files created during the conversion can end up with wrong security labels. Relabel the file system on next boot instead of disabling SELinux:

sudo touch /.autorelabel
sudo reboot

The server boots an old CentOS kernel. List the boot entries with sudo grubby --info=ALL | grep ^kernel, set the newest one as default with sudo grubby --set-default /boot/vmlinuz-version, and reboot.

Conclusion

Your server now runs Rocky Linux 8 or AlmaLinux 8 with the same applications and configuration it had on CentOS, and it receives security updates again until May 2029. As next steps, plan the move to version 9 or 10 (ELevate also supports upgrading Rocky Linux 8 and AlmaLinux 8 to 9, or you can build a new server and migrate the workload), enable automatic security updates with dnf-automatic, and remove the pre-migration snapshot once the server has run normally for a few days.