Fleet Management
    Patch & Compliance

    Deploy Uyuni on a VPS

    Deploy Uyuni — the upstream of SUSE Multi-Linux Manager — on a RamNode VPS for patch management, channel mirroring, Salt-based configuration, and OpenSCAP auditing across mixed Linux fleets.

    Uyuni is the upstream of SUSE Multi-Linux Manager and the successor to Spacewalk. It does patch management, channel mirroring, configuration management via Salt, provisioning via Cobbler, Ansible integration, and OpenSCAP auditing across SLE, openSUSE, RHEL and clones, Ubuntu, and Debian clients from one server.

    It is also the heaviest thing in this guide series by a wide margin. Read the requirements section before you provision anything.

    Target version is Uyuni 2026.06.

    Requirements, honestly

    RequirementUyuni Server
    Host OSopenSUSE Tumbleweed, clean and current
    CPUMulti-core x86_64
    RAM16 GB minimum for a base install. 32 GB recommended for production
    Disk100 GB baseline, plus roughly 50 GB per SUSE or openSUSE product mirrored and roughly 360 GB per Red Hat product
    DNSA resolvable FQDN is mandatory. Not optional, not "works without"
    Container runtimepodman 4.5.0 or later

    The proxy is far lighter: 2 GB RAM and 50 GB disk covers testing and production both, plus the same per-product mirroring space.

    Three things follow from this table.

    One: you need a large plan. A 2 GB VPS will not run Uyuni. The server will start and then die during setup or the first channel sync. Size for 16 GB as an absolute floor and 32 GB if this is going to carry real client load.

    Two: budget disk seriously. Mirroring one Red Hat product family is roughly 360 GB by itself. If you plan to mirror EL9, EL10, and Ubuntu 24.04, you are into the terabyte range. On RamNode, that means attaching block storage rather than trying to fit it on the plan's included SSD.

    Three: the validated host OS is Tumbleweed. This changed in 2025.10, moving off openSUSE Leap Micro 5.5 after it went out of support. Tumbleweed is not a stock template on most VPS providers, so plan on a custom ISO install on a KVM plan. The project explicitly says other host OSes are not forbidden, just untested, and there are ContainerUtils repos for Debian and Ubuntu hosts if you want to go that route. For a first deployment, use what upstream tests.

    If the sizing does not fit your budget, Uyuni is the wrong tool for your fleet. For inventory and compliance visibility on a small number of VPS instances, the Fleet guide in this series does that job on a 4 GB box.

    Step 1: Provision and prepare the host

    Install openSUSE Tumbleweed on a KVM plan with at least 16 GB RAM. Then:

    shell
    zypper dup
    reboot

    Tumbleweed is rolling. zypper dup is the correct update command, not zypper up. Run it, reboot, and do it again periodically or your podman and kernel drift out from under the containers.

    Set the FQDN and make sure it resolves both forward and reverse:

    shell
    hostnamectl set-hostname uyuni.example.com
    echo "203.0.113.10  uyuni.example.com  uyuni" >> /etc/hosts
    
    hostname -f          # must print uyuni.example.com
    dig +short uyuni.example.com
    dig +short -x 203.0.113.10

    If hostname -f returns anything other than the FQDN, stop and fix it. Uyuni bakes the FQDN into its SSL certificates and its Salt master config. Fixing it afterward is a certificate regeneration exercise you do not want.

    Step 2: Attach and prepare storage

    Uyuni wants its data on dedicated volumes, not the root filesystem. Attach block storage and identify the devices:

    shell
    lsblk

    You want two separate targets:

    • Storage volume for /var/lib/containers/storage/volumes, which holds repositories, channel content, and images. This is the one that grows to hundreds of gigabytes.
    • Database volume for PostgreSQL. Faster is better here.

    uyuni-storage-setup-server handles the LVM and mount setup. Install it in the next step and run it before mgradm install.

    Step 3: Add the repository and install

    shell
    zypper ar https://download.opensuse.org/repositories/systemsmanagement:/Uyuni:/Stable/images/repo/Uyuni-Server-POOL-$(arch)-Media1/ uyuni-server-stable
    zypper ref
    zypper in -t product Uyuni-Server

    Accept the GPG key when prompted.

    If you are on a non-SUSE host OS, use the ContainerUtils repo at https://download.opensuse.org/repositories/systemsmanagement:/Uyuni:/Stable:/ContainerUtils/ and install the packages directly instead:

    shell
    # non-SUSE host only
    apt install mgradm mgrctl mgradm-bash-completion podman uyuni-storage-setup-server

    Confirm podman meets the floor:

    shell
    podman --version   # must be >= 4.5.0

    Now set up storage before deploying:

    shell
    mgr-storage-server /dev/vdb /dev/vdc

    First argument is the storage device, second is the database device. The tool creates the volume groups, filesystems, and mount points. Verify:

    shell
    df -h /var/lib/containers/storage/volumes

    Step 4: Deploy

    shell
    mgradm install podman uyuni.example.com

    You will be prompted for three things:

    shell
    Password for the CA key to generate:
    Confirm the password:
    Administrator password:
    Confirm the password:

    Plus an email for notifications. Store the CA key password somewhere durable. You need it for certificate operations later, and it is not recoverable.

    Deployment pulls the container images and runs the setup assistant. Expect several minutes. On a slower disk, expect more.

    When it finishes, the web UI is at https://uyuni.example.com/. Log in with admin and the administrator password you set, then create your first organization.

    Step 5: Understand the container model

    Since 2024.10, Uyuni is containers only. The RPM-based server product is gone. Two commands drive everything:

    mgradm manages the deployment lifecycle:

    shell
    mgradm status              # is everything running
    mgradm inspect             # image and version details
    mgradm upgrade podman      # upgrade the deployment
    mgradm backup create       # backup
    mgradm support config      # collect a supportconfig bundle

    mgrctl reaches inside the running server container:

    shell
    mgrctl exec -ti -- bash                    # shell inside the server
    mgrctl exec -- spacewalk-service status    # run a command inside
    mgrctl cp localfile server:/tmp/           # copy a file in
    mgrctl logs -f                             # follow logs

    Every "run this on the Uyuni server" instruction you find in older Spacewalk or SUSE Manager docs now needs an mgrctl exec -- prefix. This trips up nearly everyone once.

    Step 6: Add channels

    Channels are the repository mirrors clients pull from. spacewalk-common-channels bootstraps the well-known ones:

    shell
    mgrctl exec -ti -- spacewalk-common-channels \
      -u admin -p 'YOUR_ADMIN_PASSWORD' -a x86_64 \
      'opensuse_leap15_6*'

    For Ubuntu 24.04:

    shell
    mgrctl exec -ti -- spacewalk-common-channels \
      -u admin -p 'YOUR_ADMIN_PASSWORD' -a amd64-deb \
      ubuntu-2404-pool-amd64-uyuni \
      ubuntu-2404-amd64-main-uyuni \
      ubuntu-2404-amd64-main-updates-uyuni \
      ubuntu-2404-amd64-main-security-uyuni \
      ubuntu-2404-amd64-uyuni-client

    For EL9 clones:

    shell
    mgrctl exec -ti -- spacewalk-common-channels \
      -u admin -p 'YOUR_ADMIN_PASSWORD' -a x86_64 \
      'almalinux9*' 'almalinux9-uyuni-client*'

    Then sync. This is the part that eats your disk and your bandwidth:

    shell
    mgrctl exec -ti -- spacewalk-repo-sync -c almalinux9-x86_64 --latest

    Watch progress in the UI under Admin, Task Schedules, or tail the logs:

    shell
    mgrctl exec -- tail -f /var/log/rhn/reposync/almalinux9-x86_64.log

    Add --latest to sync only the newest package versions. Without it you mirror every historical version in the upstream repo, which is how a 360 GB estimate becomes a 900 GB reality.

    Uyuni added a disk space health check specifically because filling the volume during a sync can corrupt the database. Do not ignore the warnings it emits.

    Step 7: Replace the SSL certificate

    Uyuni generates a self-signed CA at install. Replacing it with a real certificate is worth doing before you bootstrap clients, since every client trusts the CA at registration time.

    Read this carefully, because 2026.06 changed the rules. The transition to openSUSE Leap 16.0 as the container base brought Python 3.13, which rejects any CA certificate that does not mark the X509v3 Basic Constraints extension as critical. A CA cert that worked on an older release will fail after the upgrade. If you are bringing your own CA, check it:

    shell
    openssl x509 -in root-cert.pem -noout -text | grep -A1 "Basic Constraints"

    You want to see X509v3 Basic Constraints: critical. If the word critical is absent, regenerate the CA before upgrading or the deployment will not come back.

    To install a third-party certificate:

    shell
    for f in root-cert.pem cert.pem private.key; do
      mgrctl cp $f server:/tmp/
    done
    
    mgrctl exec -ti -- mgr-ssl-cert-setup \
      --root-ca-file=/tmp/root-cert.pem \
      --server-cert-file=/tmp/cert.pem \
      --server-key-file=/tmp/private.key

    Restart services afterward:

    shell
    mgrctl exec -- spacewalk-service restart

    Let's Encrypt works but note the 90 day lifetime. Automate the renewal and the mgr-ssl-cert-setup re-run together, or you will discover the expiry the hard way when clients stop checking in.

    Step 8: Bootstrap clients

    Create an activation key first, under Systems, Activation Keys. It bundles the base channel, child channels, system groups, and configuration channels a new client should get.

    The modern path is a Salt minion. Uyuni ships venv-salt-minion, a bundled Salt that avoids fighting the distro's own Salt packages.

    From the UI: Systems, Bootstrapping. Enter the client's hostname, SSH credentials, and the activation key. Uyuni pushes the bootstrap script over SSH.

    From the client side, for a Debian or Ubuntu target:

    shell
    wget -qO - https://download.opensuse.org/repositories/systemsmanagement:/Uyuni:/Stable:/Ubuntu2404-Uyuni-Client-Tools/xUbuntu_24.04/Release.key | gpg --dearmor | tee /usr/share/keyrings/uyuni-client.gpg > /dev/null
    
    echo "deb [signed-by=/usr/share/keyrings/uyuni-client.gpg] https://download.opensuse.org/repositories/systemsmanagement:/Uyuni:/Stable:/Ubuntu2404-Uyuni-Client-Tools/xUbuntu_24.04/ ./" \
      > /etc/apt/sources.list.d/uyuni-client-tools.list
    
    apt update && apt install -y venv-salt-minion

    Configure it:

    shell
    cat > /etc/venv-salt-minion/minion.d/uyuni.conf <<'EOF'
    master: uyuni.example.com
    server_id_use_crc: adler32
    enable_legacy_startup_events: False
    enable_fqdns_grains: False
    grains:
      susemanager:
        activation_key: "1-my-activation-key"
    EOF
    
    systemctl enable --now venv-salt-minion

    Accept the key on the server:

    shell
    mgrctl exec -- salt-key -L
    mgrctl exec -- salt-key -A

    The client shows up under Systems within a minute.

    Re-registering a client that was previously registered elsewhere needs a cleanup first, or the old minion ID sticks:

    shell
    systemctl stop venv-salt-minion
    rm -f /etc/salt/minion_id
    rm -rf /var/cache/venv-salt-minion/minion
    rm -f /etc/venv-salt-minion/minion.d/*
    systemctl start venv-salt-minion

    Salt SSH is the alternative for hosts where you cannot or will not install an agent. It is slower and supports fewer features, but it works.

    Step 9: Actually use it

    Patch management. Systems, System Set Manager, select hosts, Patches. Apply errata across a group in one action. Bulk product migration through SSM landed in 2025.10 if you need to move a group of clients across a major version.

    Configuration management. Configuration channels hold files with target paths, permissions, and ownership. Assign to systems or groups, deploy on a schedule.

    Ansible. Uyuni runs playbooks against registered systems. RBAC and Ansible integration both saw work in 2026.01. Point it at an existing playbook repo rather than rewriting your automation in Salt states if that is what you already have.

    OpenSCAP. Enhanced SCAP auditing integration arrived in 2026.04 as a technology preview. Schedule scans and read results in the UI.

    Monitoring. Prometheus exporters on clients, scraped by an external Prometheus. Note that as of 2026.03 the monitoring server packages in the SLES 12 client tools channels are gone. Exporters remain, so SLES 12 clients can still be monitored, but they cannot be the monitoring server anymore. A reporting dashboard for Grafana shipped in 2026.04.

    Backups

    shell
    mgradm backup create /var/backups/uyuni

    Online database backup management arrived in 2026.04, which means you can back up without stopping the service. Back up the volumes and the database both. The channel content is re-syncable and does not strictly need backing up, but restoring 400 GB of mirrored packages over the wire is a bad afternoon.

    Upgrades

    shell
    mgradm upgrade podman

    Read the release notes first. Every time. The Uyuni project routinely ships upgrades with hard prerequisites:

    • Upgrading to 2026.01 requires being on 2025.05 or later first, because of the PostgreSQL 18 upgrade.
    • 2025.10 changed the validated host OS from Leap Micro 5.5 to Tumbleweed and documents a migration path for the host itself.
    • 2026.06 introduced the strict CA Basic Constraints validation described above.

    Skipping releases in this project is not a mild inconvenience. It is a rebuild.

    Troubleshooting

    Setup fails or the container will not start. Check disk first, always:

    shell
    df -h
    mgradm status
    podman ps -a

    Web UI unreachable after install. Check the services inside the container:

    shell
    mgrctl exec -- spacewalk-service status
    mgrctl logs --tail 100

    Clients register but never get patches. Almost always DNS or channel assignment. Verify the client resolves the server FQDN, then check the base channel is assigned and synced. An unsynced channel produces a client that looks healthy and has nothing to install.

    Salt minion will not connect. Confirm the minion's FQDN resolves from the server side and that 4505 and 4506 are reachable. Then check the key state:

    shell
    mgrctl exec -- salt-key -L

    An unaccepted key sits in Unaccepted Keys and the client just waits forever.

    Repo sync fails partway. Read the per-channel log under /var/log/rhn/reposync/ inside the container. Out of space and upstream GPG key problems are the two usual causes.

    Everything is slow. Check RAM. The 16 GB floor is a floor, not a suggestion, and PostgreSQL plus the Java application plus Salt plus Cobbler in containers will use it.

    Where this fits

    The three guides in this series solve different problems and stack cleanly:

    • osquery gives you a SQL interface to one host.
    • Fleet centralizes osquery across many hosts and adds live queries, inventory, and vulnerability reporting.
    • Uyuni goes further and actually changes state: patches, configuration, provisioning, and channel control across a mixed Linux fleet.

    Fleet tells you a host is missing a patch. Uyuni installs it. Running both is a reasonable architecture if you can afford the resources, and plenty of shops do.