# Alpine Linux # (January 2017) Alpine linux is a light-weight distribution. Because it's so light-weight, Alpine is a good fit for containers. > What makes Alpine distinctive includes applying the grsec/PaX patches to the kernel. > It also includes the choice of musl libc, and BusyBox for the core utilities. > These choices make Alpine especially minimalist and secure. > > Another distinctive part of Alpine is its variety of "installation modes." > It can be installed to a hard disk/SSD/other storage medium like any distro; this is called the **sys mode**. > When working with removable media, consider two other installation modes. > In both of these modes, boot the machine from a static ISO image (a CD or a USB partition configured like the CD). > A writable medium is also needed to save updates to the system. > In the **diskless** mode, this writable medium is typically a USB key or a second partition. > Both the base Alpine system and all persistent changes will be unpacked into a memory-based filesystem. > The other, **data mode**, deals with large amounts of persistent data kept on a persistent storage medium, rather than unpacked into memory. > The default setup in data mode stores the /var partition directly on the hard storage medium. > But as in the diskless mode, the root system comes from a static ISO image. > The second and third modes are sometimes referred to, collectively, as "run-from-RAM" installations. > > Key to the second and third modes is Alpine's `lbu` utility. > This tracks which files differ from their static ISO version and need to persist. > The lbu utility saves those changes in .apkovl "overlay" files (essentially tar-gzip archives). Its package manager is `apk`, which works somewhat like the FreeBSD ports collection. Alpine uses OpenRC for init, rather than systemd. Manual pages are not installed by default. If needed: # apk add man And, furthermore, install per-package man pages: # apk add foo-doc Set up sshd: # apk add openssh # rc-update add sshd # /etc/init.d/sshd start Setting the time zone: # apk add tzdata # cp /usr/share/zoneinfo/America/Detroit /etc/localtime # echo 'America/Detroit' > /etc/timezone # apk del tzdata Add s6 for service supervision: # apk add s6 # rc-update add s6-svscan boot The shell is the Busybox "ash" shell. To set something like my preferred prompt: # PS1='--- \h \w \$ ' /bin/ash reads ~/.profile for a login shell. # cat << EOF > /root/.profile # When using lxc-attach, do "su -" to trigger a login shell that runs .profile. export PS1='--- \h \w \\$ ' export PAGER='less' alias l='ls' alias ll='ls -lah' alias la='ls -a' EOF ## apk ## Pull updates: # apk update Install all updates: # apk upgrade To clean out the package cache: # apk cache clean Search packages by name: # apk search -v 'nginx*' Search package descriptions: # apk search -v --description 'NTP' Add a package: # apk add nginx Remove a package: # apk del nginx Show installed packages: # apk info ## OpenRC ## OpenRC operates on top of sysvinit. `/etc/inittab` runs `/sbin/openrc sysinit`, `/sbin/openrc boot`, and `/sbin/openrc default`. "sysinit", "boot", and "default" are runlevels that correspond to directories in `/etc/runlevels/`. Each of the runlevel directories contain shell-ish scripts that get evaluated by `openrc-run`. The scripts in `/etc/runlevels/*/` are symlinks to scripts in `/etc/init.d/`. `/etc/init.d/` may also hold scripts that are not activated at a runlevel. Basic "variable setting" local service configuration can be done in `/etc/conf.d/*`; these files will survive package upgrades and so forth. OpenRC has a couple of daemons: `start-stop-daemon` and `supervise-daemon`. The former assists with starting and stopping services; the latter restarts them if they crash. Apparently, `supervise-daemon` is still considred "experimental" (as of 2016), so s6 is suggested. Apparently, s6 can also replace `start-stop-daemon`. Documentation of OpenRC is lacking. This is the best tour I've found: http://www.funtoo.org/Package:OpenRC Show overview of services: # rc-status Restart a service: # rc-service nginx restart Make a service start at the default runlevel: # rc-update add nginx default Show all known services: # rc-update show -v Minimal OpenRC init script: #!/sbin/openrc-run name="fcgiwrap" description="fcgiwrap cgi daemon" command="/usr/bin/fcgiwrap" command_args="-c 3 -s unix:/var/run/nginx/fcgiwrap.sock" command_background="yes" pidfile="/var/run/nginx/fcgiwrap.pid" user="nginx" group="nginx" depend() { need net localmount after firewall } start() { ebegin "Starting ${name}" start-stop-daemon --exec ${command} \ --pidfile ${pidfile} --make-pidfile \ --background \ -u ${user} -g ${group} \ --start -- ${command_args} eend $? } The init script must be executable. See the examples in `/etc/init.d/`. Also `openrc-run(8)`, which is perhaps the best documentation of OpenRC init scripts. # apk add man openrc-doc All init scripts are assumed to have the following functions: start() stop() status() There are default implementations in rc/sh/runscript.sh - this allows very compact init scripts. These functions can be overriden per init script as needed. Runlevels are directories in `/etc/runlevels/`. After adding a new runlevel directory, run `install -d /etc/runlevels/$runlevel`. ## s6 and runit ## Because Alpine includes Busybox, it may eventually get the Busybox runit applets. https://paulgorman.org/technical/runit.txt For some reason, OpenRC seems to support s6 as an alternative to `supervise-daemon`. Furthermore, Alpine packages s6. To specify s6 as the supervisor for an OpenRC service, place this in its init file: supervisor=s6 To use s6, install it and enable it in OpenRC: # apk add s6 # rc-update add s6-svscan boot For every service/daemon controlled by s6, an `sv-supervise` process watches it. `s6-svscan` is a supervisor of supervirsors --- it watches a flock of `s6-supervise` processes. Configuration of a daemon is handled by its controlling `sv-supervise` process, based out of a "service directory". All service directories controlled by `s6-svscan` are collected under a "scan directory". The `s6-svc` command controls a `sv-supervise` process, and lets us signal its daemon. The `s6-svcscanctl` command controls a set of `sv-supervise` processes, and start or stop entire process trees. See https://paulgorman.org/technical/s6.txt for more about s6. s6 sets the scan directory as the argument to `s6-svscan` or (if not supplied) its current directory. On Alpine, the `/etc/init.d/s6-svscan` script sets the scan directory to `/run/openrc/s6-scan` (a tmpfs). How is that supposed to work? Because, under OpenRC with s6 supervision, each service supervised by s6 has an OpenRC init script too. That OpenRC init script can specify `s6_service_path`, which OpenRC symlins into `/run/openrc/s6-scan`. By default, OpenRC sets `s6_service_path` to `/var/svc.d/${RC_SVCNAME}`. So, an OpenRC service file for a daemon supervised by s6 might look like: #!/sbin/openrc-run name="myservice" description="myservice does my stuff" supervisor=s6 s6_service_path=/var/svc.d/myservice depend() { need s6-svscan net localmount after firewall } https://gitweb.gentoo.org/proj/openrc.git/plain/s6-guide.md > If you write your own start, stop and status functions in your service script, none of this will work. > You must allow OpenRC to use the default functions. We also need the s6 service directory, of course. See https://paulgorman.org/technical/s6.txt for more about s6. ## Links ## https://alpinelinux.org/ https://wiki.alpinelinux.org/wiki/Alpine_Linux:Overview https://wiki.alpinelinux.org/wiki/Tutorials_and_Howtos https://wiki.archlinux.org/index.php/OpenRC https://wiki.gentoo.org/wiki/Handbook:X86/Working/Initscripts http://manpages.ubuntu.com/manpages/trusty/man8/start-stop-daemon.8.html https://wiki.gentoo.org/wiki/OpenRC http://wiki.alpinelinux.org/wiki/Alpine_Linux_Init_System http://manpages.org/openrc-run/8 https://gentoo-handbook.lugons.org/doc/en/handbook/2006.1/handbook-hppa.xml?part=2&chap=4 https://wiki.gentoo.org/wiki/Handbook:AMD64/Full/Working http://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management https://www.mail-archive.com/supervision@list.skarnet.org/msg01260.html https://www.mail-archive.com/supervision@list.skarnet.org/msg00848.html http://www.funtoo.org/Package:OpenRC https://www.mail-archive.com/supervision@list.skarnet.org/msg00848.html https://gitweb.gentoo.org/proj/openrc.git/plain/s6-guide.md?h=openrc-0.16.x