<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Machinestops</id>
	<title>Alpine Linux - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Machinestops"/>
	<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/wiki/Special:Contributions/Machinestops"/>
	<updated>2026-04-26T18:04:13Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Bootloaders&amp;diff=23629</id>
		<title>Bootloaders</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Bootloaders&amp;diff=23629"/>
		<updated>2023-05-31T16:14:41Z</updated>

		<summary type="html">&lt;p&gt;Machinestops: /* rEFIind */ Spelling mistake fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
This page shows the basic steps you need to perform, if you for any reason want to switch bootloaders or apply some manual configuration.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;rEFInd&amp;lt;/code&amp;gt; is an easy to use EFI boot menu that allows booting different operating systems.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Syslinux&amp;lt;/code&amp;gt; is the default light-weight bootloader used in Alpine.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;Grub&amp;lt;/code&amp;gt; is a standard linux boot loader.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;EFI Boot Stub&amp;lt;/code&amp;gt; allows booting linux directly from a motherboard supporting UEFI or another bootloader.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= rEFIind =&lt;br /&gt;
&lt;br /&gt;
For (U)EFI systems, the &amp;lt;code&amp;gt;refind&amp;lt;/code&amp;gt; package can provide a graphical EFI boot menu that allows to boot operating systems that are found on the available partitions.&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;code&amp;gt;refind&amp;lt;/code&amp;gt; is not yet available in the used alpine release, it may be installed in another dual/multi-booted linux distribution.&lt;br /&gt;
&lt;br /&gt;
For example, with a Debian based distribution, it can be installed to the EFI partition like this:&lt;br /&gt;
 &lt;br /&gt;
 apt install refind             # installs the debian package&lt;br /&gt;
 refind-install --alldrivers    # installs refind to the EFI partition&lt;br /&gt;
&lt;br /&gt;
(The --alldrivers option includes all filesystem drivers instead of only the one needed to load the currently running kernel, to allow finding and booting operating systems from more partitions.)&lt;br /&gt;
&lt;br /&gt;
And a first (default) boot menu line needs to be configured with Alpine&#039;s default boot parameters. Assuming the bootable partition is mounted at &amp;lt;code&amp;gt;/media/sdXY&amp;lt;/code&amp;gt; it can be done like this (at time of writing):&lt;br /&gt;
 echo &#039;&amp;quot;Alpine&amp;quot; &amp;quot;modules=loop,squashfs,sd-mod,usb-storage quiet initrd=\boot\intel-ucode.img initrd=\boot\amd-ucode.img initrd=\boot\initramfs-lts&amp;quot;&#039; &amp;gt; /media/sdXY/boot/refind_linux.conf&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
&lt;br /&gt;
# At the time of writing, it was still needed to use backslashes in the .conf file. &lt;br /&gt;
# The path in the config file needs to be relative to the partition that the kernel resides on. If &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt; resides on its own separate partition, then &amp;lt;code&amp;gt;\boot&amp;lt;/code&amp;gt; needs to be removed from the paths.                                                                                               }}&lt;br /&gt;
&lt;br /&gt;
= Installing Syslinux =&lt;br /&gt;
&lt;br /&gt;
If you want to switch from another bootloader back to Syslinux, or if you for some reason want to install Syslinux manually, the following steps are required.&lt;br /&gt;
&lt;br /&gt;
Install the &amp;lt;code&amp;gt;syslinux&amp;lt;/code&amp;gt; package:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apk add syslinux&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you&#039;re using GPT partitions, install the GPT MBR onto the drive you want to install the bootloader on (in this case &amp;lt;code&amp;gt;/dev/sda&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;dd bs=440 count=1 conv=notrunc if=/usr/share/syslinux/gptmbr.bin of=/dev/sda&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or if you&#039;re using DOS partitions, install the DOS MBR instead:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;dd bs=440 count=1 conv=notrunc if=/usr/share/syslinux/mbr.bin of=/dev/sda&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- See also: http://www.syslinux.org/wiki/index.php?title=Mbr --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next install the required Syslinux binaries. Despite being called &amp;lt;code&amp;gt;extlinux&amp;lt;/code&amp;gt;, Syslinux supports booting from FAT12/16/32, NTFS, ext2/3/4, [[Btrfs|btrfs]], XFS, and UFS/FFS filesystems.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;extlinux --install /boot&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The configuration file is located in &amp;lt;code&amp;gt;/boot/extlinux.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
Alpine ships with a script called &amp;lt;code&amp;gt;update-extlinux&amp;lt;/code&amp;gt; which automatically (re)generates this file, for example on updates to Syslinux.&lt;br /&gt;
The settings for this script can be found in &amp;lt;code&amp;gt;/etc/update-extlinux.conf&amp;lt;/code&amp;gt;, including the option to disable automatic overwriting of &amp;lt;code&amp;gt;/boot/extlinux.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
You can also place additional menu entries in the &amp;lt;code&amp;gt;/etc/update-extlinux.d/&amp;lt;/code&amp;gt; directory, e.g. for dual booting.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== EFI ===&lt;br /&gt;
&lt;br /&gt;
{{Todo|Work in progress. This should at least get you started.}}&lt;br /&gt;
&lt;br /&gt;
Assuming &amp;lt;code&amp;gt;/mnt&amp;lt;/code&amp;gt; is a FAT32 partition of type EF00 and &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt; belongs to the rootfs created after running &amp;lt;code&amp;gt;setup-disk&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
mkdir -p /mnt/EFI/syslinux&lt;br /&gt;
cp /usr/share/syslinux/efi64/* /mnt/EFI/syslinux/&lt;br /&gt;
cp /boot/extlinux.conf /mnt/EFI/syslinux/syslinux.cfg&lt;br /&gt;
cp /boot/vmlinuz* /mnt/&lt;br /&gt;
cp /boot/initramfs* /mnt/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may need to modify &amp;lt;code&amp;gt;/mnt/EFI/syslinux/syslinux.cfg&amp;lt;/code&amp;gt; to change the paths to absolute paths (just add a / in front of the vmlinuz/initramfs entries),&lt;br /&gt;
or copy the files to &amp;lt;code&amp;gt;/mnt/EFI/syslinux&amp;lt;/code&amp;gt; instead (XXX: untested).&lt;br /&gt;
&lt;br /&gt;
= GRUB =&lt;br /&gt;
&lt;br /&gt;
To install GRUB in BIOS mode, (optionally) remove the Syslinux package and install the required GRUB packages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apk del syslinux&lt;br /&gt;
apk add grub grub-bios&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For EFI, install Grub&#039;s EFI package instead. Note that &amp;lt;code&amp;gt;/boot&amp;lt;/code&amp;gt; has to be an EFI compatible filesystem like FAT32.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;apk add grub-efi&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Next install the MBR and GRUB binaries to disk for BIOS mode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;grub-install /dev/vda&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For EFI mode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;grub-install --target=x86_64-efi --efi-directory=/boot&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
GRUB ships with an automatic config generator, including some automatic detection of other operating systems installed on the device:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;grub-mkconfig -o /boot/grub/grub.cfg&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script can be configured via the &amp;lt;code&amp;gt;/etc/default/grub&amp;lt;/code&amp;gt; file.&lt;br /&gt;
See [https://www.gnu.org/software/grub/manual/html_node/Simple-configuration.html] for a list of available options.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= EFI Boot Stub =&lt;br /&gt;
&lt;br /&gt;
To boot directly from your motherboard&#039;s UEFI boot menu, a boot entry needs&lt;br /&gt;
to be created with either a UEFI shell or &#039;&#039;efibootmgr&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== efibootmgr ==&lt;br /&gt;
&lt;br /&gt;
Install efibootmgr:&lt;br /&gt;
&amp;lt;pre&amp;gt;apk add efibootmgr&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a boot entry. It&#039;s recommended to do this in a script, as efibootmgr&lt;br /&gt;
does not allow editing entries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
params=&amp;quot;root=/dev/sdXZ rw \&lt;br /&gt;
  initrd=\intel-ucode.img \&lt;br /&gt;
  initrd=\initramfs-lts&amp;quot;&lt;br /&gt;
&lt;br /&gt;
efibootmgr --create --label &amp;quot;Alpine Linux&amp;quot; \&lt;br /&gt;
  --disk /dev/sdX --part Y \&lt;br /&gt;
  --loader /vmlinuz-lts \&lt;br /&gt;
  --unicode &amp;quot;${params}&amp;quot; \&lt;br /&gt;
  --verbose&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;code&amp;gt;/dev/sdXY&amp;lt;/code&amp;gt; contains the EFI partition and &amp;lt;code&amp;gt;/dev/sdXZ&amp;lt;/code&amp;gt; contains the root partition. If you are using {{Pkg|linux-edge}}, replace &amp;lt;code&amp;gt;lts&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;edge&amp;lt;/code&amp;gt; in the script&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
The kernel contains the [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/init/do_mounts.c#n254 exhaustive list] of ways to specify the block device. For a more robust boot entry, it is recommended to use a persistent name such as the PARTUUID.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Optionally, set the newly created entry as the default:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;efibootmgr -n XXXX&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where &amp;lt;code&amp;gt;XXXX&amp;lt;/code&amp;gt; is the boot number of the new entry.&lt;br /&gt;
&lt;br /&gt;
{{Note|&lt;br /&gt;
The loader and initrd file arguments are relative to the EFI partition. In a default installation, alpine places these files in &amp;lt;code&amp;gt;/boot/&amp;lt;/code&amp;gt;, while EFI is mounted to &amp;lt;code&amp;gt;/boot/efi/&amp;lt;/code&amp;gt;. You can either update fstab to mount EFI at &amp;lt;code&amp;gt;/boot/&amp;lt;/code&amp;gt;, or manually copy them to &amp;lt;code&amp;gt;/boot/efi/&amp;lt;/code&amp;gt;.                                                                                           }}&lt;br /&gt;
&lt;br /&gt;
= Using a UKI (UEFI only) =&lt;br /&gt;
&lt;br /&gt;
It is possible to boot directly into a &#039;&#039;&#039;Unified Kernel Image&#039;&#039;&#039; (UKI). A UKI is a single file which contains the initfs, kernel and cmdline. While this is typically done in order to enable [https://en.wikipedia.org/wiki/UEFI SecureBoot], it is perfectly feasible to skip enrolling the custom keys and leave SecureBoot off.&lt;br /&gt;
&lt;br /&gt;
The page [[UEFI Secure Boot]] contains the instructions for setting an a UKI. Additionally, it is possible to install the UKI in the default fallback path used by most UEFI implementations. By installing the UKI into this path, the system will automatically boot into it if no other entries are defined. This can be automated as part of the kernel hook by adding the following to &amp;lt;code&amp;gt;/etc/kernel-hooks.d/secureboot.conf&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# For the edge kernel, install the UKI into the default UEFI path.&lt;br /&gt;
if [ &amp;quot;$1&amp;quot; == &amp;quot;edge&amp;quot; ]; then&lt;br /&gt;
  output_dir=&amp;quot;/efi/EFI/Boot/&amp;quot;&lt;br /&gt;
  output_name=&amp;quot;bootx64.efi&amp;quot;&lt;br /&gt;
fi&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;bootx64.efi&amp;lt;/code&amp;gt; is only correct for &amp;lt;code&amp;gt;x86_64&amp;lt;/code&amp;gt; systems. For other architectures the exact name will vary.&lt;br /&gt;
&lt;br /&gt;
= External Links =&lt;br /&gt;
* [https://www.denx.de/wiki/U-Boot/ReleaseCycle U-Boot Release Cycle]&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
[[Category:Booting]]&lt;/div&gt;</summary>
		<author><name>Machinestops</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Immutable_root_with_atomic_upgrades&amp;diff=23628</id>
		<title>Talk:Immutable root with atomic upgrades</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Immutable_root_with_atomic_upgrades&amp;diff=23628"/>
		<updated>2023-05-31T16:10:36Z</updated>

		<summary type="html">&lt;p&gt;Machinestops: /* System mutation scripts */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Sb1]], regarding diskless mode note: thanks for reminding about it, but it&#039;s a different setup with its own features, so I reduced the note, but left the links. Similar guide to diskless chroot setup would be really appreciated btw. [[User:Mvsn|Mvsn]] ([[User talk:Mvsn|talk]]) 23:04, 31 May 2021 (UTC)&lt;br /&gt;
&lt;br /&gt;
== rEFInd ==&lt;br /&gt;
&lt;br /&gt;
The rEFInd configuration provided in this does not appear to work universally, as rEFInd assumes that the &amp;lt;code&amp;gt;loader&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;initrd&amp;lt;/code&amp;gt; parameters in the MenuEntry are located within the ESP partition. To produce a bootable version of this setup, I had to move my kernel and my initramfs to the ESP partition.&lt;br /&gt;
&lt;br /&gt;
== System mutation scripts ==&lt;br /&gt;
&lt;br /&gt;
It might be helpful to note that &amp;lt;code&amp;gt;execline&amp;lt;/code&amp;gt; should be included in the list of packages installed while setting up the initial root snapshot, and also that the scripts provided should be downloaded (perhaps provide them as raw files somehow?). Without them, there is no way to modify the system other than manually mounting, creating an RW snapshot, and performing the link migration manually, which might prove bothersome for some (or unclear).&lt;br /&gt;
&lt;br /&gt;
Documenting the functionality of the scripts with comments might also be useful. The level of piping and nesting in these scripts makes it difficult to follow along for anyone unfamiliar with &amp;lt;code&amp;gt;execline&amp;lt;/code&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Machinestops</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Talk:Immutable_root_with_atomic_upgrades&amp;diff=23627</id>
		<title>Talk:Immutable root with atomic upgrades</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Talk:Immutable_root_with_atomic_upgrades&amp;diff=23627"/>
		<updated>2023-05-31T16:01:49Z</updated>

		<summary type="html">&lt;p&gt;Machinestops: /* rEFInd */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[User:Sb1]], regarding diskless mode note: thanks for reminding about it, but it&#039;s a different setup with its own features, so I reduced the note, but left the links. Similar guide to diskless chroot setup would be really appreciated btw. [[User:Mvsn|Mvsn]] ([[User talk:Mvsn|talk]]) 23:04, 31 May 2021 (UTC)&lt;br /&gt;
&lt;br /&gt;
== rEFInd ==&lt;br /&gt;
&lt;br /&gt;
The rEFInd configuration provided in this does not appear to work universally, as rEFInd assumes that the &amp;lt;code&amp;gt;loader&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;initrd&amp;lt;/code&amp;gt; parameters in the MenuEntry are located within the ESP partition. To produce a bootable version of this setup, I had to move my kernel and my initramfs to the ESP partition.&lt;/div&gt;</summary>
		<author><name>Machinestops</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Immutable_root_with_atomic_upgrades&amp;diff=23626</id>
		<title>Immutable root with atomic upgrades</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Immutable_root_with_atomic_upgrades&amp;diff=23626"/>
		<updated>2023-05-31T15:59:43Z</updated>

		<summary type="html">&lt;p&gt;Machinestops: Bluetooth persisting settings across reboots requires a mutable /var/lib/bluetooth. Introduce this alongside iwd.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== What? ===&lt;br /&gt;
This article provides a basic guide to setting up a read-only-root-based Alpine Linux system with several boot environments and atomic upgrades using rEFInd and [[BTRFS|btrfs]].&lt;br /&gt;
&lt;br /&gt;
=== Why? ===&lt;br /&gt;
Read-only root and atomic upgrades with ability to easily rollback or boot previous configurations is a concept that got some popularity recently. Distributions providing and promoting such features, for example, are [https://silverblue.fedoraproject.org/ Fedora Silverblue], [https://microos.opensuse.org/ Opensuse MicroOS], [https://nixos.org NixOS] and [https://guix.gnu.org GNU Guix].&lt;br /&gt;
&lt;br /&gt;
While Alpine Linux has it&#039;s killer features it lacks mentioned above ones on default setup. This is a proof of concept that it&#039;s possible to implement them in a minimal way on a minimal system.&lt;br /&gt;
&lt;br /&gt;
{{Note|Alpine Linux can also boot from RAM in &#039;&#039;&#039;diskless mode&#039;&#039;&#039; (see [[Installation]]) which supports preserving changes between reboots using [[lbu]].}}&lt;br /&gt;
&lt;br /&gt;
= Preparation =&lt;br /&gt;
You should have bootable Alpine media. The process to obtain it decribed on the [[Installation|installation page.]]&lt;br /&gt;
&lt;br /&gt;
= Partitioning disks =&lt;br /&gt;
In this guide it is assumed that you have a fresh UEFI system without OS and just managed to boot into live Alpine using USB flash drive or CD.&lt;br /&gt;
The first step is creating partition table on your HDD/SSD target device (&amp;lt;code&amp;gt;/dev/sda&amp;lt;/code&amp;gt; here):&lt;br /&gt;
&amp;lt;pre&amp;gt;# apk add gptfdisk&lt;br /&gt;
# gdisk /dev/sda&lt;br /&gt;
&amp;gt; o ↵&lt;br /&gt;
&amp;gt; y ↵&lt;br /&gt;
&amp;gt; w ↵&lt;br /&gt;
&amp;gt; y ↵&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now we can define the partitions:&lt;br /&gt;
&amp;lt;pre&amp;gt;# cgdisk /dev/sda&amp;lt;/pre&amp;gt;&lt;br /&gt;
Partition creation process consists of several steps:&lt;br /&gt;
# Start sector - you can safely use default value by pressing ↵&lt;br /&gt;
# Size&lt;br /&gt;
# Type (as hex code) - EFI is ef00, Linux filesystem is 8300, Swap is 8200.&lt;br /&gt;
Result table:&lt;br /&gt;
&amp;lt;pre&amp;gt;Part.     #     Size        Partition Type            Partition Name&lt;br /&gt;
----------------------------------------------------------------&lt;br /&gt;
1               200.0 MiB   EFI System                EFI&lt;br /&gt;
2               200.0 GiB   Linux filesystem          ROOT&lt;br /&gt;
3               32.0 GiB    Linux swap                SWAP&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;ROOT&amp;lt;/code&amp;gt; partition name will later be used in rEFInd configuration to identify boot volume.&lt;br /&gt;
Next step is creating filesystems:&lt;br /&gt;
&amp;lt;pre&amp;gt;# mkfs.vfat -F32 /dev/sda1&lt;br /&gt;
# mkfs.btrfs /dev/sda2&lt;br /&gt;
# mkswap /dev/sda3&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now we can mount our root volume:&lt;br /&gt;
&amp;lt;pre&amp;gt;# mount -t btrfs /dev/sda2 /mnt&amp;lt;/pre&amp;gt;&lt;br /&gt;
= File system structure =&lt;br /&gt;
Now we should create file structure that would provide reliable atomic system upgrades.&amp;lt;br&amp;gt;&lt;br /&gt;
Start with following directories:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# mkdir /mnt/next&amp;lt;/pre&amp;gt;&lt;br /&gt;
Stores next &amp;lt;code&amp;gt;current&amp;lt;/code&amp;gt; link, is necessary due to how busybox &amp;lt;code&amp;gt;mv&amp;lt;/code&amp;gt; does atomic link replacement.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# mkdir /mnt/commons&amp;lt;/pre&amp;gt;&lt;br /&gt;
Stores common non-snapshotting subvolumes.&amp;lt;br&amp;gt;&lt;br /&gt;
We may populate it right away:&lt;br /&gt;
&amp;lt;pre&amp;gt;# btrfs subvolume create /mnt/commons/@var@tmp&lt;br /&gt;
# btrfs subvolume create /mnt/commons/@var@cache&lt;br /&gt;
# btrfs subvolume create /mnt/commons/@var@log&lt;br /&gt;
# btrfs subvolume create /mnt/commons/@home&amp;lt;/pre&amp;gt;&lt;br /&gt;
If you use flatpak, you may also want to keep it&#039;s directory separate:&lt;br /&gt;
&amp;lt;pre&amp;gt;# btrfs subvolume create /mnt/commons/@var@lib@flatpak&amp;lt;/pre&amp;gt;&lt;br /&gt;
Include anything else in &amp;lt;code&amp;gt;/var&amp;lt;/code&amp;gt; that should be mutable, for example iwd and bluetooth:&lt;br /&gt;
&amp;lt;pre&amp;gt;# btrfs subvolume create /mnt/commons/@var@lib@iwd&lt;br /&gt;
# btrfs subvolume create /mnt/commons/@var@lib@bluetooth&amp;lt;/pre&amp;gt;&lt;br /&gt;
Next, most important directories:&lt;br /&gt;
&amp;lt;pre&amp;gt;# mkdir /mnt/snapshots&amp;lt;/pre&amp;gt;&lt;br /&gt;
Stores directories containing snapshots belonging to one generation.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# mkdir /mnt/links&amp;lt;/pre&amp;gt; &lt;br /&gt;
Stores generations of directories containing links to snapshot generations.&amp;lt;br&amp;gt;&lt;br /&gt;
Let&#039;s create first generation and populate it with one OS root snapshot &amp;lt;code&amp;gt;@&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;# NEWSNAPSHOTS=&amp;quot;$(date -u +&amp;quot;%Y%m%d%H%M%S&amp;quot;)$(cat /dev/urandom | tr -dc &#039;a-zA-Z&#039; | fold -w 8 | head -n 1)&amp;quot;&lt;br /&gt;
# mkdir &amp;quot;/mnt/snapshots/$NEWSNAPSHOTS&amp;quot;&lt;br /&gt;
# btrfs subvolume create /mnt/snapshots/$NEWSNAPSHOTS/@&amp;lt;/pre&amp;gt;&lt;br /&gt;
Populate &amp;lt;code&amp;gt;links&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;# NEWLINKS=&amp;quot;$(date -u +&amp;quot;%Y%m%d%H%M%S&amp;quot;)$(cat /dev/urandom | tr -dc &#039;a-zA-Z&#039; | fold -w 8 | head -n 1)&amp;quot;&lt;br /&gt;
# mkdir &amp;quot;/mnt/links/$NEWLINKS&amp;quot;&lt;br /&gt;
# ln -s &amp;quot;../../snapshots/$NEWSNAPSHOTS&amp;quot; &amp;quot;/mnt/links/$NEWLINKS/0&amp;quot;&lt;br /&gt;
# ln -s &amp;quot;../../snapshots/$NEWSNAPSHOTS&amp;quot; &amp;quot;/mnt/links/$NEWLINKS/1&amp;quot;&lt;br /&gt;
# ln -s &amp;quot;../../snapshots/$NEWSNAPSHOTS&amp;quot; &amp;quot;/mnt/links/$NEWLINKS/2&amp;quot;&lt;br /&gt;
# ln -s &amp;quot;../../snapshots/$NEWSNAPSHOTS&amp;quot; &amp;quot;/mnt/links/$NEWLINKS/3&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can have as many links as you like, just apply changes to rEFInd config and upgrade scripts described below accordingly.&amp;lt;br&amp;gt;&lt;br /&gt;
Link that will point to latest links generation:&lt;br /&gt;
&amp;lt;pre&amp;gt;# ln -s &amp;quot;./links/$NEWLINKS&amp;quot; /mnt/current&amp;lt;/pre&amp;gt;&lt;br /&gt;
This setup allows us to just have static rEFInd config that points to to &amp;lt;code&amp;gt;/current/0/@&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/current/1/@&amp;lt;/code&amp;gt;, etc. while the actual underlying boot environment will change with each upgrade.&amp;lt;br&amp;gt;&lt;br /&gt;
But how will fs mounting services know which snapshot generation is currently loaded?&amp;lt;br&amp;gt;&lt;br /&gt;
The answer is common &amp;lt;code&amp;gt;fstab&amp;lt;/code&amp;gt; in the [[BTRFS|btrfs]] root.&amp;lt;br&amp;gt;&lt;br /&gt;
Get UUIDs of the partitions first:&lt;br /&gt;
&amp;lt;pre&amp;gt;# blkid &amp;gt; /mnt/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now edit fstab accordingly:&lt;br /&gt;
&amp;lt;pre&amp;gt;# vi /mnt/fstab&amp;lt;/pre&amp;gt;&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 / btrfs subvol=CURRENT_SNAPSHOTS_PATH/@,ro,noatime 0 0&lt;br /&gt;
UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 /var/tmp btrfs subvol=/commons/@var@tmp,rw,noatime 0 0&lt;br /&gt;
UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 /var/cache btrfs subvol=/commons/@var@cache,rw,noatime 0 0&lt;br /&gt;
UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 /var/log btrfs subvol=/commons/@var@log,rw,noatime 0 0&lt;br /&gt;
UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 /var/lib/flatpak btrfs subvol=/commons/@var@lib@flatpak,rw,noatime 0 0&lt;br /&gt;
UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 /var/lib/iwd btrfs subvol=/commons/@var@lib@iwd,rw,noatime 0 0&lt;br /&gt;
UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 /var/lib/bluetooth btrfs subvol=/commons/@var@lib@bluetooth,rw,noatime 0 0&lt;br /&gt;
UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 /home btrfs subvol=/commons/@home,rw,noatime 0 0&lt;br /&gt;
# UUID=2FE6-837A /boot/efi vfat rw,noatime,discard 0 2&lt;br /&gt;
tmpfs /tmp tmpfs mode=1777,noatime,nosuid,nodev,size=2G 0 0&lt;br /&gt;
UUID=f0239163-9d46-47c1-67a4-3ee1d63d0676 swap swap rw,noatime,discard 0 0&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;CURRENT_SNAPSHOTS_PATH&amp;lt;/code&amp;gt; will be replaced by scripts with, for example, &amp;lt;code&amp;gt;/snapshots/20210411212549sdBXyLxg&amp;lt;/code&amp;gt;, and the result will be piped into &amp;lt;code&amp;gt;/etc/fstab&amp;lt;/code&amp;gt; of a created &amp;lt;code&amp;gt;@&amp;lt;/code&amp;gt; snapshot during new generation preparations.&amp;lt;br&amp;gt;&lt;br /&gt;
Root [[BTRFS|btrfs]] volume structure mounted on &amp;lt;code&amp;gt;/mnt&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;|--mnt&lt;br /&gt;
| |--commons&lt;br /&gt;
| | |--@var@tmp&lt;br /&gt;
| | |--@var@cache&lt;br /&gt;
| | |--@var@log&lt;br /&gt;
| | |--@var@lib@flatpak&lt;br /&gt;
| | |--@var@lib@iwd&lt;br /&gt;
| | |--@home&lt;br /&gt;
| |--current&lt;br /&gt;
| |--fstab&lt;br /&gt;
| |--links&lt;br /&gt;
| | |--20210411213742qwrXAJBz&lt;br /&gt;
| | | |--0&lt;br /&gt;
| | | |--1&lt;br /&gt;
| | | |--2&lt;br /&gt;
| | | |--3&lt;br /&gt;
| |--next&lt;br /&gt;
| |--snapshots&lt;br /&gt;
| | |--20210411212549sdBXyLxg&lt;br /&gt;
| | | |--@&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Base system install =&lt;br /&gt;
With the directory strtucture prepared we can start installation of a basic Alpine Linux system.&amp;lt;br&amp;gt;&lt;br /&gt;
Considering that installation is done from Alpine system, we only need following parts of [[Alpine_Linux_in_a_chroot|the process]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;# apk -X https://dl-cdn.alpinelinux.org/alpine/latest-stable/main -U --allow-untrusted -p /mnt/snapshots/20210411212549sdBXyLxg/@ --initdb add alpine-base&amp;lt;/pre&amp;gt;&lt;br /&gt;
Now we can setup basic chroot to complete the installation process:&lt;br /&gt;
&amp;lt;pre&amp;gt;# export SNP=&amp;quot;/mnt/snapshots/20210411212549sdBXyLxg/@&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# mount -o bind /dev $SNP/dev&lt;br /&gt;
# mount -t proc none $SNP/proc&lt;br /&gt;
# mount -t sysfs sys $SNP/sys&lt;br /&gt;
&lt;br /&gt;
# sed &amp;quot;s#CURRENT_SNAPSHOTS_PATH#/snapshots/20210411212549sdBXyLxg#g&amp;quot; /mnt/fstab &amp;gt; &amp;quot;$SNP/etc/fstab&amp;quot;&lt;br /&gt;
&lt;br /&gt;
# cp -L /etc/resolv.conf &amp;quot;$SNP/etc/&amp;quot;&lt;br /&gt;
# chroot &amp;quot;$SNP&amp;quot; /bin/sh&lt;br /&gt;
&lt;br /&gt;
# mount -a&lt;br /&gt;
&lt;br /&gt;
# mv /etc/resolv.conf /tmp/&lt;br /&gt;
# ln -s /tmp/resolv.conf /etc/resolv.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As soon as you in chroot, define repositories:&lt;br /&gt;
&amp;lt;pre&amp;gt;# echo &amp;quot;https://dl-cdn.alpinelinux.org/alpine/latest-stable/main&amp;quot; &amp;gt; /etc/apk/repositories&amp;lt;/pre&amp;gt;&lt;br /&gt;
Example shows only &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;, but you should also add &amp;lt;code&amp;gt;testing&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;community&amp;lt;/code&amp;gt; if you need any packages in those.&amp;lt;br&amp;gt;&lt;br /&gt;
Now it&#039;s time for firmware, kernel and btrfs packages:&lt;br /&gt;
&amp;lt;pre&amp;gt;# apk add -U linux-firmware linux-lts btrfs-progs&amp;lt;/pre&amp;gt;&lt;br /&gt;
You may want to change &amp;lt;code&amp;gt;linux-firmware&amp;lt;/code&amp;gt; to a custom set of firmware packages suitable for you system, for example &amp;lt;code&amp;gt;linux-firmware-amd linux-firmware-amd-ucode linux-firmware-amdgpu linux-firmware-ath10k linux-firmware-qca&amp;lt;/code&amp;gt; for typical AMD laptop.&amp;lt;br&amp;gt;&lt;br /&gt;
It is also important to add &amp;lt;code&amp;gt;btrfs&amp;lt;/code&amp;gt; feature to &amp;lt;code&amp;gt;mkinitfs.conf&amp;lt;/code&amp;gt; and run &amp;lt;code&amp;gt;mkinitfs&amp;lt;/code&amp;gt; manually:&lt;br /&gt;
&amp;lt;pre&amp;gt;# vi /etc/mkinitfs/mkinitfs.conf&lt;br /&gt;
# mkinitfs&amp;lt;/pre&amp;gt;&lt;br /&gt;
These steps prepare kernel and generate &amp;lt;code&amp;gt;initramfs&amp;lt;/code&amp;gt; which later will be used to boot from our first snapshot.&amp;lt;br&amp;gt;&lt;br /&gt;
After that you should install any package you may need on first boot.&lt;br /&gt;
&lt;br /&gt;
{{Warning|In case your PC only has wireless connection you should also install any suitable networking software, like &amp;lt;code&amp;gt;iwd&amp;lt;/code&amp;gt; in this example, so you will not end up severed from network on your first boot.}}&lt;br /&gt;
&lt;br /&gt;
{{Note|Due to root being immutable during operation, it&#039;s recommended to install package &amp;lt;code&amp;gt;openresolv&amp;lt;/code&amp;gt; to support changing network connection. In this case &amp;lt;code&amp;gt;/etc/resolvconf.conf&amp;lt;/code&amp;gt; should have &amp;lt;code&amp;gt;resolv_conf{{=}}/tmp/resolv.conf&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;/etc/resolv.conf&amp;lt;/code&amp;gt; should be moved to &amp;lt;code&amp;gt;/tmp/resolv.conf&amp;lt;/code&amp;gt; and a link to the new resolv.conf location should be created: &amp;lt;code&amp;gt;ln -sfn /tmp/resolv.conf /etc/resolv.conf&amp;lt;/code&amp;gt;.&lt;br /&gt;
You may also use static DNS, but this would make your network activity directly identifiable to the DNS server provider, therefore it&#039;s not recommended.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Now, configure the system, start with setting a password for the root:&lt;br /&gt;
&amp;lt;pre&amp;gt;# passwd root&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Don&#039;t forget to add essential services to their respective runlevels:&lt;br /&gt;
&amp;lt;pre&amp;gt;rc-update add devfs sysinit&lt;br /&gt;
rc-update add dmesg sysinit&lt;br /&gt;
rc-update add mdev sysinit&lt;br /&gt;
rc-update add hwdrivers sysinit&lt;br /&gt;
&lt;br /&gt;
rc-update add hwclock boot&lt;br /&gt;
rc-update add modules boot&lt;br /&gt;
rc-update add sysctl boot&lt;br /&gt;
rc-update add hostname boot&lt;br /&gt;
rc-update add bootmisc boot&lt;br /&gt;
rc-update add syslog boot&lt;br /&gt;
&lt;br /&gt;
rc-update add mount-ro shutdown&lt;br /&gt;
rc-update add killprocs shutdown&lt;br /&gt;
rc-update add savecache shutdown&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With the snapshot prepared and configured we can chroot out of it and unmount everything:&lt;br /&gt;
&amp;lt;pre&amp;gt;# umount -a&lt;br /&gt;
# exit&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finish editing snapshot by setting &amp;lt;code&amp;gt;ro&amp;lt;/code&amp;gt; flag and unmounting root volume:&lt;br /&gt;
&amp;lt;pre&amp;gt;# btrfs property set -ts &amp;quot;/mnt/snapshots/20210411212549sdBXyLxg/@&amp;quot; ro true&lt;br /&gt;
# umount /mnt&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Bootloader installation =&lt;br /&gt;
{{Note|The example demonstrated here only make use of rEFInd bootloader as it is relatively easy to install manually and generally easy to use. You may however setup any prefered bootloader given it supports [[BTRFS|btrfs]] and can be configured to boot specific snapshot.}}&lt;br /&gt;
Mount the EFI partition:&lt;br /&gt;
&amp;lt;pre&amp;gt;# mount -t vfat /dev/sda1 /mnt&lt;br /&gt;
# mkdir /mnt/EFI&amp;lt;/pre&amp;gt;&lt;br /&gt;
Check the latest version number of the &amp;lt;code&amp;gt;refind&amp;lt;/code&amp;gt; package:&lt;br /&gt;
&amp;lt;pre&amp;gt;# apk info -X https://dl-cdn.alpinelinux.org/alpine/edge/testing -U refind&amp;lt;/pre&amp;gt;&lt;br /&gt;
Download the latest version (replace 0.13.2-r3 in the example below) of the &amp;lt;code&amp;gt;refind&amp;lt;/code&amp;gt; package:&lt;br /&gt;
&amp;lt;pre&amp;gt;# wget https://dl-cdn.alpinelinux.org/alpine/edge/testing/x86_64/refind-0.13.2-r3.apk&amp;lt;/pre&amp;gt;&lt;br /&gt;
Unpack prepared rEFInd archive and copy relevant files to &amp;lt;code&amp;gt;/mnt/EFI/&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;# tar -xzf refind-0.13.2-r3.apk&lt;br /&gt;
# cp -r usr/share/refind /mnt/EFI/&lt;br /&gt;
# cd /mnt/EFI/refind&amp;lt;/pre&amp;gt;&lt;br /&gt;
Rename config file and edit it:&lt;br /&gt;
&amp;lt;pre&amp;gt;# mv refind.conf-sample refind.conf&lt;br /&gt;
# vi refind.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
And append following to the end of the file, remember to replace example UUIDs with your own for &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt; ([[BTRFS|btrfs]] partition) and &amp;lt;code&amp;gt;resume&amp;lt;/code&amp;gt; (swap partition):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
menuentry &amp;quot;Alpine Linux&amp;quot; {&lt;br /&gt;
    icon /EFI/refind/icons/os_linux.png&lt;br /&gt;
    volume &amp;quot;ROOT&amp;quot;&lt;br /&gt;
    loader /current/0/@/boot/vmlinuz-lts&lt;br /&gt;
    initrd /current/0/@/boot/initramfs-lts&lt;br /&gt;
    options &amp;quot;root=UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 rootfstype=btrfs rootflags=subvol=/current/0/@,ro,noatime resume=UUID=f0239163-9d46-47c1-67a4-3ee1d63d0676 quiet splash&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    submenuentry &amp;quot;Boot fallback 1&amp;quot; {&lt;br /&gt;
        loader /current/1/@/boot/vmlinuz-lts&lt;br /&gt;
        initrd /current/1/@/boot/initramfs-lts&lt;br /&gt;
        options &amp;quot;root=UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 rootfstype=btrfs rootflags=subvol=/current/1/@,ro,noatime resume=UUID=f0239163-9d46-47c1-67a4-3ee1d63d0676 quiet splash&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    submenuentry &amp;quot;Boot fallback 2&amp;quot; {&lt;br /&gt;
        loader /current/2/@/boot/vmlinuz-lts&lt;br /&gt;
        initrd /current/2/@/boot/initramfs-lts&lt;br /&gt;
        options &amp;quot;root=UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 rootfstype=btrfs rootflags=subvol=/current/2/@,ro,noatime resume=UUID=f0239163-9d46-47c1-67a4-3ee1d63d0676 quiet splash&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    submenuentry &amp;quot;Boot fallback 3&amp;quot; {&lt;br /&gt;
        loader /current/3/@/boot/vmlinuz-lts&lt;br /&gt;
        initrd /current/3/@/boot/initramfs-lts&lt;br /&gt;
        options &amp;quot;root=UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 rootfstype=btrfs rootflags=subvol=/current/3/@,ro,noatime resume=UUID=f0239163-9d46-47c1-67a4-3ee1d63d0676 quiet splash&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
{{Note|&amp;lt;code&amp;gt;&amp;quot;ROOT&amp;quot;&amp;lt;/code&amp;gt; is the &amp;lt;code&amp;gt;PARTLABEL&amp;lt;/code&amp;gt; of the [[BTRFS|btrfs]] partition. You may also use &amp;lt;code&amp;gt;PARTUUID&amp;lt;/code&amp;gt; instead. To get both &amp;lt;code&amp;gt;blkid&amp;lt;/code&amp;gt; from &amp;lt;code&amp;gt;blkid&amp;lt;/code&amp;gt; package can be used. &amp;lt;code&amp;gt;blkid&amp;lt;/code&amp;gt; included in busybox does not provide this information. }}&lt;br /&gt;
To add rEFInd to UEFI, &amp;lt;code&amp;gt;efibootmgr&amp;lt;/code&amp;gt; is a suitable tool:&lt;br /&gt;
&amp;lt;pre&amp;gt;# apk add efibootmgr&lt;br /&gt;
# efibootmgr --create --disk /dev/sda --part 1 --loader /EFI/refind/refind_x64.efi --label &amp;quot;rEFInd&amp;quot; --verbose&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;/dev/sda&amp;lt;/code&amp;gt; is our disk device and &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; is the number of partition containing &amp;lt;code&amp;gt;rEFInd&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Updating or altering the system =&lt;br /&gt;
{{Note|These examples are implemented using execline and require &amp;lt;code&amp;gt;execline&amp;lt;/code&amp;gt; package in the system. These could surely be implemented in POSIX shell, however execline provides number of runtime advantages and is much more readable.}}&lt;br /&gt;
&amp;lt;pre&amp;gt;# touch /usr/sbin/sysmut&lt;br /&gt;
# chmod +x /usr/sbin/sysmut&lt;br /&gt;
# vi /usr/sbin/sysmut&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example script to mutate the the system:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#!/bin/execlineb -W&lt;br /&gt;
unshare --mount&lt;br /&gt;
importas -D 0 source 1&lt;br /&gt;
define mnt /media/root&lt;br /&gt;
if { mkdir -p ${mnt} }&lt;br /&gt;
if { mount -t btrfs -o rw,noatime UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 ${mnt} }&lt;br /&gt;
foreground {&lt;br /&gt;
	backtick -E dt {&lt;br /&gt;
		date -u +%Y%m%d%H%M%S&lt;br /&gt;
	}&lt;br /&gt;
	backtick -E rnd {&lt;br /&gt;
		pipeline { cat /dev/urandom }&lt;br /&gt;
		pipeline { tr -dc a-zA-Z }&lt;br /&gt;
		pipeline { fold -w 8 }&lt;br /&gt;
		head -n 1&lt;br /&gt;
	}&lt;br /&gt;
	define newsnap ${dt}${rnd}&lt;br /&gt;
	if { mkdir -p ${mnt}/snapshots/${newsnap} }&lt;br /&gt;
	if { btrfs subvolume snapshot ${mnt}/current/${source}/@ ${mnt}/snapshots/${newsnap}/@ }&lt;br /&gt;
	if {&lt;br /&gt;
		redirfd -w 1 ${mnt}/snapshots/${newsnap}/@/etc/fstab&lt;br /&gt;
			sed s#CURRENT_SNAPSHOTS_PATH#/snapshots/${newsnap}#g ${mnt}/fstab&lt;br /&gt;
	}&lt;br /&gt;
	if { mount -t proc none ${mnt}/snapshots/${newsnap}/@/proc }&lt;br /&gt;
	if { mount -t sysfs sys ${mnt}/snapshots/${newsnap}/@/sys }&lt;br /&gt;
	if { mount -o bind,ro /dev ${mnt}/snapshots/${newsnap}/@/dev }&lt;br /&gt;
	foreground {&lt;br /&gt;
		foreground { mount -o bind,ro /etc/resolv.conf ${mnt}/snapshots/${newsnap}/@/etc/resolv.conf }&lt;br /&gt;
		if {&lt;br /&gt;
			chroot ${mnt}/snapshots/${newsnap}/@&lt;br /&gt;
			foreground { mount -a }&lt;br /&gt;
			foreground { sh }&lt;br /&gt;
			importas apply ?&lt;br /&gt;
			foreground { umount -a }&lt;br /&gt;
			exit ${apply}&lt;br /&gt;
		}&lt;br /&gt;
		foreground { redirfd -w 2 /dev/null umount ${mnt}/snapshots/${newsnap}/@/etc/resolv.conf }&lt;br /&gt;
		if { btrfs property set -ts ${mnt}/snapshots/${newsnap}/@ ro true }&lt;br /&gt;
		define newlink ${dt}${rnd}&lt;br /&gt;
		if { mkdir -p ${mnt}/links/${newlink} }&lt;br /&gt;
		if { ln -s ../../snapshots/${newsnap} ${mnt}/links/${newlink}/0 }&lt;br /&gt;
		if { cp -P ${mnt}/current/0 ${mnt}/links/${newlink}/1 }&lt;br /&gt;
		if { cp -P ${mnt}/current/1 ${mnt}/links/${newlink}/2 }&lt;br /&gt;
		if { cp -P ${mnt}/current/2 ${mnt}/links/${newlink}/3 }&lt;br /&gt;
		if { mkdir -p ${mnt}/next }&lt;br /&gt;
		if { ln -sfn ./links/${newlink} ${mnt}/next/current }&lt;br /&gt;
		if { mv ${mnt}/next/current ${mnt}/ }&lt;br /&gt;
		echo &amp;quot;Switched to the new snapshot&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	foreground { redirfd -w 2 /dev/null umount ${mnt}/snapshots/${newsnap}/@/proc }&lt;br /&gt;
	foreground { redirfd -w 2 /dev/null umount ${mnt}/snapshots/${newsnap}/@/sys }&lt;br /&gt;
	redirfd -w 2 /dev/null umount ${mnt}/snapshots/${newsnap}/@/dev&lt;br /&gt;
}&lt;br /&gt;
umount ${mnt}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It will get you into the root shell chrooted into the new snapshot, where you can apply any change you like.&amp;lt;br&amp;gt;&lt;br /&gt;
If chroot shell exits with an error, there will be no switch to the new snapshots. This means you can manually discard changes while in the chroot by:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# exit 1&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Deleting unused snapshots =&lt;br /&gt;
Unused snapshots can be garbage-collected by:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;# touch /usr/sbin/syscln&lt;br /&gt;
# chmod +x /usr/sbin/syscln&lt;br /&gt;
# vi /usr/sbin/syscln&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#!/bin/execlineb -W&lt;br /&gt;
unshare --mount&lt;br /&gt;
define mnt /media/root&lt;br /&gt;
if { mkdir -p ${mnt} }&lt;br /&gt;
if { mount -t btrfs -o rw,noatime,compress=zstd:3 UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 ${mnt} }&lt;br /&gt;
foreground {&lt;br /&gt;
	foreground {&lt;br /&gt;
		pipeline {&lt;br /&gt;
			foreground {&lt;br /&gt;
				pipeline {&lt;br /&gt;
					find -H ${mnt}/snapshots/ -maxdepth 1 -mindepth 1 -print0&lt;br /&gt;
				}&lt;br /&gt;
				xargs -0 -r realpath&lt;br /&gt;
			}&lt;br /&gt;
			pipeline {&lt;br /&gt;
				find -H ${mnt}/current/ -maxdepth 1 -mindepth 1 -print0&lt;br /&gt;
			}&lt;br /&gt;
			xargs -0 -r realpath&lt;br /&gt;
		}&lt;br /&gt;
		pipeline { tr \\n \\0 }&lt;br /&gt;
		pipeline { sort -z }&lt;br /&gt;
		pipeline { uniq -u -z }&lt;br /&gt;
		pipeline { xargs -0 -r -n 1 -I [] find -H [] -maxdepth 1 -mindepth 1 -print0 }&lt;br /&gt;
		xargs -0 -r btrfs subvolume delete&lt;br /&gt;
	}&lt;br /&gt;
	foreground { find -H ${mnt}/snapshots/ -maxdepth 1 -mindepth 1 -empty -type d -delete }&lt;br /&gt;
	foreground {&lt;br /&gt;
		pipeline {&lt;br /&gt;
			foreground {&lt;br /&gt;
				pipeline {&lt;br /&gt;
					find -H ${mnt}/links/ -maxdepth 1 -mindepth 1 -print0&lt;br /&gt;
				}&lt;br /&gt;
				xargs -0 -r realpath&lt;br /&gt;
			}&lt;br /&gt;
			realpath ${mnt}/current&lt;br /&gt;
		}&lt;br /&gt;
		pipeline { tr \\n \\0 }&lt;br /&gt;
		pipeline { sort -z }&lt;br /&gt;
		pipeline { uniq -u -z }&lt;br /&gt;
		pipeline { xargs -0 -r -n 1 -I [] find -H [] -maxdepth 1 -mindepth 1 -print0 }&lt;br /&gt;
		xargs -0 -r -n 1 unlink&lt;br /&gt;
	}&lt;br /&gt;
	find -H ${mnt}/links/ -maxdepth 1 -mindepth 1 -empty -type d -delete&lt;br /&gt;
}&lt;br /&gt;
umount ${mnt}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Allowing temporary runtime alterations =&lt;br /&gt;
You can use &amp;lt;code&amp;gt;overlayfs&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;tmpfs&amp;lt;/code&amp;gt; built into Alpine&#039;s init script to allow changes in the rootfs which will be automatically reverted upon reboot.&amp;lt;br&amp;gt;&lt;br /&gt;
To make use this just add &amp;lt;code&amp;gt;overlaytmpfs&amp;lt;/code&amp;gt; to the kernel boot options in &amp;lt;code&amp;gt;refind.conf&amp;lt;/code&amp;gt;, e.g.:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    initrd /current/0/@/boot/initramfs-lts&lt;br /&gt;
    options &amp;quot;root=UUID=b9ff5e7b-e128-4e64-861a-2fdd794a9828 rootfstype=btrfs rootflags=subvol=/current/0/@,ro,noatime resume=UUID=f0239163-9d46-47c1-67a4-3ee1d63d0676 overlaytmpfs quiet splash&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    submenuentry &amp;quot;Boot fallback 1&amp;quot; {&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Machinestops</name></author>
	</entry>
</feed>