Title: How-to install Alpine Linux in full ram with persistency | |
Author: Solène | |
Date: 14 July 2023 | |
Tags: immutability linux alpine | |
Description: In this article, you will learn how to install and | |
configure Alpine Linux to run your system from memory and save its | |
state for next boots. | |
# Introduction | |
In this guide, I'd like to share with you how to install Alpine Linux, | |
so it runs entirely from RAM, but using its built-in tool to handle | |
persistency. Perfect setup for a NAS or router, so you don't waste a | |
disk for the system, and this can even be used for a workstation. | |
Alpine Linux official project website | |
Alpine Linux wiki: Alpine local backup | |
# The plan | |
Basically, we want to get the Alpine installer on a writable disk | |
formatted in FAT instead of a read only image like official installers, | |
then we will use the command `lbu` to handle persistency, and we will | |
see what need to be configured to have a working system. | |
This is only a list of steps, they will be detailed later: | |
1. boot from an Alpine Installer (if you are using Alpine, you don't | |
need too) | |
2. format an usb memory drive with an ESP partition and make it | |
bootable | |
3. run `setup-bootloader` to copy the bootloader from the installer to | |
the freshly formatted drive | |
4. reboot on the usb drive | |
5. run `setup-alpine` | |
6. you are on your new Alpine system | |
7. run `lbu commit` to make changes persistent across reboot | |
8. make changes, run `lbu commit` again | |
A mad scientist Girl with a t-shirt labeled "rare t-shirt" is looking at a peng… | |
Artwork above by Prahou | |
# The setup | |
## Booting Alpine | |
For this step you have to download an Alpine Linux installer, take the | |
one that suits your needs, if unsure, take the "Extended" one. Don't | |
forget to verify the file checksum. | |
=> https://www.alpinelinux.org/downloads/ | |
Once you have the ISO file, create the installation media: | |
Alpine Linux documentation: Using the image | |
Now, boot your system using your brand-new installer. | |
## Writable boot media creation | |
In this step, we will need to boot on the Alpine installer to create a | |
new Alpine installer, but writable. | |
You need another USB media for this step, the one that will keep your | |
system and data. | |
On Alpine Linux, you can use `setup-alpine` to configure your network, | |
key map and a few things for the current system. You only have to say | |
"none" when you are asked what you want to install, where, and if you | |
want to store the configuration somewhere. | |
Run the following commands on the destination USB drive (networking is | |
required to install a package), this will format it and use all the | |
space as a FAT32 partition. In the example below, the drive is | |
`/dev/sdc`. | |
```shell | |
apk add parted | |
parted /dev/sdc -- mklabel gpt | |
parted /dev/sdc -- mkpart ESP fat32 1MB 100% | |
parted /dev/sdc -- set 1 esp on | |
``` | |
This creates a GPT table on `/dev/sdc`, then creates a first partition | |
as FAT32 from the first megabyte up to the full disk size, and finally | |
marks it bootable. This guide is only for UEFI compatible systems. | |
We actually have to format the drive as FAT32, otherwise it's just a | |
partition type without a way to mount it as FAT32: | |
``` | |
mkfs.vfat /dev/sdc1 | |
modprobe vfat | |
``` | |
Final step, we use an Alpine tool to copy the bootloader from the | |
installer to our new disk. In the example below, your installer may be | |
`/media/usb` and the destination `/dev/sdc1`, you could figure the | |
first one using `mount`. | |
``` | |
setup-bootable /media/usb /dev/sdc1 | |
``` | |
At this step, you made a USB disk in FAT32 containing the Alpine Linux | |
installer you were using live. Reboot on the new one. | |
## System installation | |
On your new installation media, run `setup-alpine` as if you were | |
installing Alpine Linux, but answer "none" when you are asked which | |
disk you want to use. When asked "Enter where to store configs", you | |
should be prompted your new device by default, accept. Immediately, | |
after, you will be prompted for an APK cache, accept. | |
At this point, we can say Alpine is installed! Don't reboot yet, you | |
are already on your new system! | |
Just use it, and run `lbu commit` when you need to save changes done to | |
packages or `/etc/`. `lbu commit` creates a new tarball in your USB | |
disk containing a list of files configured in | |
`/etc/apk/protected_paths.d/`, and this tarball is loaded at boot time, | |
and will install your package list quickly from the local cache. | |
Alpine Linux wiki: Alpine local backup (lbu command documentation) | |
Please take extra care that if you include more files, everything you | |
commit the changes, they have to be stored on your USB media. You | |
could modify the fstab to add an extra disk/partition for persistent | |
data on a performant drive. | |
# Updating the kernel | |
The kernel can't be upgraded using apk, you have to use the script | |
`update-kernel` that will create a "modloop" file in the boot partition | |
which contains the boot image. You can't rollback this file. | |
You will need a few gigabytes in your in-memory filesystem, or use a | |
temporary build directory by affecting `TMPDIR` variable to a | |
persistent storage. | |
By default, tmpfs on root is set to 1 GB, this can be increased given | |
you have enough memory using the command: `mount -o remount,size=6G /`. | |
The script should have the boot directory as a parameter, so it should | |
look like `update-kernel /media/usb/boot` in a default setup, if you | |
use an external partition, this would look like `env | |
TMPDIR=/mnt/something/ update-kernel /media/usb/boot`. | |
## Extra configuration | |
Here is a list of tweaks to improve your experience! | |
### keep last n configuration | |
By default, lbu will only keep the last version you save, by | |
setting`BACKUP_LIMIT` to a number n, you will always have the last n | |
versions of your system stored in the boot media, this is practical if | |
you want to roll back a change. | |
### apk repositories | |
Edit `/etc/apk/repositories` to uncomment the community repository. | |
### fstab check | |
Edit `/etc/fstab` to make sure the disk you are using is explicitly | |
configured using a UUID entry, if you only have this: | |
``` | |
/dev/cdrom /media/cdrom iso9660 noauto,ro 0 0 | |
/dev/usbdisk /media/usb vfat noauto,ro 0 0 | |
``` | |
This mean your system may have troubles if you use it on a different | |
computer or that you plug another USB disk in it. Fix by using the | |
UUID of your partition, you can find it using the program `blkid` from | |
the eponym package, and fix the fstab like this: | |
``` | |
UUID=61B2-04FA /media/persist vfat noauto,ro 0 0 | |
/dev/cdrom /media/cdrom iso9660 noauto,ro 0 0 | |
/dev/usbdisk /media/usb vfat noauto,ro 0 0 | |
``` | |
This will ALWAYS mount your drive as `/media/persist`. | |
If you had to make the change, you need to make some extra changes to | |
keep things coherent: | |
* set `LBU_MEDIA=persist` into `/etc/lbu/lbu.conf` | |
* umount the drive in `/media` and run `mkdir -p /media/persist && | |
mount -a`, you should have `/media/persist` with data in it | |
* run `lbu commit` to save the changes | |
### desktop setup | |
You can install a graphical desktop, this can easily be done with these | |
commands: | |
``` | |
setup-desktop xfce | |
setup-xorg-base | |
``` | |
Due to a bug, we have to re-enable some important services, otherwise | |
you would not have networking at the next boot: | |
``` | |
rc-update add hwdrivers sysinit | |
``` | |
Alpine bug report #9653 | |
You may want to enable the display manager at boot, which may be | |
lightdm, gdm or sddm depending on your desktop: | |
``` | |
rc-update add lightdm | |
``` | |
### user persistency | |
If you added a user during `setup-alpine`, its home directory has been | |
automatically added to `/etc/apk/protected_paths.d/lbu.list`, when you | |
run `lbu commit`, its whole home is stored. This may not be desired. | |
If you don't want to save the whole home directory, but only a | |
selection of files/directories, here is how to proceed: | |
1. edit `/etc/apk/protected_paths.d/lbu.list` to remove the line adding | |
your user directory | |
2. you need to create the user directory at boot with the correct | |
permissions: `echo "install -d -o solene -g solene -m 700 /home/solene" | |
| doas tee /etc/local.d/00-user.start` | |
3. in case you have some persistency set at least one user sub | |
directories, it's important to fix the permissions of all the user data | |
after the boot: `echo "chown -R solene:solene /home/solene | doas tee | |
-a /etc/local.d/00-user.start` | |
4. you need to mark this script as executable: `doas chmod +x | |
/etc/local.d/00-user.start` | |
5. you need to run the local scripts at boot time: `doas rc-update add | |
local` | |
6. save the changes: `doas lbu commit` | |
I'd recommend the use of a directory named `Persist` and adding it to | |
the lbu list. Doing so, you have a place to store some important data | |
without having to save all your home directory (including garbage such | |
as cache). This is even nicer if you use ecryptfs as explained below. | |
### extra convenience | |
Because Alpine Linux is packaged in a minimalistic manner, you may have | |
to install a lot of extra packages to have all the fonts, icons, | |
emojis, cursors etc... working correctly as you would expect for a | |
standard Linux desktop. | |
Fortunately, there is a community guide explaining each section you may | |
want to configure. | |
Alpine Linux wiki: Post installation | |
### Set X default keyboard layout | |
Alpine insists of you using a qwerty desktop for X until you log into | |
your session, this can be complicated to type passwords. | |
You can create a file `/etc/X11/xorg.conf.d/00-keyboard.conf` like in | |
the linked example and choose your default keyboard layout. You will | |
have to create the directories `/etc/X11/xorg.conf.d` first. | |
Arch Linux wiki: Keyboard configuration | |
### encrypted personal directory | |
You could use ecryptfs to either encrypt the home partition of your | |
user, or just give it a Private directory that could be unlocked on | |
demand AND made persistent without pulling all the user files at every | |
configuration commit. | |
``` | |
$ doas apk add ecryptfs-utils | |
$ doas modprobe ecryptfs | |
$ ecryptfs-setup-private | |
Enter your login passphrase [solene]: | |
Enter your mount passphrase [leave blank to generate one]: | |
[...] | |
$ doas lbu add $HOME/.Private | |
$ doas lbu add $HOME/.ecryptfs | |
$ echo "install -d -o solene -g solene -m 700 /home/solene/Private" | doas tee … | |
$ doas chmod +x /etc/local.d/50-ecryptfs.start | |
$ doas rc-update add local | |
$ doas lbu commit | |
``` | |
Now, when you need to access your private directory, run | |
`ecryptfs-mount-private` and you have your `$HOME/Private` directory | |
which is encrypted. | |
You could use ecryptfs to encrypt the whole user directory, this | |
requires extra steps and changes into `/etc/pam.d/base-auth`, don't | |
forget to add `/home/.ecryptfs` to the lbu include list. | |
Using ecryptfs guide | |
# Security | |
Let's be clear, this setup isn't secure! The weak part is the boot | |
media, which doesn't use secure boot, could easily be modified, and has | |
nothing encrypted (except the local backups, but NOT BY DEFAULT). | |
However, once the system has booted, if you remove the boot media, | |
nothing can be damaged as everything lives in memory, but you should | |
still use passwords for your users. | |
# Conclusion | |
Alpine is a very good platform for this kind of setup, and they provide | |
all the tools out of the box! It's a very fun setup to play with. | |
Don't forget that by default everything runs from memory without | |
persistency, so be careful if you generate data you don't want to lose | |
(passwords, downloads, etc...). | |
# Going further | |
The lbu configuration can be encrypted, this is recommended if you plan | |
to carry your disk around, especially if it contains sensitive data. | |
You can use the fat32 partition only for the bootloader and the local | |
backup files, but you could have an extra partition that could be | |
mounted for /home or something, and why not a layer of LUKS for | |
encryption. | |
You may want to use zram if you are tight on memory, this creates a | |
compressed block device that could be used for swap, it's basically | |
compressed RAM, it's very efficient but less useful if you have a slow | |
CPU. |