Diskless Mode: Difference between revisions

From Alpine Linux
(rephrased installation section, changed heading names)
m (minor rewording and added wikilinks)
 
(39 intermediate revisions by 4 users not shown)
Line 1: Line 1:
In Diskless mode the entire operating system with all applications are first loaded into RAM and then only run from there. This is also the method used to boot the Alpine Linux <Code>iso</Code> installation media. Alpine Linux can be installed and configured so that the system continue to boot like this if "disk=none" is specified while running the <code>[[Alpine_setup_scripts#setup-alpine|setup-alpine]]</code> script.  
In Diskless mode, the entire operating system with all applications are first loaded into RAM (<code>tmpfs</code>) and then only run from there. This is also the method used to boot the Alpine Linux <Code>ISO9660</Code> filesystem based read-only [[Installation#Preparing_installation_media|installation media]].


The mode is extremely fast and can save on unnecessary disk spin-ups, power, and wear. It is similar to what other linux distributions may call a "frugal" install or boot using a "toram" option.  
Diskless mode is extremely fast and can save on unnecessary disk spin-ups, power, and wear and suitable for servers. It is similar to what other linux distributions may call a "frugal" install or boot using a "toram" option.


Custom configurations may be preserved or "persist" across reboots by using the Alpine Linux tool named <code>[[Alpine_local_backup|Local Backup Utility]](lbu)</code>. The initial and possibly read-only installation media can remain the only boot device for the "diskless" system by saving the running state to an [[#Apkovl|<Code>.apkovl</Code>]] file, and have these automatically loaded when booting from the boot device.
Alpine Linux provides [[Alpine_local_backup|Local Backup Utility]]({{ic|lbu}}) that allows custom configurations and package installations to be optionally preserved or made to "persist" across reboots as [[#Apkovl|apkovl]] files. If additional or updated packages have been added to the system, these may also be made available for automatic (re)installation during the boot phase without any (re)downloading, by enabling a [[#Local package cache|local package cache]].


In addition to the installation media, it is also possible to boot "diskless mode" Alpine Linux from a [[Create_a_Bootable_Device|customizable boot device]].
== Diskless installation ==


== Apkovl ==
When running the <code>[[Alpine_setup_scripts#setup-alpine|setup-alpine]]</code> script, if "disk=none" is specified, then Alpine Linux will continue to run in diskless mode. It invokes <code>[[Alpine_setup_scripts#setup-lbu|setup-lbu]]</code>  and <code>[[Alpine_setup_scripts#setup-apkcache|setup-apkcache]]</code> to use any available writable filesystem on any media other than the read-only [[Installation#Preparing_installation_media|installation media]] for saving the configuration settings as [[#Apkovl|apkovl]] file and [[#Local package cache|local package cache]].


Apkovl is a file used for storing local configuration state when running Alpine Linux in [[Diskless Mode]]. It stores all configuration files that have changed from the default ones. The filename is <Code><hostname>.apkovl.tar.gz</Code> and is stored in a location whose path is defined in {{Path|/etc/lbu/lbu.conf}}. The contents from the Apkovl file are overlaid on top of the contents of the apks that are loaded on boot.
{{Tip|For Diskless installations, create a [[Create a Bootable Device|Customizable boot device]] instead of a read-only installation media.}}


The backup tool <code>[[Alpine_local_backup|lbu]]</code> enables committing and reverting local configuration system state by using '''.apkovl''' files that are saved to a backup location and loaded when booting. In Diskless mode, for every change made to the running system to persist across reboot, the command <code>[[Alpine_local_backup|lbu commit]]</code> must be issued before rebooting the system to update the .apkovl file.
Complete the below preparatory steps depending on the available persistent storage option.  


== Local Package Cache ==
=== Using an internal disk for persistent storage ===


When Alpine Linux boots in Diskless Mode, the remote repositories will not be available until after networking has started. That means packages newer than on your local boot media would not be available after a reboot, unless they were made to persistent, by having a [[Alpine_Package_Keeper#Local_Cache|local package cache]] available on a local, writable, storage device.
Due to Bug: [https://gitlab.alpinelinux.org/alpine/alpine-conf/-/issues/10473 #10473] storing local configs on '''internal disks''' requires manual steps, i.e making an entry in {{Path|/etc/fstab}}, create mountpoint, and mount the partition before running <code>setup-alpine</code> script.  
 
If additional or updated packages have been added to the system, these may also be made available for automatic (re)installation and copied into RAM during the boot phase without any (re)downloading, by enabling a [[Alpine_Package_Keeper#Local_Cache|local package cache]] on a writable storage. The local package cache can be stored on the same partition as the .apkovl file.
 
== Installation  ==
 
Boot the target diskless system from the [[Installation#Preparing_installation_media|installation media]] and do not proceed after the [[Installation#Boot_Process|boot process]] stage. Eventhough Alpine Linux setup script <code>setup-alpine</code> uses <code>[[Alpine_setup_scripts#setup-lbu|setup-lbu]]</code> script, due to Bug: [https://gitlab.alpinelinux.org/alpine/alpine-conf/-/issues/10473 #10473] storing local configs and package cache on '''internal disks''' requires creating filesystem in a certain way, making an entry in {{Path|/etc/fstab}}, create mountpoint, and mount the partition before running <code>setup-alpine</code> script.  


# In this case, boot the target diskless system from the [[Installation#Preparing_installation_media|installation media]] and do not proceed after the [[Installation#Boot_Process|boot process]] stage.
# If necessary partition(s) are unavailable, manually [[Setting_up_disks_manually#Creating_partitions|create]] a partition using <Code>fdisk</Code>. In the below steps, we will use /dev/sdXY as partition number. Adjust the partition identifier as per the output of {{Codeline|<Code>blkid</Code>}}<br>
# If necessary partition(s) are unavailable, manually [[Setting_up_disks_manually#Creating_partitions|create]] a partition using <Code>fdisk</Code>. In the below steps, we will use /dev/sdXY as partition number. Adjust the partition identifier as per the output of {{Codeline|<Code>blkid</Code>}}<br>
#* Due to Bug: {{Issue|11589|The APKOVL loading of diskless setups doesn't work on btrfs and xfs filesystems, or nvme-based devices}}. So use only ext4 filesystem partitions on classic drives to store diskless mode states.
#* Due to Bug: {{Issue|11589|The APKOVL loading of diskless setups doesn't work on btrfs and xfs filesystems, or nvme-based devices}}. So use only ext4 filesystem partitions on classic drives to store diskless mode states.
#*  mkfs.ext4 creates ext4 filesystem with 64bit feature enabled by default, but extlinux may not be able to boot with that due to Issue {{Issue|14895}}. You may need to add "-O ^64bit" to mkfs.ext4 to circumvent this. The below command creates an ext4 partition with disabled journaling, to reduce write operations and allow the disk to spin down after the .apkovl and the packages have been read from the partition during the boot. Install package {{pkg|<Code>e2fsprogs</code>}} using command {{Codeline|<Code>apk add e2fsprogs</Code>}}, if the command <Code>mkfs.ext4</Code> is not available.
#*  mkfs.ext4 creates ext4 filesystem with 64bit feature enabled by default, but extlinux may not be able to boot with that due to Issue {{Issue|14895}}. You may need to add "-O ^64bit" to mkfs.ext4 to circumvent this. The below command creates an ext4 partition with disabled journaling, to reduce write operations and allow the disk to spin down after the .apkovl and the packages have been read from the partition during the boot. Install package {{pkg|<Code>e2fsprogs</code>}} using command {{Codeline|<Code>apk add e2fsprogs</Code>}}, if the command <Code>mkfs.ext4</Code> is not available.
#: {{Cmd|mkfs.ext4 -O ^has_journal,^64bit /dev/sdXY}}
#: {{Cmd|# mkfs.ext4 -O ^has_journal,^64bit /dev/sdXY}}
# Due to a [https://gitlab.alpinelinux.org/alpine/mkinitfs/-/issues/5 bug], the partition can not be mounted to /boot. Configure the /etc/fstab to mount the writable partition to /media/sdXY instead of /boot i.e. conforming to the hot/cold-plug mountpoints.  
# Due to a [https://gitlab.alpinelinux.org/alpine/mkinitfs/-/issues/5 bug], the partition can not be mounted to /boot. Configure the /etc/fstab to mount the writable partition to /media/sdXY instead of /boot i.e. conforming to the hot/cold-plug mountpoints.  
#: {{Cmd|mkdir /media/sdXY}}
#: {{Cmd|# mkdir /media/sdXY}}
#: {{cmd|echo "/dev/sdXY /media/sdXY ext4 noatime,ro 0 0" >> /etc/fstab}}
#: {{cmd|# echo "/dev/sdXY /media/sdXY ext4 noatime,ro 0 0" >> /etc/fstab}}
<!-- Mounting read-only is possible, because the [[Alpine_local_backup|lbu tools]] can temporarily remount it writable for their operation. -->
<!-- Mounting read-only is possible, because the [[Alpine_local_backup|lbu tools]] can temporarily remount it writable for their operation. -->
# Mount the partitions listed in {{Path|/etc/fstab}}.
# Mount the partitions listed in {{Path|/etc/fstab}}:{{Cmd|# <code>mount -a</code>}}  
#: {{Cmd|<code>mount -a</code>}} Look at the output of {{Codeline|<code>mount</code>}} to verify that the changes have been applied correctly.<br>
# Verify that the changes have been applied correctly by looking at the output of {{Cmd|$ <code>mount</code>}}  
# If <code>Setup-alpine</code> has not run before, follow the [[Installation#Installation_Step_Details|Installation steps]] to complete the [[Installation#Base_configuration|base configuration]]. The above changes should now enable you to choose the partition for saving the local configs and package cache. If asked, there is no need to first unmount the partition, that would only be needed to allow installing on its parent disk.
# Proceed to [[#Finishing diskless installation|Finishing diskless installation]] section without rebooting the computer.
# If <code>Setup-alpine</code> has already been used to configure the diskless system, the storage settings may be modified directly with
#: {{cmd|setup-lbu sdXY}}
# [[Alpine_Package_Keeper#Local_Cache|Local package cache]] can be enabled as follows:
#: {{cmd|mkdir /media/sdXY/cache}}
#: {{cmd|setup-apkcache /media/sdXY/cache}}
# If the partition is large enough, it can be useful to edit {{Path|lbu.conf}} to uncomment and set {{Codeline|BACKUP_LIMIT{{=}}3}}. For example, to allow reverting to a previous, working state if needed.
#: {{cmd|apk add nano}}
#: {{cmd|nano /etc/lbu/lbu.conf }}
# Finally, generate the first .apkovl file containing all the previous changes by executing <code>lbu commit</code>, so the customizations that were just made will persist a reboot.
#: {{cmd|lbu commit}}
# From now on, whenever packages are installed or newly configured, and the changes should be kept, execute <code>lbu commit</code>.


== Customizable boot device ==  
=== Using customizable boot device for persistent storage ===
{{Main|Create a Bootable Device}}


Alpine Linux running Diskless mode can also boot from a partition with a writable filesystem on USB-Stick/CompactFlash/SDCard or SSD/NVMe harddisk. This boot device is known as [[Create_a_Bootable_Device|customizable boot device]] to differentiate against iso9660 filesystem based read only Installation Media based boot device. Local customizations like apkovl files and cached packages can be stored in this customizable boot device, which also allows to also upgrade the kernel with its modules and firmware with the <code>update-kernel</Code> script.
A [[Create_a_Bootable_Device|Customizable boot device]] allows Alpine Linux to boot and run in Diskless mode from a partition with a writable filesystem on USB-Stick/CompactFlash/SDCard or SSD/NVMe harddisk. The [[#Apkovl|apkovl]] file(s) and [[#Local package cache|local package cache]] can be stored in this customizable boot device and no other storage is required.


For the newly configured local "diskless" system, it is possible to copy the boot system from a read-only installation media to a writable vfat partition (e.g. /dev/sdXY) with <code>[[Alpine_setup_scripts#setup-bootable|setup-bootable]]</code> script or manually to any writable partition and [[Create_a_Bootable_Device|create a customizable boot device]].
# Boot using the [[Create_a_Bootable_Device|Customizable boot device]].
# Find out where the customizable boot device is mounted, the location could vary.{{Cmd|<nowiki># mount | grep /media
/dev/sdXY on /media/sdXY type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=utf8,shortname=mixed,errors=remount-ro)
</nowiki>}}
# Mount the customizable boot device in rw mode, if required. {{Cmd|# mount -o remount,rw /media/sdXY}}
<!--
# Issue the below commands to create a directory for [[Local_APK_cache|Local Package Cache]]. {{Cmd|<nowiki># mkdir /media/sda1/cache
# setup-apkcache /media/sda1/cache
# ls -l /etc/apk/cache
lrwxrwxrwx    1 root    root            17 Oct 19 13:16 /etc/apk/cache -> /media/sda1/cache
</nowiki>}}-->
# Proceed to [[#Finishing diskless installation|Finishing diskless installation]] section without rebooting the computer.


== Loading apkovl from webserver ==
=== Finishing diskless installation ===


Alpine's "diskless mode" ISO boot images support boot parameters to load customizations files i.e  [[Alpine_local_backup#Creating_and_saving_an_apkovl_from_a_remote_host|apkovl from a webserver]].  
# If <code>setup-alpine</code> has not run before, follow the [[Installation#Installation_Step_Details|Installation steps]] to complete until the '''Disk & Install''' option appears.
<!--If asked, there is no need to first unmount the partition, that would only be needed to allow installing on its parent disk.-->
#* When the ''' Disk & Install''' option appears, the preparatory steps done earlier for [[#Using an internal disk for persistent storage|internal disk]] or [[#Using customizable boot device for persistent storage|customizable boot device]] should now enable you to choose the partition('''sdXY''') for saving the local configs and package cache. So accept the choices as follows:{{Cmd|<nowiki>Which disk(s) would you like to use? (or '?' for help or 'none') [none]
Enter where to store configs ('floppy', 'sdXY', 'usb' or 'none') [sdXY]:
Enter apk cache directory (or '?' or 'none') [/media/sdXY/cache]:</nowiki>}}
# If <code>setup-alpine</code> has already been run to configure the diskless system, the storage and package cache settings can be configured using the <code>[[Alpine_setup_scripts#setup-lbu|setup-lbu]]</code> and <code>[[Alpine_setup_scripts#setup-apkcache|setup-apkcache]]</code> as follows:{{cmd|<nowiki># setup-lbu sdXY
# mkdir /media/sdXY/cache
# setup-apkcache /media/sdXY/cache</nowiki>}}
# After the installer finished one can see how many created/modified files are detected and will be added to the backup:{{Cmd|<nowiki># lbu status
# lbu status | wc -l
59
</nowiki>}}
# Now Commit all the changes using the command:{{Cmd|# lbu commit}}
# Verify that the above command has created the [[#Apkovl|apkovl]] file i.e <Code><hostname>.apkovl.tar.gz</Code> as follows:{{Cmd|<nowiki>ls -l /media/sda1/*apkovl.tar.gz
-rwxr-xr-x    1 root    root          9591 Oct 19 15:23 /media/sda1/foo.apkovl.tar.gz
</nowiki>}}
# Now the diskless installation can be considered complete.


It's possible to load an APKOVL file from a webserver, by supplying a custom url with the <code>APKOVL</code> kernel boot parameter. If you don't have a web server you can run busybox's httpd temporarily to serve an .apkovl - <code>busybox httpd -p 127.0.0.1:80</code>.
== Configuration ==


== Upgrading a Running System ==
Refer to the following sections related to running a Diskless installation.


When Alping Linux runs in "diskless" or "data" disk mode, Upgrading a running system requires few extra steps.
=== Modifying root filesystem size ===


If booting a "diskless" system from a read-only device, or as an iso image on writable media, it's not possible to update the boot files (kernel, modules, firmware, ...) that reside on that device.
In Diskless mode, the root filesystem is mounted as <code>tmpfs</code>. By default rootfs is allocated 50% of available RAM (without swap). This may be adjusted to arbitrary value (like 300MB) at boot by setting [https://gitlab.alpinelinux.org/alpine/mkinitfs/-/blob/54bae0769080710e0769370a7bf3e0e158eec152/initramfs-init.in#L809-813 kernel parameter] as <code>rootflags{{=}}size{{=}}300M</code>, or temporarily after boot by issuing <code>mount -o remount,size{{=}}300M /</code>.


For [[Create_a_Bootable_Device|customizable boot device]], It is possible to update the boot files. However, even then, the kernel, with its modules and firmware files, can still not be updated directly through regular packages updates. Instead, there is the <code>update-kernel</code> script that can generate initfs images and install them together with upgraded kernels.
=== Local package cache ===
{{Main|Local APK cache}}
When Alpine Linux boots in Diskless Mode, the remote repositories will not be available until after networking has started. That means newer or extra packages not in your local boot media's squashfs image would not be available after a reboot, unless they were made available as [[Local APK cache|local package cache]] on a writable local storage device. The local package cache can be on the same partition as the '''apkovl''' file.


Upgrading can be done as follows.
=== Apkovl ===
{{cmd|apk add mkinitfs
 
}}
The local configuration or system state is saved  as APK Overlay ('''apkovl''') file to a backup location by the {{ic|lbu}}and loaded when booting. The filename for the '''apkovl'''  file is of the format <Code><hostname>.apkovl.tar.gz</Code> and is stored in a location whose path is defined in {{Path|/etc/lbu/lbu.conf}} file. Apkovl file stores all configuration files that have changed from the default ones. The contents from the Apkovl file are overlaid on top of the contents of the base image. In Diskless mode, for every change made to the running system to persist across reboot, the command {{ic|lbu commit}} must be issued to update the apkovl file.
This package is required for the generation of the initial filesystem used during boot.
 
* Additional initfs features that are missing in the default configuration, like the [[Btrfs|btrfs]] filesystem support (at the time of writing, to allow loading .apkovl configs and package cache during boot), may be enabled in <code>/etc/mkinitfs/mkinitfs.conf</code>.
==== Loading apkovl from webserver ====
 
If a read-only installation media is used, it can remain the only boot device for the "diskless" system by saving the running state i.e [[#Apkovl|apkovl]] file to a webserver, and have these automatically loaded when booting from the boot device. The Alpine linux boot process supports passing boot parameters to load [[#Apkovl|apkovl]] file from a webserver, by supplying a custom url with the {{ic|apkovl}} kernel boot parameter. If you don't have a web server you can run busybox's httpd temporarily to serve an .apkovl - <code>busybox httpd -p 127.0.0.1:80</code>.
 
== Upgrading a diskless system ==
 
[[Alpine_Package_Keeper#Upgrade_a_Running_System|Upgrading a running]] system with [[Diskless Mode|diskless]] or [[Data Disk Mode|Data disk]] mode for regular package update requires running the below command from [[Alpine_local_backup|Local Backup Utility]] after every package update:{{Cmd|# lbu commit}}
 
For upgrading the kernel, with its modules and firmware files use [[Diskless Mode#update-kernel script|update-kernel]] script. For upgrading  [[Diskless Mode|diskless]] or [[Data Disk Mode|Data disk]] installations to a new release branch refer  [[Upgrading Alpine Linux to a new release branch#Upgrading diskless and data disk mode installs to latest release|Upgrading diskless and data disk mode installs to latest release]].
 
=== update-kernel script ===
 
When kernel packages with its modules and firmware packages are upgraded, the <code>update-kernel</code> script generates initfs images and installs them together with upgraded kernel and updates the boot files in persistent storages like [[Create_a_Bootable_Device|customizable boot device]].
 
* Before upgrading, install the {{Pkg|mkinitfs}} package as this is required for the generation of the initial filesystem used during boot as follows: {{cmd|# apk add mkinitfs}}
* Additional initfs features that are missing in the default configuration, like the [[Btrfs|btrfs]] filesystem support (at the time of writing, to allow loading .apkovl configs and package cache during boot), may be enabled in the file {{Path|/etc/mkinitfs/mkinitfs.conf}}.
* Available initfs features may be listed with <code>ls /etc/mkinitfs/features.d</code>
* Available initfs features may be listed with <code>ls /etc/mkinitfs/features.d</code>
{{cmd|ls /etc/mkinitfs/features.d
{{cmd|<nowiki># ls /etc/mkinitfs/features.d
apk add nano
# apk add nano
nano /etc/mkinitfs/mkinitfs.conf
# nano /etc/mkinitfs/mkinitfs.conf
lbu commit
# lbu commit
</nowiki>}}
* Finally update the kernel and its boot environment.
{{cmd|# update-kernel /media/sdXY/boot/
}}
}}
Finally update the kernel and its boot environment.
{{Note|<code>update-kernel</code> run needs at least 8 GB free ram memory to avoid a broken modloop-image. So, in memory constrained devices like [[Raspberry Pi]], use the environment variable <code>TMPDIR</code> to point to a directory on a *nix file system formatted physical device, like a SD-Card or USB-Stick as follows: {{Cmd|<nowiki># TMPDIR=/media/sdc1/tmp update-kernel /media/mmcblk0p1/boot/</nowiki>}}}}
{{cmd|update-kernel /media/sdXY/boot/
 
}}
See <code>update-kernel --help</code> for options to manually add additional module or firmware packages.
* An <code>update-kernel</code> run needs at least 8 GB free ram memory to avoid a broken modloop-image.
* See <code>update-kernel --help</code> for options to manually add additional module or firmware packages.


== Kernel Options ==
== Documentation on kernel options ==


Documentation about kernel command line options regarding diskless mode will be available after installing the documentation sub-package {{Pkg|mkinitfs-doc}}:  
Documentation about kernel command line options regarding diskless mode can be accessed by installing the documentation sub-package {{Pkg|mkinitfs-doc}} and running the command {{Cmd|man mkinitfs-bootparam}}  


{{Cmd|man mkinitfs-bootparam}} <Pre>
<Pre>
       If no root= parameter is given, the initramfs will build a live system
       If no root= parameter is given, the initramfs will build a live system
       in memory from scratch. This is also called diskless mode.
       in memory from scratch. This is also called diskless mode.
Line 136: Line 164:
               previously mounted from a different system/OS.
               previously mounted from a different system/OS.
</Pre>
</Pre>
== See Also ==
 
== See also ==
 
* [[Alpine_local_backup|Alpine Local backup Utility - ''lbu''']]
* [[Alpine_local_backup|Alpine Local backup Utility - ''lbu''']]
* [[Alpine_Package_Keeper#Local_Cache|Local package cache]]
* [[Local APK cache|Local package cache]]
* [[Manually editing a existing apkovl]]
* [[Manually editing a existing apkovl]]
* [[Back Up a Flash Memory Installation]]
* [[Back Up a Flash Memory Installation]]
Line 146: Line 176:
* [[QEMU#Live_mode|QEMU Diskless example]]  
* [[QEMU#Live_mode|QEMU Diskless example]]  
* [[Alpine local backup#Include special files.2Ffolders to the apkovl|Include special files section]] - To include custom files outside of <code>/etc</code> in .apkovl file.
* [[Alpine local backup#Include special files.2Ffolders to the apkovl|Include special files section]] - To include custom files outside of <code>/etc</code> in .apkovl file.
* [[SquashFS]]
* [[OverlayFS]]
* [https://gitlab.alpinelinux.org/alpine/mkinitfs/-/blob/54bae0769080710e0769370a7bf3e0e158eec152/initramfs-init.in#L809-813 Root filesystem Size Allocation]
* [https://www.fedux.net/post/setup-alpine-linux-diskless/ Detailed Diskless Installation Instruction]
* [https://www.reddit.com/r/AlpineLinux/comments/1bezynm/comment/kuxcy70 Diskless Installation Instructions]


[[Category:Diskless]] [[Category:LBU]]
[[Category:Diskless]]

Latest revision as of 10:27, 29 September 2025

In Diskless mode, the entire operating system with all applications are first loaded into RAM (tmpfs) and then only run from there. This is also the method used to boot the Alpine Linux ISO9660 filesystem based read-only installation media.

Diskless mode is extremely fast and can save on unnecessary disk spin-ups, power, and wear and suitable for servers. It is similar to what other linux distributions may call a "frugal" install or boot using a "toram" option.

Alpine Linux provides Local Backup Utility(lbu) that allows custom configurations and package installations to be optionally preserved or made to "persist" across reboots as apkovl files. If additional or updated packages have been added to the system, these may also be made available for automatic (re)installation during the boot phase without any (re)downloading, by enabling a local package cache.

Diskless installation

When running the setup-alpine script, if "disk=none" is specified, then Alpine Linux will continue to run in diskless mode. It invokes setup-lbu and setup-apkcache to use any available writable filesystem on any media other than the read-only installation media for saving the configuration settings as apkovl file and local package cache.

Tip: For Diskless installations, create a Customizable boot device instead of a read-only installation media.

Complete the below preparatory steps depending on the available persistent storage option.

Using an internal disk for persistent storage

Due to Bug: #10473 storing local configs on internal disks requires manual steps, i.e making an entry in /etc/fstab, create mountpoint, and mount the partition before running setup-alpine script.

  1. In this case, boot the target diskless system from the installation media and do not proceed after the boot process stage.
  2. If necessary partition(s) are unavailable, manually create a partition using fdisk. In the below steps, we will use /dev/sdXY as partition number. Adjust the partition identifier as per the output of blkid
    • Due to Bug: #11589. The APKOVL loading of diskless setups doesn't work on btrfs and xfs filesystems, or nvme-based devices. So use only ext4 filesystem partitions on classic drives to store diskless mode states.
    • mkfs.ext4 creates ext4 filesystem with 64bit feature enabled by default, but extlinux may not be able to boot with that due to Issue #14895. You may need to add "-O ^64bit" to mkfs.ext4 to circumvent this. The below command creates an ext4 partition with disabled journaling, to reduce write operations and allow the disk to spin down after the .apkovl and the packages have been read from the partition during the boot. Install package e2fsprogs using command apk add e2fsprogs, if the command mkfs.ext4 is not available.

    # mkfs.ext4 -O ^has_journal,^64bit /dev/sdXY

  3. Due to a bug, the partition can not be mounted to /boot. Configure the /etc/fstab to mount the writable partition to /media/sdXY instead of /boot i.e. conforming to the hot/cold-plug mountpoints.

    # mkdir /media/sdXY

    # echo "/dev/sdXY /media/sdXY ext4 noatime,ro 0 0" >> /etc/fstab

  4. Mount the partitions listed in /etc/fstab:

    # mount -a

  5. Verify that the changes have been applied correctly by looking at the output of

    $ mount

  6. Proceed to Finishing diskless installation section without rebooting the computer.

Using customizable boot device for persistent storage

A Customizable boot device allows Alpine Linux to boot and run in Diskless mode from a partition with a writable filesystem on USB-Stick/CompactFlash/SDCard or SSD/NVMe harddisk. The apkovl file(s) and local package cache can be stored in this customizable boot device and no other storage is required.

  1. Boot using the Customizable boot device.
  2. Find out where the customizable boot device is mounted, the location could vary.

    # mount | grep /media /dev/sdXY on /media/sdXY type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=utf8,shortname=mixed,errors=remount-ro)

  3. Mount the customizable boot device in rw mode, if required.

    # mount -o remount,rw /media/sdXY

  4. Proceed to Finishing diskless installation section without rebooting the computer.

Finishing diskless installation

  1. If setup-alpine has not run before, follow the Installation steps to complete until the Disk & Install option appears.
    • When the Disk & Install option appears, the preparatory steps done earlier for internal disk or customizable boot device should now enable you to choose the partition(sdXY) for saving the local configs and package cache. So accept the choices as follows:

      Which disk(s) would you like to use? (or '?' for help or 'none') [none] Enter where to store configs ('floppy', 'sdXY', 'usb' or 'none') [sdXY]: Enter apk cache directory (or '?' or 'none') [/media/sdXY/cache]:

  2. If setup-alpine has already been run to configure the diskless system, the storage and package cache settings can be configured using the setup-lbu and setup-apkcache as follows:

    # setup-lbu sdXY # mkdir /media/sdXY/cache # setup-apkcache /media/sdXY/cache

  3. After the installer finished one can see how many created/modified files are detected and will be added to the backup:

    # lbu status # lbu status | wc -l 59

  4. Now Commit all the changes using the command:

    # lbu commit

  5. Verify that the above command has created the apkovl file i.e <hostname>.apkovl.tar.gz as follows:

    ls -l /media/sda1/*apkovl.tar.gz -rwxr-xr-x 1 root root 9591 Oct 19 15:23 /media/sda1/foo.apkovl.tar.gz

  6. Now the diskless installation can be considered complete.

Configuration

Refer to the following sections related to running a Diskless installation.

Modifying root filesystem size

In Diskless mode, the root filesystem is mounted as tmpfs. By default rootfs is allocated 50% of available RAM (without swap). This may be adjusted to arbitrary value (like 300MB) at boot by setting kernel parameter as rootflags=size=300M, or temporarily after boot by issuing mount -o remount,size=300M /.

Local package cache

When Alpine Linux boots in Diskless Mode, the remote repositories will not be available until after networking has started. That means newer or extra packages not in your local boot media's squashfs image would not be available after a reboot, unless they were made available as local package cache on a writable local storage device. The local package cache can be on the same partition as the apkovl file.

Apkovl

The local configuration or system state is saved as APK Overlay (apkovl) file to a backup location by the lbuand loaded when booting. The filename for the apkovl file is of the format <hostname>.apkovl.tar.gz and is stored in a location whose path is defined in /etc/lbu/lbu.conf file. Apkovl file stores all configuration files that have changed from the default ones. The contents from the Apkovl file are overlaid on top of the contents of the base image. In Diskless mode, for every change made to the running system to persist across reboot, the command lbu commit must be issued to update the apkovl file.

Loading apkovl from webserver

If a read-only installation media is used, it can remain the only boot device for the "diskless" system by saving the running state i.e apkovl file to a webserver, and have these automatically loaded when booting from the boot device. The Alpine linux boot process supports passing boot parameters to load apkovl file from a webserver, by supplying a custom url with the apkovl kernel boot parameter. If you don't have a web server you can run busybox's httpd temporarily to serve an .apkovl - busybox httpd -p 127.0.0.1:80.

Upgrading a diskless system

Upgrading a running system with diskless or Data disk mode for regular package update requires running the below command from Local Backup Utility after every package update:

# lbu commit

For upgrading the kernel, with its modules and firmware files use update-kernel script. For upgrading diskless or Data disk installations to a new release branch refer Upgrading diskless and data disk mode installs to latest release.

update-kernel script

When kernel packages with its modules and firmware packages are upgraded, the update-kernel script generates initfs images and installs them together with upgraded kernel and updates the boot files in persistent storages like customizable boot device.

  • Before upgrading, install the mkinitfs package as this is required for the generation of the initial filesystem used during boot as follows:

    # apk add mkinitfs

  • Additional initfs features that are missing in the default configuration, like the btrfs filesystem support (at the time of writing, to allow loading .apkovl configs and package cache during boot), may be enabled in the file /etc/mkinitfs/mkinitfs.conf.
  • Available initfs features may be listed with ls /etc/mkinitfs/features.d

# ls /etc/mkinitfs/features.d # apk add nano # nano /etc/mkinitfs/mkinitfs.conf # lbu commit

  • Finally update the kernel and its boot environment.

# update-kernel /media/sdXY/boot/

Note: update-kernel run needs at least 8 GB free ram memory to avoid a broken modloop-image. So, in memory constrained devices like Raspberry Pi, use the environment variable TMPDIR to point to a directory on a *nix file system formatted physical device, like a SD-Card or USB-Stick as follows:

# TMPDIR=/media/sdc1/tmp update-kernel /media/mmcblk0p1/boot/

See update-kernel --help for options to manually add additional module or firmware packages.

Documentation on kernel options

Documentation about kernel command line options regarding diskless mode can be accessed by installing the documentation sub-package mkinitfs-doc and running the command

man mkinitfs-bootparam

       If no root= parameter is given, the initramfs will build a live system
       in memory from scratch. This is also called diskless mode.

       When booting in diskless mode, the following options are also
       available:

       alpine_repo=(URL | PATH)
              If set, /etc/apk/repositories will be filled with this. May be a
              comma-separated list of URLs.

       apkovl=(URL | [DEVICE[:FS_TYPE]:]PATH)
              A HTTP, HTTPS or FTP URL to an apkovl.tar.gz file which will be
              retrieved and applied. Can also be a filesystem path, optionally
              prepended with the device name without the /dev/ prefix.

       autodetect_serial=no
              Disable automatic detection and setup of serial console.

       ds=OPTIONS
              Data source for tiny-cloud. If OPTIONS starts with nocloud,
              tiny-cloud will be enabled.

       nokeep_apk_new
              Setup a fresh system, ignore any apkovl.

       pkgs=PACKAGE{,PACKAGE}
              Comma-separated list of packages to be installed.
       ssh_key=(URL | SSH_KEY)
              This setting installs openssh and places the public key given as
              value in /root/.ssh/authorized_keys.  If the value is an HTTP or
              FTP url, its fetches the key(s) from there.

       splash Enable splash screen.

       usbdelay=NUMBER
              Wait NUMBER seconds for USB devices to show up before searching
              for boot media.

       wireguard=INTERFACE;IP_ADDRESS{,IP_ADDRESS,...}[;WG_CONFIG_FILE]
              Set up a wireguard interface named INTERFACE with the addresses
              IP_ADDRESS and use /etc/wireguard/initrd.conf or WG_CONFIG_FILE
              as a classic wg (not wg-quick) config.

       zfs_force=NUMBER
              Enable force importing the root zpool on boot, even if it was
              previously mounted from a different system/OS.

See also