(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
export PS1=‘— \h \w \$ ’ export PAGER=‘less’ alias l=‘ls’ alias ll=‘ls -lah’ alias la=‘ls -a’ EOF
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 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
.
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.
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