OpenRC: Difference between revisions

From Alpine Linux
(replaced wlsunset by pipewire)
(46 intermediate revisions by 3 users not shown)
Line 1: Line 1:
Alpine Linux uses [https://github.com/OpenRC/ openrc] for its init system. The init system manages the services, startup and shutdown of your computer.  
Alpine Linux uses [https://github.com/OpenRC/ OpenRC] for its [https://en.wikipedia.org/wiki/Init init] system. The init system manages the services, including the boot and shutdown of your system. OpenRC also supports managing [[#User services|services for users]].  


Refer to the excellent guide [https://docs.alpinelinux.org/user-handbook/0.1a/Working/openrc.html working with OpenRC] from Alpine Linux documentation project to learn the basics quickly. Refer [[Writing Init Scripts]] and [[Multiple Instances of Services|Multiple instances of services]] pages for more advanced information.
To learn the basics of OpenRC quickly, refer to the [https://docs.alpinelinux.org/user-handbook/0.1a/Working/openrc.html working with OpenRC] guide from the Alpine Linux documentation project.  


== Quickstart  ==
== Quickstart  ==
Line 13: Line 13:
| colspan="3" | '''Managing a service - start,stop and restart'''
| colspan="3" | '''Managing a service - start,stop and restart'''
|-
|-
| Start <serviceName> now || {{ic|# rc-service <serviceName> start}}
| Start {{ic|ServiceName}} now || {{ic|# rc-service {{ic|ServiceName}} start}}
|-
|-
| Stop <serviceName> now || {{ic|# rc-service <serviceName> stop}}  
| Stop {{ic|ServiceName}} now || {{ic|# rc-service {{ic|ServiceName}} stop}}  
|-
|-
| Restart <serviceName> now || {{ic|# rc-service <serviceName> restart}}  
| Restart {{ic|ServiceName}} now || {{ic|# rc-service {{ic|ServiceName}} restart}}  
|-
|-
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
| colspan="3" | '''Adding and removing service from runlevels'''
| colspan="3" | '''Adding and removing service from runlevels'''
|-
|-
| Add <serviceName> to <runlevel> || {{ic|# rc-update add <serviceName> <runlevel>}}  
| Add {{ic|ServiceName}} to {{ic|runlevel}} || {{ic|# rc-update add {{ic|ServiceName}} {{ic|runlevel}}}}  
|-
|-
| Remove <serviceName> from <runlevel> || {{ic|# rc-update del <serviceName> <runlevel>}}  
| Remove {{ic|ServiceName}} from {{ic|runlevel}} || {{ic|# rc-update del {{ic|ServiceName}} {{ic|runlevel}}}}  
|-
|-
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
Line 30: Line 30:
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
|-
|-
| To check status of <serviceName> || {{ic|$ rc-service <serviceName> status}}  
| To check status of {{ic|ServiceName}} || {{ic|$ rc-service {{ic|ServiceName}} status}}  
|-
|-
| To view services configured at <runlevel> || {{ic|$ rc-update show <runlevel>}}  
| To view services configured at {{ic|runlevel}} || {{ic|$ rc-update show {{ic|runlevel}}}}  
|-
|-
| To view currently active runlevels and state of services  || {{ic|$ rc-status}}  
| To view currently active runlevels and state of services  || {{ic|$ rc-status}}  
Line 42: Line 42:
| To view available runlevels || {{ic|$ rc-status -l}}  
| To view available runlevels || {{ic|$ rc-status -l}}  
|-
|-
| To change to a different <runlevel> || {{ic|$ openrc <runlevel>}}  
| To change to a different {{ic|runlevel}} || {{ic|# openrc {{ic|runlevel}}}}  
|-
|-
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
Line 48: Line 48:
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
|-
|-
| To add <s-runlevel> as a stacked <runlevel|| {{ic|# rc-update add -s <s-runlevel> <runlevel>}}  
| To add {{ic|s-runlevel}} as a stacked {{ic|runlevel}} || {{ic|# rc-update add -s {{ic|s-runlevel}} {{ic|runlevel}}}}  
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
| colspan="3" | ''' User Services -  adding '''-U''' or '''--user''' to most of above commands should work
| colspan="3" |'''User Services'''
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
|- style="background:#333333; color:#ffffff; font-size: 0.9em; text-align:center;"
|-
|-
| To view currently active User runlevels and state of User services || {{ic|$ rc-status -U}}  
| To view currently active User runlevels and state of User services || {{ic|$ rc-status -U}}  
|-
|-
| To change to a different user <runlevel> || {{ic|$ openrc -U <runlevel>}}  
| To change to a different user {{ic|runlevel}} || {{ic|$ openrc -U {{ic|runlevel}}}}  
|-
|-
| Add User <serviceName> to user <runlevel> || {{ic|$ rc-update add -U <serviceName> <runlevel>}}  
| Add User {{ic|ServiceName}} to user {{ic|runlevel}} || {{ic|$ rc-update -U add {{ic|ServiceName}} {{ic|runlevel}}}}  
|}
|}


== Runlevels ==
== Runlevels ==


A runlevel is basically a collection of services that needs to be started. Instead of random numbers they are named, and users can create their own if needed. The default startup uses the runlevels sysinit, boot, and default, in that order. Shutdown uses the shutdown runlevel.
A ''runlevel'' is basically a collection of services that needs to be started when certain conditions are met. Instead of using runlevel numbers, such as is used traditionally with ''SysV'' init, these are named, and users can create their own, if needed. The default startup uses the '''sysinit''', '''boot''', and '''default''' runlevels, in that order. Shutdown uses the '''shutdown''' runlevel.


The available runlevels are:
The available runlevels are:
Line 71: Line 71:
The special runlevels are:
The special runlevels are:


* '''sysinit''' - Brings up system specific stuff such as <code>/dev</code>, <code>/proc</code> and optionally <code>/sys</code> for Linux based systems. It also mounts <code>/lib/rc/init.d</code> as a ramdisk using tmpfs where available unless <code>/</code> is mounted rw at boot. <code>'''rc'''</code> uses <code>/lib/rc/init.d</code> to hold state information about the services it runs. sysinit always runs when the host first starts and should not be run again.
* '''sysinit''' - Brings up system specific stuff such as <code>/dev</code>, <code>/proc</code> and optionally <code>/sys</code> for Linux based systems. It also mounts <code>/lib/rc/init.d</code> as a ramdisk using tmpfs where available unless <code>/</code> is mounted rw at boot. <code>'''rc'''</code> uses <code>/lib/rc/init.d</code> to hold state information about the services it runs. '''sysinit''' always runs when the host first starts and should not be run again.
* '''boot''' - Generally the only services you should add to the boot runlevel are those which deal with the mounting of filesystems, set the initial state of attached peripherals and logging. Hotplugged services are added to the boot runlevel by the system. All services in the boot and sysinit runlevels are automatically included in all other runlevels except for those listed here.
* '''boot''' - Generally, the only services that one should add to the '''boot''' runlevel are those which deal with the mounting of filesystems, setting the initial state of attached peripherals, and logging. Hotplugged services are added to the '''boot''' runlevel by the system. All services in the '''boot''' and '''sysinit''' runlevels are automatically included in all other runlevels except for those listed here.
* '''single''' - Stops all services except for those in the sysinit runlevel.
* '''single''' - Stops all services except for those in the '''sysinit''' runlevel.
* '''reboot''' - Changes to the shutdown runlevel and then reboots the host.
* '''reboot''' - Changes to the '''shutdown''' runlevel, and then reboots the host.
* '''shutdown''' - Changes to the shutdown runlevel and then halts the host.
* '''shutdown''' - Changes to the shutdown '''runlevel''', and then halts the host.


=== Stacked runlevels ===
=== Stacked runlevels ===


Runlevel "inheritance" is acheived through [https://docs.alpinelinux.org/user-handbook/0.1a/Working/openrc.html#_runlevel_stacking runlevel stacking]. For more detailed information, refer [https://wiki.gentoo.org/wiki/OpenRC/Stacked%20runlevel Gentoo wiki].
''Stacked'' runlevels allows for the "inheritance" of services. A few use cases are given below:-
* [https://docs.alpinelinux.org/user-handbook/0.1a/Working/openrc.html#_runlevel_stacking Running an office runlevel with VPN service]
* [[#Preventing slow services from delaying system startup|Preventing slow services from delaying system startup]]
For more detailed information, refer [https://wiki.gentoo.org/wiki/OpenRC/Stacked%20runlevel Gentoo wiki].


== Configuration ==  
== Config files ==  


System-wide configuration file for OpenRC is {{Path|/etc/rc.conf}}.
The main configuration file for OpenRC is {{Path|/etc/rc.conf}}. The OpenRC service scripts for each service can be found at {{Path|/etc/init.d/}} and their respective service configuration files at {{Path|/etc/conf.d/}}.


If the setting {{Codeline|rc_parallel{{=}}"YES"}} is configured, the OpenRC system tries to start services in parallel for a slight speed improvement. This setting however comes with a message from openRC developers:{{Warning|whilst we have improved parallel, it can still potentially lock the boot process. Don't file bugs about this.}} To improve boot times, consider the idea suggested in the [[#Preventing slow services from delaying boot|preventing slow services]] from delaying boot section.
== Command usage ==


=== Cgroups ===
OpenRC provides the following commands:
* {{ic|rc-update}}
* {{ic|rc-service}}
* {{ic|rc-status}}
* {{ic|openrc}}


Since {{pkg|openrc}} 0.51 cgroups v2, or "unified", is the default. You can enable hybrid cgroups v1 & v2 by editing {{Path|/etc/rc.conf}} and setting <code>rc_cgroup_mode="hybrid"</code>.
To view the command usage for all OpenRC commands, use the '''--help''' or '''-h''' flag.  For eg:{{ic|$ rc-update '''--help'''}} or {{ic|$ rc-update '''-h'''}} will show usage information for {{ic|rc-update}}.


Then you should run {{Cmd|# rc-service cgroups start}}
To {{ic|start}}, {{ic|stop}} or {{ic|restart}} a service {{ic|ServiceName}} immediately at the current runlevel:
to take effect and {{Cmd|# rc-update add cgroups}}
{{cmd|$ doas rc-service {{ic|ServiceName}} start}}
to auto mount the cgroup filesystem on boot.
{{cmd|$ doas rc-service {{ic|ServiceName}} stop}}


== User services ==
To {{ic|add}} or {{ic|delete}} a service to/from the sequence of services that need to start automatically in future sessions at the {{ic|boot}} runlevel:
{{cmd|$ doas rc-update add {{ic|ServiceName}} boot}}
Note that the {{ic|'''default'''}} runlevel is assumed, so it does not need to be stated explicitly:
{{cmd|$ doas rc-update add {{ic|ServiceName}}}}
{{cmd|$ doas rc-update del {{ic|ServiceName}}}}


OpenRC supports managing services for users. User services are currently experimental and available from [[Release_Notes_for_Alpine_3.22.0#OpenRC_User_services|v3.22]] for the following:
List the current status of all services; to display the status of all ''user services'' add '''-U''' :
* [[PipeWire]]
{{cmd|$ rc-status}}
* {{pkg|wlsunset}}
List the assigned runlevels of all services; to display the runlevels of ''user services'' add '''-U''' :
* [[Mako]]
{{cmd|$ rc-update}}


=== Prerequisites ===
Refer to the [https://github.com/OpenRC/openrc/blob/master/user-guide.md OpenRC user guide] for more detailed information.


* [[XDG_RUNTIME_DIR]] variable must be set
== Cgroups ==


=== Configuration ===
OpenRC supports [https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html cgroups v2] in the default configuration. To enable hybrid cgroups, edit the file {{Path|/etc/rc.conf}} and change the setting for {{ic|rc_cgroup_mode}} as follows:{{Cat|/etc/rc.conf|rc_cgroup_mode{{=}}"hybrid"}}


Follow the below configuration steps to install user service:
Then, one should run {{Cmd|# rc-service cgroups start}}
to take effect and {{Cmd|# rc-update add cgroups}}
to auto mount the cgroup filesystem on boot.


# Allow propagation of the WAYLAND_DISPLAY environment variable by adding the following lines to file {{path|${XDG_CONFIG_HOME:-$HOME/.config}/rc/rc.conf}} as follows:{{Cat|rc.conf|<nowiki>rc_env_allow="WAYLAND_DISPLAY"</nowiki>}}
== Local service ==
#:The above option ensures settings in {{path|${XDG_CONFIG_HOME:-$HOME/.config}/rc/rc.conf}} override {{path|/etc/rc.conf}}. Similarly, configuration and service files in {{path|${XDG_CONFIG_HOME:-$HOME/.config}/rc/conf.d/}} and {{path|${XDG_CONFIG_HOME:-$HOME/.config}/rc/init.d/}} override {{path|/etc/user/conf.d/}} and {{path|/etc/user/init.d/}} respectively.
# For many [[wayland]] user services, a custom GUI runlevel needs to be created. To create this runlevel,run the following command:{{Cmd|$ mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/rc/runlevels/gui"}}
#To start user services from the above '''gui'''  runlevel, add the line {{ic|openrc --user gui}} to the startup file of your compositor after {{ic|$WAYLAND_DISPLAY}} is set.
#: For eg, for [[Sway]], add the following line to sway user config file {{Path|~/.config/sway/config}} as follows {{Cat|~/.config/sway/config|...
exec openrc --user gui
...}}
# Enable [[PipeWire]] User service by adding it to '''gui''' runlevel:{{Cmd|$ rc-update add -U pipewire gui}}
#: If {{pkg|wlsunset}} package is installed, to enable the wlsunset service replace {{codeline|pipewire}} by {{codeline|wlsunset}} in the above command.
# Remove the startup of above services either from {{Path|/etc/xdg/autostart}} folder or from the startup/config file, i.e wherever they were started/mentioned earlier.
# Logout and login to your [[wayland]] compositor for the user services to be lauched.
# Issuing the command {{ic|$ rc-status -U}} will produce an output similar to below, if the above instructions have been followed:
<Pre>
Runlevel: gui
pipewire                                                [  started 04:29:55 (0) ]
wlsunset                                                [  started 04:29:55 (0) ]
mako                                                    [  started 04:29:53 (1) ]
Dynamic Runlevel: hotplugged
Dynamic Runlevel: needed/wanted
dbus                                                    [  started 04:29:55 (0) ]
wireplumber                                              [  started 04:29:53 (1) ]
Dynamic Runlevel: manual
</Pre>
{{Todo|
[[KDE]] plasma users are requested to test the below instructions and [[Help:Editing|edit]] this page directly or the [[Talk:OpenRC|Discussion]] page.
# Enable [[#PAM support|PAM support]] for openrc user services.
# In the above instructions, skip steps 2 & 3. In step 4, skip the word "gui", as [[SDDM]] automatically drops the user in "default" user runlevel on logging in.}}


=== PAM support ===
Use the {{Path|/etc/local.d/}} directory to place programs or scripts which are to be run when the {{ic|local}} service is started or stopped.


The default installation of OpenRC user services is without PAM support. To ensure that user services do not linger on logout, enable PAM support for OpenRC user services by installing the {{pkg|openrc-user-pam}} package.{{Cmd|# apk add {{pkg|openrc-user-pam}}}}
If a file in this directory is executable and it has a .start extension, it will be run when the local service is started. If a file is executable and it has a .stop extension, it will be run when the local service is stopped. For more info refer [https://github.com/OpenRC/openrc/blob/master/local.d/README README]


If [[greetd]] is used, a harmless failed error message appears for {{ic|user.greetd}} service as per {{MR|81612#note_492385}}.
To enable the {{ic|local}} service, issue the command:{{Cmd|# rc-update add local}}


== Preventing slow services from delaying boot ==
== Preventing slow services from delaying system startup ==


Services that take a while to start will block the boot process until they complete. E.g.: <code>iwd</code> and <code>networking</code> might delay startup of an interactive system rather than start in the background.
Services that take a while to start will block the boot process until they complete. E.g.: {{ic|iwd}},{{ic|networking}},{{ic|chrony}} etc... might delay startup of an interactive system rather than start in the background.  


This can be remedied as per Patrycja's blog post titled [https://ptrcnull.me/posts/openrc-async-services/ OpenRC: Start services after login prompt]. This solution makes use of [[#Stacked runlevels|stacked runlevels]].
=== Parallel services ===


{{Warning|If the file {{Path|'''/etc/inittab'''}} is edited wrongly, the system may not boot. Take backup and learn how to restore using rescue disk  before proceeding.}}
If the setting {{Codeline|rc_parallel{{=}}"YES"}} is configured, the OpenRC system tries to start services in parallel for a slight speed improvement.  
* Create a custom runlevel (name is “async” here, but it doesn’t matter) {{Cmd|# mkdir /etc/runlevels/async}}
This setting however comes with a message from openRC developers:{{Warning|whilst we have improved parallel, it can still potentially lock the boot process. Don't file bugs about this.}}  


* Add default as a stacked runlevel {{Cmd|# rc-update add -s default async}}
=== Stacked runlevel method ===


* Remove slow services from default and add them to async {{Cmd|<nowiki># rc-update del chronyd
Slow services can also be [https://ptrcnull.me/posts/openrc-async-services.html started after login prompt] using [[#Stacked runlevels|stacked runlevels]].
# rc-update add chronyd async </nowiki>}}
{{Warning|Editing the file {{Path|'''/etc/inittab'''}} wrongly will render the system unusable. Take backup and learn to restore it using rescue disk before proceeding.}}


* Add changing of runlevel to async by adding the line '''::once:/sbin/openrc async''' to {{Path|/etc/inittab}} file as follows: {{Cat|/etc/inittab|<nowiki>...
# Create a custom runlevel '''async''':  {{Cmd|# mkdir /etc/runlevels/async}}
# Add '''default''' as a stacked runlevel {{Cmd|# rc-update add -s default async}}
# Remove slow service from '''default''' runlevel and add them to the '''async''' runlevel:{{Cmd|<nowiki># rc-update del <servicename> default
# rc-update add <servicename> async </nowiki>}}
# Enable the '''async''' runlevel by adding the line '''::once:/sbin/openrc async''' to {{Path|/etc/inittab}} file as follows: {{Cat|/etc/inittab|<nowiki>...
::wait:/sbin/openrc default
::wait:/sbin/openrc default
::once:/sbin/openrc async -q
::once:/sbin/openrc async -q
Line 165: Line 156:
tty1::respawn:/sbin/getty 38400 tty1
tty1::respawn:/sbin/getty 38400 tty1
...</nowiki>}}
...</nowiki>}}
After rebooting, services from async will start separately. This change does not affect other services that start from Default runlevel and they may still block agetty from running due to the wait label.
After rebooting, services from '''async''' will start separately. Other services started in '''default''' runlevel may still block [[TTY_Autologin|agetty]] from running, due to the {{ic|wait}} label.
 
== User services ==


== Command usage ==
OpenRC supports managing services for users. User services are currently experimental and available from [[Release_Notes_for_Alpine_3.22.0#OpenRC_User_services|v3.22]]. Here is the [https://pkgs.alpinelinux.org/contents?file=*&path=%2Fetc%2Fuser%2Finit.d&name=&branch=edge&repo=&arch=x86_64 list of OpenRC User services] available currently.
 
Such services are said to be running in ''user mode'' and are managed with usual OpenRC commands using the  '''-U''' option (as distinct from the ''-u'' option), and without '''doas''' (nor as root). 
 
=== Prerequisites ===
 
* [[XDG_RUNTIME_DIR]] variable must be set
 
=== Config files for user services ===
 
OpenRC uses {{path|$XDG_CONFIG_HOME/rc}} for its user service configuration. <code>$XDG_CONFIG_HOME</code>, the fallback {{path|~/.config}} is used. is unset.
 
The main configuration file for OpenRC User services is {{path|~/.config/rc/rc.conf}}.
 
==== Runlevels ====
 
Runlevels are represented by directories in {{path|$XDG_CONFIG_HOME/rc/runlevels}}. The default runlevel is <code>sysinit</code> and needs to be created explicitly in order to be enabled:
 
mkdir -p ${XDG_CONFIG_HOME:-~/.config}/rc/runlevels/sysinit
 
To start the default runlevel (<code>sysinit</code>), use:
 
openrc -U
 
To start another runlevel, use:
 
openrc -U $RUNLEVEL
 
Add the above line to <code>~/.profile</code> to automatically start the runlevel after logging in.
 
If automatic start-up of a runlevel needs to be enforced by the system administrator, see [[#PAM support|PAM support]] below.
 
==== Services ====
 
The service scripts for each OpenRC user service provided as part of official packages can be found at {{Path|/etc/user/init.d/}} and their respective service configuration files at {{Path|/etc/user/conf.d/}}.
 
The folders {{path|~/.config/rc/init.d/}} and {{path|~/.config/rc/conf.d/}} can have user customized service scripts for User services and their respective configuration files. These scripts override official files at {{Path|/etc/user/}}, if their service names match.
 
=== Configure environment variables ===
 
==== For Wayland ====
{{Tip|User services like {{pkg|wlsunset}} depend on the {{ic|$WAYLAND_DISPLAY}} environment variable. Hence, it is [https://gitlab.alpinelinux.org/alpine/aports/-/issues/17375#note_530383 recommended] to use '''gui''' runlevel for such services. Even though [[PipeWire]] can run at '''default''' runlevel, ensure that all your User services can run at the chosen runlevel.}}
* Allow propagation of the {{ic|$WAYLAND_DISPLAY}} and associated environment variables by adding the following lines to file {{path|~/.config/rc/rc.conf}} as follows:{{Cat|~/.config/rc/rc.conf|<nowiki>rc_env_allow="WAYLAND_DISPLAY"</nowiki>}}
* Create a custom '''gui''' user runlevel:{{Cmd|$ mkdir -p ~/.config/rc/runlevels/gui}}
* To start '''gui''' user runlevel, add the line {{ic|openrc -U gui}} to the startup file of your compositor. For eg, for [[Sway]] add:{{Cat|~/.config/sway/config|...
exec openrc -U gui}}
 
==== For Xorg ====
 
If [[Elogind]] is not used, ensure that [[Wayland#Creating_and_exporting_XDG_RUNTIME_DIR_manually|XDG_RUNTIME_DIR]] is set manually in {{path|~/.xinitrc}}. For eg, for [[dwm]] add:{{Cat|~/.xinitrc|<nowiki>...
if [ -z "$XDG_RUNTIME_DIR" ]; then
XDG_RUNTIME_DIR="/tmp/$(id -u)-runtime-dir"
mkdir -pm 0700 "$XDG_RUNTIME_DIR"
export XDG_RUNTIME_DIR
fi
openrc -U default
exec dwm</nowiki>}}
 
{{Note|For both the above cases, logout and login for the OpenRC user services to be started, before proceeding further.}}
 
=== User service management ===
 
Issue the command {{ic|$ rc-status -Ur}} to view and verify the current user runlevel as '''gui''' and '''default''' for Wayland and Xorg, respectively, before proceeding.
 
To start {{ic|ServiceName}} user service, issue the command:{{Cmd|$ rc-service -U {{ic|ServiceName}} start}}
Verify that the above OpenRC user service is started before proceeding further: {{Cmd|$ rc-status -U}}
To enable {{ic|ServiceName}} user service, issue the command: {{Cmd|$ rc-update -U add ServiceName}}


Usage: rc-update [options] add <service> [<runlevel>...]
{{Tip|Once a user service is configured, to prevent duplicate instance, remove them from {{Path|/etc/xdg/autostart}} folder or from the startup/config file.}}
  or: rc-update [options] del <service> [<runlevel>...]
  or: rc-update [options] [show [<runlevel>...]]
Options: [ asuChqVv ]
  -a, --all                        Process all runlevels
  -s, --stack                      Stack a runlevel instead of a service
  -u, --update                      Force an update of the dependency tree
  -h, --help                        Display this help output
  -C, --nocolor                    Disable color output
  -V, --version                    Display software version
  -v, --verbose                    Run verbosely
  -q, --quiet                      Run quietly (repeat to suppress errors)


Usage: rc-status [options] [-f ini] <runlevel>...
=== PAM support ===
  or: rc-status [options] [-f ini] [-a | -c | -l | -m | -r | -s | -u]
Options: [ acf:lmrsSuChqVv ]
  -a, --all                        Show services from all run levels
  -c, --crashed                    Show crashed services
  -f, --format <arg>                format status to be parsable (currently arg must be ini)
  -l, --list                        Show list of run levels
  -m, --manual                      Show manually started services
  -r, --runlevel                    Show the name of the current runlevel
  -s, --servicelist                Show service list
  -S, --supervised                  show supervised services
  -u, --unused                      Show services not assigned to any runlevel
  -h, --help                        Display this help output
  -C, --nocolor                    Disable color output
  -V, --version                    Display software version
  -v, --verbose                    Run verbosely
  -q, --quiet                      Run quietly (repeat to suppress errors)


Usage: rc-service [options] [-i] <service> <cmd>...
The default installation of OpenRC user services in Alpine Linux is without PAM support.
  or: rc-service [options] -e <service>
  or: rc-service [options] -l
  or: rc-service [options] -r <service>
Options: [ cdDe:ilr:INsSZChqVv ]
  -d, --debug                      set xtrace when running the command
  -D, --nodeps                      ignore dependencies
  -e, --exists <arg>                tests if the service exists or not
  -c, --ifcrashed                  if the service is crashed run the command
  -i, --ifexists                    if the service exists run the command
  -I, --ifinactive                  if the service is inactive run the command
  -N, --ifnotstarted                if the service is not started run the command
  -s, --ifstarted                  if the service is started run the command
  -S, --ifstopped                  if the service is stopped run the command
  -l, --list                        list all available services
  -r, --resolve <arg>              resolve the service name to an init script
  -Z, --dry-run                    dry run (show what would happen)
  -h, --help                        Display this help output
  -C, --nocolor                    Disable color output
  -V, --version                    Display software version
  -v, --verbose                    Run verbosely
  -q, --quiet                      Run quietly (repeat to suppress errors)


Usage: openrc [options] [<runlevel>]
In scenarios where services should not be allowed to [https://wiki.gentoo.org/wiki/OpenRC#lingering linger] on logout, PAM support for OpenRC user services can be enabled by installing the {{pkg|openrc-user-pam}} package.{{Cmd|# apk add {{pkg|openrc-user-pam}}}}
Options: [ a:no:s:SChqVv ]
  -n, --no-stop                    do not stop any services
  -o, --override <arg>              override the next runlevel to change into
                                    when leaving single user or boot runlevels
  -s, --service <arg>              runs the service specified with the rest
                                    of the arguments
  -S, --sys                        output the RC system type, if any
  -h, --help                        Display this help output
  -C, --nocolor                    Disable color output
  -V, --version                    Display software version
  -v, --verbose                    Run verbosely
  -q, --quiet                      Run quietly (repeat to suppress errors)


  Reboot/Halt/Poweroff: (And their equivalent from traditional GNU/Linux systems):{{Cmd|<nowiki># reboot  # ⇔ shutdown now -r
{{Warning|Starting services via PAM will start them before the user session initialises, which can lead them to fail in unexpected way due to missing preconditions. E.g.: because the [[XDG_RUNTIME_DIR]] is not yet initialised.}}
# halt    # ⇔ shutdown now -H
# poweroff # ⇔ shutdown now -P</nowiki>}}


== Troubleshooting ==
== Troubleshooting ==


Whenever a openRC service fails to run, to troubleshoot enable debugging option and run the command.  
Whenever a openRC service fails to run, troubleshoot by enabling a debugging option, and then run the command.  
 
For example, if running the command {{ic|rc-service greetd start}} causes the [[Greetd|greetd]] service to immediately crash, then alter the command to enable debug and to view its output:{{Cmd|# rc-service -d greetd restart}}
 
=== XDG_RUNTIME_DIR unset ===
 
While configuring [[#User services|user services]], running the command {{ic|$ doas rc-update add -U pipewire gui}} will generate the above error {{ic|XDG_RUNTIME_DIR unset}}.  Always issue the command as normal user {{ic|$ rc-update add -U pipewire gui}} and do NOT use {{ic|doas}}.
 
=== ERROR: user.greetd failed to start ===
 
While using [[#User services|user services]] with [[greetd]], the above error message will appear. This failed error message for {{ic|user.greetd}} service is harmless as per {{MR|81612#note_492385}}.
 
=== failed to create display ===


For example, if running the command {{ic|rc-service greetd start}} causes greetd service to immediately crash, then alter the command to enable and view the debug:{{Cmd|# rc-service -d greetd restart}}
When using openRC user services for {{ic|wlsunset}}, the following  error message may appear:{{Cmd|daemon.err wlsunset: failed to create display}}You will need the GUI runlevel for services that depend on {{ic|$WAYLAND_DISPLAY}}. Refer [[#For Wayland| Configure environment variables For Wayland]] section.


== See also ==
== See also ==
Line 256: Line 265:
* [https://wiki.archlinux.org/title/OpenRC ArchWiki]
* [https://wiki.archlinux.org/title/OpenRC ArchWiki]
* [https://wiki.postmarketos.org/wiki/OpenRC PostmarketOS Wiki]
* [https://wiki.postmarketos.org/wiki/OpenRC PostmarketOS Wiki]
* [https://ptrcnull.me/posts/openrc-async-services/ Start services after login prompt]
* [https://ptrcnull.me/posts/openrc-async-services.html Start services after login prompt]


[[Category:Booting]]  
[[Category:Booting]]  
[[Category:System Administration]]
[[Category:System Administration]]
[[Category:Services]]
[[Category:Services]]

Revision as of 12:54, 5 September 2025

Alpine Linux uses OpenRC for its init system. The init system manages the services, including the boot and shutdown of your system. OpenRC also supports managing services for users.

To learn the basics of OpenRC quickly, refer to the working with OpenRC guide from the Alpine Linux documentation project.

Quickstart

Action Command
Managing a service - start,stop and restart
Start ServiceName now # rc-service ServiceName start
Stop ServiceName now # rc-service ServiceName stop
Restart ServiceName now # rc-service ServiceName restart
Adding and removing service from runlevels
Add ServiceName to runlevel # rc-update add ServiceName runlevel
Remove ServiceName from runlevel # rc-update del ServiceName runlevel
Check services in a runlevel and their status
To check status of ServiceName $ rc-service ServiceName status
To view services configured at runlevel $ rc-update show runlevel
To view currently active runlevels and state of services $ rc-status
Check and manage runlevels
To view available runlevels $ rc-status -l
To change to a different runlevel # openrc runlevel
Stacked runlevels
To add s-runlevel as a stacked runlevel # rc-update add -s s-runlevel runlevel
User Services
To view currently active User runlevels and state of User services $ rc-status -U
To change to a different user runlevel $ openrc -U runlevel
Add User ServiceName to user runlevel $ rc-update -U add ServiceName runlevel

Runlevels

A runlevel is basically a collection of services that needs to be started when certain conditions are met. Instead of using runlevel numbers, such as is used traditionally with SysV init, these are named, and users can create their own, if needed. The default startup uses the sysinit, boot, and default runlevels, in that order. Shutdown uses the shutdown runlevel.

The available runlevels are:

  • default - Used if no runlevel is specified. (This is generally the runlevel you want to add services to.)
  • hotplugged
  • manual

The special runlevels are:

  • sysinit - Brings up system specific stuff such as /dev, /proc and optionally /sys for Linux based systems. It also mounts /lib/rc/init.d as a ramdisk using tmpfs where available unless / is mounted rw at boot. rc uses /lib/rc/init.d to hold state information about the services it runs. sysinit always runs when the host first starts and should not be run again.
  • boot - Generally, the only services that one should add to the boot runlevel are those which deal with the mounting of filesystems, setting the initial state of attached peripherals, and logging. Hotplugged services are added to the boot runlevel by the system. All services in the boot and sysinit runlevels are automatically included in all other runlevels except for those listed here.
  • single - Stops all services except for those in the sysinit runlevel.
  • reboot - Changes to the shutdown runlevel, and then reboots the host.
  • shutdown - Changes to the shutdown runlevel, and then halts the host.

Stacked runlevels

Stacked runlevels allows for the "inheritance" of services. A few use cases are given below:-

For more detailed information, refer Gentoo wiki.

Config files

The main configuration file for OpenRC is /etc/rc.conf. The OpenRC service scripts for each service can be found at /etc/init.d/ and their respective service configuration files at /etc/conf.d/.

Command usage

OpenRC provides the following commands:

  • rc-update
  • rc-service
  • rc-status
  • openrc

To view the command usage for all OpenRC commands, use the --help or -h flag. For eg:$ rc-update --help or $ rc-update -h will show usage information for rc-update.

To start, stop or restart a service ServiceName immediately at the current runlevel:

$ doas rc-service ServiceName start

$ doas rc-service ServiceName stop

To add or delete a service to/from the sequence of services that need to start automatically in future sessions at the boot runlevel:

$ doas rc-update add ServiceName boot

Note that the default runlevel is assumed, so it does not need to be stated explicitly:

$ doas rc-update add ServiceName

$ doas rc-update del ServiceName

List the current status of all services; to display the status of all user services add -U :

$ rc-status

List the assigned runlevels of all services; to display the runlevels of user services add -U :

$ rc-update

Refer to the OpenRC user guide for more detailed information.

Cgroups

OpenRC supports cgroups v2 in the default configuration. To enable hybrid cgroups, edit the file /etc/rc.conf and change the setting for rc_cgroup_mode as follows:

Contents of /etc/rc.conf

rc_cgroup_mode="hybrid"

Then, one should run

# rc-service cgroups start

to take effect and

# rc-update add cgroups

to auto mount the cgroup filesystem on boot.

Local service

Use the /etc/local.d/ directory to place programs or scripts which are to be run when the local service is started or stopped.

If a file in this directory is executable and it has a .start extension, it will be run when the local service is started. If a file is executable and it has a .stop extension, it will be run when the local service is stopped. For more info refer README

To enable the local service, issue the command:

# rc-update add local

Preventing slow services from delaying system startup

Services that take a while to start will block the boot process until they complete. E.g.: iwd,networking,chrony etc... might delay startup of an interactive system rather than start in the background.

Parallel services

If the setting rc_parallel="YES" is configured, the OpenRC system tries to start services in parallel for a slight speed improvement.

This setting however comes with a message from openRC developers:

Warning: whilst we have improved parallel, it can still potentially lock the boot process. Don't file bugs about this.


Stacked runlevel method

Slow services can also be started after login prompt using stacked runlevels.

Warning: Editing the file /etc/inittab wrongly will render the system unusable. Take backup and learn to restore it using rescue disk before proceeding.


  1. Create a custom runlevel async:

    # mkdir /etc/runlevels/async

  2. Add default as a stacked runlevel

    # rc-update add -s default async

  3. Remove slow service from default runlevel and add them to the async runlevel:

    # rc-update del <servicename> default # rc-update add <servicename> async

  4. Enable the async runlevel by adding the line ::once:/sbin/openrc async to /etc/inittab file as follows:

    Contents of /etc/inittab

    ... ::wait:/sbin/openrc default ::once:/sbin/openrc async -q # Set up a couple of getty's tty1::respawn:/sbin/getty 38400 tty1 ...

After rebooting, services from async will start separately. Other services started in default runlevel may still block agetty from running, due to the wait label.

User services

OpenRC supports managing services for users. User services are currently experimental and available from v3.22. Here is the list of OpenRC User services available currently.

Such services are said to be running in user mode and are managed with usual OpenRC commands using the -U option (as distinct from the -u option), and without doas (nor as root).

Prerequisites

Config files for user services

OpenRC uses $XDG_CONFIG_HOME/rc for its user service configuration. $XDG_CONFIG_HOME, the fallback ~/.config is used. is unset.

The main configuration file for OpenRC User services is ~/.config/rc/rc.conf.

Runlevels

Runlevels are represented by directories in $XDG_CONFIG_HOME/rc/runlevels. The default runlevel is sysinit and needs to be created explicitly in order to be enabled:

mkdir -p ${XDG_CONFIG_HOME:-~/.config}/rc/runlevels/sysinit

To start the default runlevel (sysinit), use:

openrc -U

To start another runlevel, use:

openrc -U $RUNLEVEL

Add the above line to ~/.profile to automatically start the runlevel after logging in.

If automatic start-up of a runlevel needs to be enforced by the system administrator, see PAM support below.

Services

The service scripts for each OpenRC user service provided as part of official packages can be found at /etc/user/init.d/ and their respective service configuration files at /etc/user/conf.d/.

The folders ~/.config/rc/init.d/ and ~/.config/rc/conf.d/ can have user customized service scripts for User services and their respective configuration files. These scripts override official files at /etc/user/, if their service names match.

Configure environment variables

For Wayland

Tip: User services like wlsunset depend on the $WAYLAND_DISPLAY environment variable. Hence, it is recommended to use gui runlevel for such services. Even though PipeWire can run at default runlevel, ensure that all your User services can run at the chosen runlevel.
  • Allow propagation of the $WAYLAND_DISPLAY and associated environment variables by adding the following lines to file ~/.config/rc/rc.conf as follows:

    Contents of ~/.config/rc/rc.conf

    rc_env_allow="WAYLAND_DISPLAY"
  • Create a custom gui user runlevel:

    $ mkdir -p ~/.config/rc/runlevels/gui

  • To start gui user runlevel, add the line openrc -U gui to the startup file of your compositor. For eg, for Sway add:

    Contents of ~/.config/sway/config

    ... exec openrc -U gui

For Xorg

If Elogind is not used, ensure that XDG_RUNTIME_DIR is set manually in ~/.xinitrc. For eg, for dwm add:

Contents of ~/.xinitrc

... if [ -z "$XDG_RUNTIME_DIR" ]; then XDG_RUNTIME_DIR="/tmp/$(id -u)-runtime-dir" mkdir -pm 0700 "$XDG_RUNTIME_DIR" export XDG_RUNTIME_DIR fi openrc -U default exec dwm
Note: For both the above cases, logout and login for the OpenRC user services to be started, before proceeding further.

User service management

Issue the command $ rc-status -Ur to view and verify the current user runlevel as gui and default for Wayland and Xorg, respectively, before proceeding.

To start ServiceName user service, issue the command:

$ rc-service -U ServiceName start

Verify that the above OpenRC user service is started before proceeding further:

$ rc-status -U

To enable ServiceName user service, issue the command:

$ rc-update -U add ServiceName

Tip: Once a user service is configured, to prevent duplicate instance, remove them from /etc/xdg/autostart folder or from the startup/config file.

PAM support

The default installation of OpenRC user services in Alpine Linux is without PAM support.

In scenarios where services should not be allowed to linger on logout, PAM support for OpenRC user services can be enabled by installing the openrc-user-pam package.

# apk add openrc-user-pam

Warning: Starting services via PAM will start them before the user session initialises, which can lead them to fail in unexpected way due to missing preconditions. E.g.: because the XDG_RUNTIME_DIR is not yet initialised.


Troubleshooting

Whenever a openRC service fails to run, troubleshoot by enabling a debugging option, and then run the command.

For example, if running the command rc-service greetd start causes the greetd service to immediately crash, then alter the command to enable debug and to view its output:

# rc-service -d greetd restart

XDG_RUNTIME_DIR unset

While configuring user services, running the command $ doas rc-update add -U pipewire gui will generate the above error XDG_RUNTIME_DIR unset. Always issue the command as normal user $ rc-update add -U pipewire gui and do NOT use doas.

ERROR: user.greetd failed to start

While using user services with greetd, the above error message will appear. This failed error message for user.greetd service is harmless as per !81612#note_492385.

failed to create display

When using openRC user services for wlsunset, the following error message may appear:

daemon.err wlsunset: failed to create display

You will need the GUI runlevel for services that depend on $WAYLAND_DISPLAY. Refer Configure environment variables For Wayland section.

See also