An Alpine Adventure

The Ansible playbooks for this article can be found here

I have a laptop that I use for experimenting with different operating systems. I’ve used it to run various Linux distributions, as well as FreeBSD and OpenBSD. I tend to set it up by hand, use it for a while, then reinstall with something new. In the most recent iteration of this I’ve used Alpine Linux to see if it would be suitable distribution for more than a container runtime. Many people may be familiar with Alpine from using Docker, where Alpine gives you one of the smallest footprint containers to start from. Some of its more compelling features are that it uses OpenRC as its init system, musl libc instead of glibc, and busybox for a pile of standard tools that normally require other binaries.

Alpine also has a large set of available packages , which are updated regularly, uses very little memory, launches only the minimum of needed services at boot, and is really easy to install. It includes one of my favorite desktop environments, Xfce , and drivers for the video cards I use. It seemed like a perfect fit for this laptop, and I have been meaning to write an Ansible playbook to make setup and maintenance easier and repeatable.


I started with the standard release , wrote it to a USB stick using dd, and booted it on the laptop. It greets you with a login screen where you login as root with no password. The message of the day tells you how to install it by running setup-alpine from the cmdline.

The install process is pretty basic, go with the flow and answer the questions presented. keyboard selection, network device initialization (including wireless!), timezone, etc. are all easy to understand. I use the defaults of chrony for network time and openssh instead of dropbear for ssh. Since this is a laptop I wanted to setup an encrypted disk, which from what I found on the wiki was a bit of a daunting task for a first install. It ends up I didn’t need any of that, the installer for Alpine 3.15 includes a crypto option when it asks you how you want to use the disk. Select that and then select sys for the filesystem on top, and the installation proceeds quickly. Make sure you select a long passphrase to protect your data, but also something you aren’t going to forget.

Setup remote access to root

On first reboot of the system I edited the /etc/ssh/sshd_config file to enable root password logins. Add a line that says PermitRootLogin yes and restart the sshd daemon with rc-service sshd restart. Now add your local ssh public key to the laptop root account’s authorized_keys file by running ssh-copy-id from the host you are going to run Ansible from, like this:

ssh-copy-id -i ~/.ssh/ root@laptop

ssh into the laptop using your key to make sure it is working.

Playbook Changes

If you are using an Intel video card the Ansible playbooks should Just Work(TM) for you. If you have a different video card you can search the available packages on Alpine using apk search xf86-video and apk info xf86-video-DRIVER to select the right one. Edit the system-setup.yml playbook and replace the xf86-video-intel package with the right one. The Alpine xorg wiki section may provide some help if there are problems.

Run the Ansible Playbooks

Edit the Ansible hosts file to set the IP or hostname for your laptop, and then you can run Ansible to setup the system, install Xfce, and setup pipewire:

ansible-playbook system-setup.yml
ansible-playbook applications.yml

These playbooks will install a bunch of packages, including useful utilities, replacements for the busybox provided tools, Xfce, sound (using pipewire), everything you need to get a basic desktop up and running. It will also switch sshd back to only allowing root login with the ssh key, enabling the Alpine community repository, setting up pipewire, doas, acpi hardware keys, and setting up wpa_supplicant so members of the netdev group can use wpa_cli or wpa_gui.

User Setup

You should now have a lightdm GUI running asking for login. You can write your own Ansible playbook to setup your user account to your liking, or ssh in as root and set one up manually. Make sure they are a member of the netdev, video, audio, and wheel groups. This allows use of doas for running root commands, and wpa_cli or wpa_gui for network configuration. Reboot to make sure everything is working correctly and all the changes have taken effect. eg. the hardware volume buttons don’t start working for me until I reboot.

WiFi network selection can be done using wpa_gui. One quirk with this is that it doesn’t like being run from the Xfce Application Autostart menu. It runs but when you exit it won’t attach itself to the panel. So I use the alt-f2 menu to run it and it works fine, adding an icon to the panel when it closes. This may not be a big issue if you are on the same network all the time – it will connected to the last used network on reboot.

The acpi hardware volume controls are handled by a script, /etc/acpi/ which I have modified and included in the playbook’s configs/etc/ directory. I use amixer to control the volume and mute. If you have other buttons, or ones that use different names you can find them by running acpi_listen and pushing the keys. Edit the script in Ansible to match your hardware and rerun the playbook to update the laptop.

In my opinion Alpine provides a nice streamlined distribution that is secure, easy to modify, easy to understand, and doesn’t use much memory. I’m seeing around 650M of use with Xfce and Firefox running on my system, leaving lots of room for other things like running Prusa Slicer using podman (that’ll be in the next post). Battery usage has been excellent so far, and the WiFi drivers are much faster than the ones in FreeBSD and OpenBSD using this same hardware.