Skip to content

image

Rocky Linux 9

A RHEL 9 rebuild that aims for bug-for-bug parity. Pick it when exact Red Hat behaviour matters more than anything else.

Parity is the point

Rocky Linux 9 rebuilds RHEL 9 sources with the stated goal of behaving identically, quirks included. That makes it a strong staging and CI target for software that ships to RHEL in production. If a test passes on Rocky 9, it should pass on RHEL 9. Released July 2022, Rocky 9 gets general support to May 2027 and security fixes to May 2032.

The practical difference from AlmaLinux 9 is small for most workloads. Treat it as a standards choice: match what your organisation or your customers run.

First boot, Ansible-shaped

Most Rocky deployments are configured by automation, so here is the minimum by hand, followed by the playbook equivalent:

dnf -y upgrade
dnf -y install epel-release
dnf config-manager --set-enabled crb
dnf -y install python3-libselinux python3-firewall tmux

The CRB (CodeReady Builder) repository supplies build dependencies many EPEL packages need. Turn it on early or you'll hit confusing missing-dependency errors later.

- hosts: rocky
  become: true
  tasks:
    - ansible.builtin.dnf: { name: '*', state: latest }
    - ansible.posix.firewalld:
        service: https
        permanent: true
        immediate: true
        state: enabled
    - ansible.posix.seboolean:
        name: httpd_can_network_connect
        state: true
        persistent: true
    - ansible.builtin.copy:
        dest: /etc/ssh/sshd_config.d/40-keys-only.conf
        content: "PasswordAuthentication no\nPermitRootLogin prohibit-password\n"
        validate: /usr/sbin/sshd -t -f %s
      notify: reload sshd
  handlers:
    - name: reload sshd
      ansible.builtin.service: { name: sshd, state: reloaded }

The validate line runs sshd -t against the candidate file before it goes live. A typo can't lock you out.

firewalld zones done properly

For a server with one public interface, the public zone is fine. To restrict admin ports to your office or VPN range, use a source-bound zone rather than a pile of rich rules:

firewall-cmd --permanent --new-zone=mgmt
firewall-cmd --permanent --zone=mgmt --add-source=198.51.100.0/28
firewall-cmd --permanent --zone=mgmt --add-service=ssh
firewall-cmd --permanent --zone=public --remove-service=ssh
firewall-cmd --reload

Keep the browser console in the portal open in another tab before removing SSH from public. If your source range is wrong, that is your way back in.

SELinux and containers

Podman is the native container runtime on Rocky 9, rootless and SELinux-aware. Bind mounts need the :Z or :z suffix so files get a container-readable label:

podman run -d --name api -p 8080:8080 -v /srv/api:/data:Z ghcr.io/example/api:1.4

Generate a systemd unit with Quadlet (a .container file in /etc/containers/systemd/) so the container starts at boot without a separate daemon. Docker Engine also installs from Docker's RHEL repository if your tooling depends on it.

Patching

dnf -y install dnf-automatic
systemctl enable --now dnf-automatic-install.timer
dnf updateinfo list --security

dnf-automatic-install.timer downloads and applies updates on a schedule. Scope it to security errata in /etc/dnf/automatic.conf if you want feature updates to wait for a deliberate change window.

Gotchas

  • Kernel live patching isn't set up by default. Plan reboots for kernel errata.
  • NetworkManager owns networking. Use nmcli. Legacy ifcfg files are deprecated in 9.
  • crypto-policies. The system-wide DEFAULT policy rejects SHA-1 signatures. Old clients may fail TLS or SSH handshakes. Fix the client rather than dropping to LEGACY.

Building RPMs

Rocky 9 makes a good packaging host. mock builds each RPM in a clean chroot, so your build host's installed packages never leak into the result:

dnf -y install mock rpm-build rpmdevtools
usermod -aG mock ops
rpmdev-setuptree
mock -r rocky-9-x86_64 --rebuild ~/rpmbuild/SRPMS/myapp-1.2-1.el9.src.rpm

Each chroot is cached under /var/cache/mock and /var/lib/mock. NVMe-backed disk keeps chroot set-up quick, but those directories grow. Give them their own cleanup job, or the 40 GB on Boost fills faster than you expect. Sign packages with a key kept off the build host, and publish the repository from a separate server.

Sizing

CI runners building RPMs, or staging copies of RHEL services, map well to Boost and Turbo. Parallel mock builds or heavy test suites want the six cores on Warp. A production-like RHEL service you only use for pre-release testing can share a box with its runner. Split them once test jobs start skewing the service's response times, because noisy neighbours inside your own VM still count. See CI runners.

Questions

Rocky Linux or AlmaLinux?

Both track RHEL 9 and both run the same software. Rocky aims for bug-for-bug parity with RHEL; AlmaLinux targets ABI compatibility and sometimes ships fixes earlier. Pick whichever your team or vendor already standardises on.

Can I manage Rocky Linux with Ansible?

Yes. Python 3 is present on the image, so Ansible can connect over SSH immediately. The ansible.posix and community.general collections cover firewalld and SELinux tasks.

When does Rocky Linux 9 reach end of life?

General support runs to May 2027 and security support to May 2032, in step with RHEL 9.