There are four ways to put openSUSE Leap Immutable on a machine, and they don’t behave the same once you log in. One gives you a sudo that wants your own password, another wants root’s. One splits /var onto its own partition, another keeps it inside the root filesystem. It pays to know which one you are getting before you pick.
Leap Immutable is the read-only, transactional mode of openSUSE Leap, and it’s the replacement for Leap Micro (the how-it-works explainer covers why). This guide walks you through every install route we tested: the Agama installer in Immutable mode, an unattended Agama install from a JSON profile, the self-install USB image, and the qcow2 appliance on Proxmox or KVM. You’ll also get the jeos-firstboot wizard screen by screen, including the SSH key trick that trips people up.
Pick the method that fits your machine
The table sums it up. Each row is a real install we did on the same Proxmox host, with the same 2 vCPU and 4 GB RAM VM.
| Method | Best for | You download | First-boot setup | sudo asks for | /var |
|---|---|---|---|---|---|
| Agama, Immutable mode | Bare metal and VMs where you want to choose disks, encryption and users up front | Agama installer ISO (about 740 MiB) | Done in the installer | Your own password | Separate btrfs partition |
| Agama with a JSON profile | Building several identical nodes | Same ISO plus a small JSON file | Done by the profile | Your own password | Separate btrfs partition |
| Self-install image | Mini PCs, edge boxes, anything you can boot from a USB stick | SelfInstall.iso (about 1.5 GiB) | jeos-firstboot wizard | root’s password | Subvolume on the root partition |
| qcow2 appliance | Proxmox, KVM and libvirt hosts | Base-qcow.qcow2 (about 1.3 GiB) | jeos-firstboot, or Combustion/Ignition | root’s password | Subvolume on the root partition |
If you’re unsure, start with Agama. It’s the friendliest, and it sets up sudo the way most people expect. Pick the qcow2 image if you live in Proxmox, because it boots in under a minute.
What you need before you start
The requirements are small, but one of them catches people on older hardware.
- An x86-64-v2 CPU. On Proxmox, the web UI’s default CPU type for new VMs (
x86-64-v2-AES) is fine, and so ishost. VMs created withqm createand no--cpugetkvm64, and with that model the kernel panics about a second into boot. - UEFI firmware. Every install here used OVMF on Proxmox.
- At least 2 GB of RAM (we used 4 GB) and a 40 GB disk, which is what openSUSE recommends and what every install here used. Agama splits the disk roughly in half between
/and/var, so go bigger if you plan to run a lot of containers. - Network access during the install if you use the Agama ISO. It pulls packages from the openSUSE mirrors.
Every download lives on download.opensuse.org. Grab the matching checksum file too (.sha256 for the files used here), because you’ll check it before you write anything to a disk.
Install with Agama in Immutable mode
Agama is the installer for Leap, and Immutable mode is a switch inside it, not a separate download. If you’ve used Agama for a normal Leap install, the Agama installer walkthrough will feel familiar. Only a few screens change.
Download and verify the ISO
Fetch the online installer ISO and its checksum:
curl -LO https://download.opensuse.org/distribution/leap/16.1/installer/iso/agama-installer.x86_64-Leap_16.1.iso
curl -LO https://download.opensuse.org/distribution/leap/16.1/installer/iso/agama-installer.x86_64-Leap_16.1.iso.sha256
Then check it. You want to see OK:
sha256sum -c agama-installer.x86_64-Leap_16.1.iso.sha256
Our download matched:
agama-installer.x86_64-Leap_16.1.iso: OK
The openSUSE download page links the same online installer under another name, Leap-16.1-online-installer-x86_64.install.iso in distribution/leap/16.1/offline/. Either file works. That folder also has a larger offline ISO (about 4.3 GiB) for machines with no internet during the install. Its checksums are .sha512 files, so check those with sha512sum -c. To make a USB stick from either ISO, follow the steps in creating a bootable USB on Linux or macOS.
Boot it and set a password for remote access
Boot the ISO and you’ll land on this menu:

Here’s a step most guides skip. Agama runs a web UI, and you can drive the whole install from your laptop’s browser instead of the server’s small console. That needs a root password for the installer itself, and the live system doesn’t have a known one. Press p on the boot menu and type a password twice:

This password only exists in the installer’s RAM. It does not end up on the installed system. Press Enter on Install Leap 16.1 and wait about a minute.
Open the installer from your browser
The console shows the installer’s IP address. Open https://10.0.1.50 (use your own IP) in a browser, accept the self-signed certificate warning, and log in as root with the password you just set:

If you skip the p step, you’ll see “Could not log in” here no matter what you type. Just use the console instead, or reboot and set the password.
Choose Immutable mode
This is the screen that matters. Select Leap 16.1, and two modes appear: Standard and Immutable. Pick Immutable, tick the license box and click Select Leap 16.1:

You cannot switch modes after the install. If you pick Standard by mistake, you’ll get a regular read-write Leap system, and the only fix is to reinstall.
Check the storage plan
Agama now shows an overview. Open Storage before you change anything else. In Immutable mode it creates three partitions: a 512 MiB EFI partition, one btrfs partition for / and a second btrfs partition for /var:

On our 40 GB disk that was 19.75 GiB each. The split exists because /var holds everything that changes (container images, logs, databases), while / holds read-only snapshots. Keeping them apart means a container pulling a few gigabytes of images can’t starve the snapshots. The Encryption tab is where you’d turn on disk encryption; part 8 of this series covers TPM2 unlocking in detail.
Leave the software alone
The software page starts with no desktop and four patterns already chosen (base system, SELinux, software management and man pages):

That’s the right starting point for a server. You’ll add packages later with transactional-update, and piling them on now only slows the install.
Create your admin user
Under Authentication, tick Define an administrator user and fill in the name, username and password. You can paste an SSH public key here too:

The description is worth reading: this user “can run administrator commands using sudo”. Agama puts it in the wheel group and ships a sudo rule for that group. Root stays locked, which is what you want on a server.
Under System, switch the hostname from Transient to Static and give the machine a name. Without that, it takes whatever name DHCP hands out. We used leap-vm and set the time zone to UTC under Language and region. The overview now shows everything you chose:

Install and reboot
Click Install now. Agama warns that no desktop is selected. For a server, that’s exactly right:

Click Confirm and install. Our install worked through 1,482 steps and took about six and a half minutes on a home internet connection:

When it’s done, click Reboot and remove the ISO or USB stick:

Check what you got
Log in over SSH as your new user and run a few checks:
findmnt -n -o SOURCE,OPTIONS / | cut -d, -f1-2
findmnt -n -o SOURCE /var
lsblk -o NAME,SIZE,FSTYPE /dev/sda
id "$USER"
The root filesystem is a read-only snapshot, /var is its own partition, and the user is in wheel:

The sudo rule lives in /usr/etc/sudoers.d/50-wheel-auth-self. It tells sudo to ask members of wheel for their own password instead of root’s. The image-based methods below do not ship it.
One more surprise: this install has 738 packages but no Podman. The appliance images include it, but Agama’s Immutable mode does not. Adding it is your first transactional-update:
sudo transactional-update --non-interactive pkg install podman
The package goes into a new snapshot, not the running system:
New default snapshot is #2 (/.snapshots/2/snapshot).
Transaction completed.
Please reboot your machine to activate the changes and avoid data loss.
Reboot, and podman --version answers from the new snapshot. If the snapshot idea is new to you, part 4 of this series goes through every transactional-update command, and the zypper cheat sheet helps with package names.
Automate Agama with a JSON profile
Clicking through Agama is fine for one machine. For three or ten, you’ll want the same answers every time. Agama has a command-line client, and it can load your choices from a JSON file. This is the flow we tested end to end.
Boot the ISO, set the installer password with p as before, and note the IP. Then, on a Linux workstation, generate a password hash for your user. Pick your own password:
export INSTALLER_IP="10.0.1.50"
export HASH=$(openssl passwd -6 'ChangeMe2026')
echo "${HASH}"
The output must start with $6$. On a Mac it won’t: the built-in /usr/bin/openssl is LibreSSL, which rejects -6 with unknown option '-6' and leaves HASH empty. Install OpenSSL from Homebrew and call "$(brew --prefix openssl@3)"/bin/openssl passwd -6 instead. We checked both. Mac users also need sed -i '' in place of sed -i in the sed step below, because BSD sed wants a backup suffix there.
Create the profile:
vim leap-immutable.json
Paste this. The "mode": "immutable" line is the one that makes it an immutable install:
{
"product": {
"id": "openSUSE_Leap",
"mode": "immutable"
},
"hostname": {
"static": "leap-node1"
},
"l10n": {
"timezone": "UTC"
},
"user": {
"fullName": "Lorna Chepkoech",
"userName": "lorna",
"password": "PASSWORD_HASH_HERE",
"hashedPassword": true
}
}
Swap the placeholder for your real hash. The hash contains $ and / characters, so the sed uses | as its separator:
sed -i "s|PASSWORD_HASH_HERE|${HASH}|" leap-immutable.json
Copy it to the installer and load it. Each command asks for the installer password you set with p. The first line clears any old host key for that IP, because every installer boot and every finished install brings new SSH host keys. On a workstation that has never used SSH, it complains that known_hosts doesn’t exist; that’s harmless:
ssh-keygen -R "${INSTALLER_IP}"
ssh root@"${INSTALLER_IP}" 'cat > /root/leap-immutable.json' < leap-immutable.json
ssh root@"${INSTALLER_IP}" agama config load /root/leap-immutable.json
Agama re-reads its settings and ends with zero open issues:
stage: Configuring, active tasks: 1, progresses: 0, issues: 0, questions: 0
stage: Configuring, active tasks: 0, progresses: 0, issues: 0, questions: 0
If the issue count stays above zero, run agama config show on the installer and compare it with your file. Once it’s clean, start the install and let Agama reboot into the new system when it finishes:
ssh root@"${INSTALLER_IP}" agama install
ssh root@"${INSTALLER_IP}" agama finish
agama install waits until the install is done. Ours took 3 minutes 14 seconds, faster than the clicked install because nothing was waiting on us. After agama finish the machine came back on the same DHCP address as leap-node1, with a read-only root. Its host key is new again, so clear it once more before you log in with the password behind the hash:
ssh-keygen -R "${INSTALLER_IP}"
ssh lorna@"${INSTALLER_IP}"
Storage and software use the same defaults you saw in the web UI. Once you know the click-through result is what you want, the profile gives you that result every time.
Not sure what a key is called? Set it once in the web UI, then run agama config show on the installer. It prints your choices as JSON, which is how we checked the format of the file above. The full list of keys is in the Agama profile reference.
Install from the self-install USB image
The self-install image is the route for physical boxes like mini PCs and edge devices. It’s an ISO with the finished system packed inside. You write it to a USB stick, boot the machine from the stick, and it copies the system onto the internal disk. There are no packages to download and no questions beyond one confirmation.
Download it on any Linux machine and check it:
curl -LO https://download.opensuse.org/distribution/leap/16.1/appliances/iso/Leap-16.1-Immutable.x86_64-Base-SelfInstall.iso
curl -LO https://download.opensuse.org/distribution/leap/16.1/appliances/iso/Leap-16.1-Immutable.x86_64-Base-SelfInstall.iso.sha256
sha256sum -c Leap-16.1-Immutable.x86_64-Base-SelfInstall.iso.sha256
Plug in the stick and find its device name. Look at the size, model and the usb transport, and don’t guess, because the next command wipes it:
lsblk -d -o NAME,SIZE,MODEL,TRAN
Set it once, then write the ISO. A 2 GB stick is enough:
export USB_DISK=/dev/sdb
sudo dd if=Leap-16.1-Immutable.x86_64-Base-SelfInstall.iso of="${USB_DISK}" bs=4M conv=fsync status=progress
On a Mac, the bootable USB guide covers the same step. Now boot the target machine from the stick. The menu has an install entry, a failsafe one and Boot from Hard Disk:

Pick Install Leap 16.1. Our VM had a single internal disk, so the installer went straight to the only question it asks:

Read the device path before you answer. Yes is already selected, so pressing Enter wipes that disk. On a machine with more than one disk, a Select Installation Disk list comes first. We added a second, smaller disk and booted the stick again to see it:

The first disk is highlighted, and OK takes whichever line is highlighted, so move to the right one first. The sizes are your best clue to which disk is which. Once you confirm, the installer writes the image:

On our 40 GB virtual disk the copy finished in well under a minute. The machine rebooted from the internal disk, grew the root partition to fill it, and was at the jeos-firstboot welcome screen less than two minutes after we confirmed. We checked the disk afterwards: a 512 MiB EFI partition and a 39.5 GiB btrfs root, with /var as a subvolume inside it.
Pull the stick out once the copy finishes. If your firmware boots USB first and the menu shows up again, choose Boot from Hard Disk, not Install. jeos-firstboot comes up next, and the section after the qcow2 method walks through it.
Skip the installer: write the raw image straight to the disk
The parent folder, distribution/leap/16.1/appliances/, has SelfInstall.raw.xz. That’s the disk image the ISO carries, without the installer around it. It doesn’t install anything: whatever disk you write it to becomes the system. We booted it from a second disk and again as a USB storage device, and both times it ran from that device while the internal disk stayed empty.
That’s handy when a live Linux system is already running on the box, for example a rescue system on a rented server. Boot any live USB that has xz and dd, download and check the image, find the internal disk with lsblk as above, and write it there:
curl -LO https://download.opensuse.org/distribution/leap/16.1/appliances/Leap-16.1-Immutable.x86_64-Base-SelfInstall.raw.xz
curl -LO https://download.opensuse.org/distribution/leap/16.1/appliances/Leap-16.1-Immutable.x86_64-Base-SelfInstall.raw.xz.sha256
sha256sum -c Leap-16.1-Immutable.x86_64-Base-SelfInstall.raw.xz.sha256
export TARGET_DISK=/dev/nvme0n1
xzcat Leap-16.1-Immutable.x86_64-Base-SelfInstall.raw.xz | sudo dd of="${TARGET_DISK}" bs=4M conv=fsync status=progress
Writing to our 40 GB disk took 24 seconds. Shut down, remove the live USB and boot. On first boot the root partition grows to fill the disk, the same as with the ISO:

You’ll also see a SelfInstall .tar file next to the raw image, with a build number in its name. That’s a PXE kit (kernel, initrd and boot options) for network installs, not something you write to a stick.
Run the qcow2 image on Proxmox or KVM
If you live in a hypervisor, this is the quickest route. The qcow2 appliance has a 32 GiB virtual disk with 1.32 GiB of real data, and it reached the jeos-firstboot welcome screen 31 seconds after qm start. These are the exact Proxmox steps we used. Run them as root on the Proxmox node, and change the VM ID and storage to suit your setup:
export VMID=9101
export STORAGE=local-lvm
curl -LO https://download.opensuse.org/distribution/leap/16.1/appliances/Leap-16.1-Immutable.x86_64-Base-qcow.qcow2
curl -LO https://download.opensuse.org/distribution/leap/16.1/appliances/Leap-16.1-Immutable.x86_64-Base-qcow.qcow2.sha256
sha256sum -c Leap-16.1-Immutable.x86_64-Base-qcow.qcow2.sha256
Create an empty UEFI VM with the CPU type set to host:
qm create "${VMID}" --name leap-immutable --machine q35 --bios ovmf --cpu host \
--cores 2 --memory 4096 --net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-single \
--agent enabled=1 --ostype l26 --efidisk0 "${STORAGE}":1,efitype=4m,pre-enrolled-keys=0
Import the image as a disk:
qm importdisk "${VMID}" Leap-16.1-Immutable.x86_64-Base-qcow.qcow2 "${STORAGE}"
The last line names the new disk. On our ZFS storage it looked like this:
unused0: successfully imported disk 'zfs-pool:vm-3107-disk-1'
The disk is now listed as unused0 in the VM config. Its exact name depends on the storage type, so read it from the config instead of typing it. Attach it, then set the boot order in a separate command:
export DISK=$(qm config "${VMID}" | awk '/^unused0:/ {print $2}')
qm set "${VMID}" --scsi0 "${DISK}",discard=on,ssd=1
qm set "${VMID}" --boot order=scsi0
qm start "${VMID}"
That separate --boot line matters. Without it, OVMF tries network boot first, and you’ll stare at PXE timeouts for about two minutes before anything happens. Also don’t ask qm resize for anything below 32G. Proxmox refuses with “shrinking disks is not supported”, because the image is already 32 GiB.
With no configuration attached, the VM goes straight to jeos-firstboot. If you’d rather skip the wizard and have users, SSH keys and packages set up automatically, attach a Combustion or Ignition config instead. Part 3 of this series rebuilds the same node three times that way.
Get through jeos-firstboot
Both image methods end here. The wizard is short, but two of its screens behave in ways you won’t expect. It starts with a welcome screen:

Press Enter, then accept the keyboard layout, the license and the time zone (UTC is at the top of the list). Next it asks for a root password, twice. If the password contains the word “root”, you’ll see BAD PASSWORD: The password contains the user name in some form flash by later. It’s only a warning, and the password still gets set.
Enroll your SSH key over the network
Then comes the part that trips people up. The wizard asks whether you want to enroll SSH keys:

Say Yes, and it shows its IP address and host key fingerprints:

Now go to your workstation and SSH to that address as root, with your normal key loaded. No password is involved. The server reads the public key your client offers and hands it back to the wizard:
ssh [email protected]
Your terminal prints this and disconnects:
ssh-pairing: Received 1 public keys
Received disconnect from 10.0.1.51 port 22:11: Bye Bye
Back on the console, the wizard asks whether that message appeared. Look closely: No is selected by default.

If you just hit Enter out of habit, it throws your key away. Press the left arrow to select Yes, then confirm the key fingerprint on the next screen the same way. It says “Imported 1 keys”, and root can now log in with that key.
Create a user
The last screen creates a regular user. The wizard notes that you need one for password-based SSH login and for Cockpit:

Leave Groups empty. There’s no wheel group on these images, which is also why old Leap Micro Combustion scripts that run useradd -G wheel fail here (part 1 of this series shows that failure).
After that, the console shows the login prompt and the IP address. Two things are different from an Agama install, and both are easy to fix.
First, sudo asks for root’s password, not yours. The images use SUSE’s classic Defaults targetpw rule, and they don’t include the wheel drop-in that Agama installs:

Type the root password from the wizard and it works. Second, the hostname is localhost, because the wizard never asks for one. /etc is writable, so set it like on any Linux box, giving sudo the root password when it asks. The name survives a reboot:
sudo hostnamectl set-hostname leap-node2
If you would rather use your own password, as on an Agama install, create the wheel group, add your user to it, and give the group the same two-line rule Agama ships. We ran this on the self-installed VM, and afterwards sudo took lorna‘s own password. Replace lorna with your username:
sudo groupadd -r wheel
sudo usermod -aG wheel lorna
echo -e 'Defaults:%wheel !targetpw\n%wheel ALL = (root) ALL' | sudo tee /etc/sudoers.d/50-wheel-auth-self
sudo chmod 440 /etc/sudoers.d/50-wheel-auth-self
sudo visudo -cf /etc/sudoers.d/50-wheel-auth-self
The last line must say parsed OK. A typo in a sudoers file can lock you out of sudo; if that happens, su - with the root password still gets you in to fix it. Log out and back in so the new group applies. Everything here lives in /etc, so no reboot or snapshot is needed.
Leap Micro 6.2: the same methods with older images
If you still need Leap Micro 6.2 for existing machines, the image methods carry over. The files live under distribution/leap-micro/6.2/appliances/ and start with openSUSE-Leap-Micro.x86_64. Two differences matter when you pick a file. 6.2 has Default images alongside Base, while every x86_64 Immutable image for 16.1 is a Base variant (with RT, encrypted and VMware flavours). And 6.2 images do have a wheel group (gid 497 on our 6.2 VM), so old scripts that use it keep working there. There’s no Agama Immutable mode for 6.2, because that mode is part of Leap 16.1 itself. Plan new machines on Leap Immutable, and when you’re ready to move the old ones, part 9 of this series runs the migration tool on a live Leap Micro 6.2 box.
When first boot goes sideways
These are the errors we actually hit while testing, with the fix for each.
“ssh-pairing-server exited with 1: Session did not complete until keyboard-interactive”

The SSH client never reached the keyboard-interactive step, so the wizard got no key. We caused it by connecting with ssh -o BatchMode=yes, which turns that step off. Connect with a normal interactive ssh root@IP from a real terminal. The wizard then asks “No keys enrolled. Try again?”, and you can say Yes.
“[sudo] password for root:” rejects your password
You installed from an image, so sudo wants the root password you set in jeos-firstboot, not your user’s. Use that, or add the wheel rule from the previous section.
“Could not log in” in the Agama web UI
The live installer has no root password you know. Reboot the ISO, press p at the boot menu, set one, and log in with it. On our build the message spelled it “passsword”, with three s’s, so don’t let that throw you.
The VM sits on PXE boot for minutes
The Proxmox boot order still lists the network card first. Run qm set "${VMID}" --boot order=scsi0 as its own command, then reset the VM.
“Kernel panic – not syncing: Attempted to kill init! exitcode=0x00007f00”
Check the CPU type first. We got this panic about a second into boot when the qcow2 VM used the kvm64 CPU model that qm create picks when you don’t pass --cpu, which lacks the x86-64-v2 instructions Leap 16.1 is built for. Switching the same VM to --cpu host fixed it:

Run qm set "${VMID}" --cpu host and start the VM again. In a cluster with mixed CPU generations, use x86-64-v2-AES instead, because host blocks live migration between different CPUs. On physical hardware this isn’t a concern, since any x86 CPU from roughly the last decade supports x86-64-v2.
Once you’re logged in, the Cockpit web console is a nice next step if you like a browser view of the system. For the bigger picture of how snapshots and rollback work, see the Snapper rollback guide, and if you’d rather run a regular read-write system, there’s the standard Leap install guide.