Learn Alpine Linux - OpenRC: Init System & Service Management
Episode 5 of 23

Learn Alpine Linux - OpenRC: Init System & Service Management

This episode dissects OpenRC, Alpine's non-systemd init system. You'll learn the boot chain from PID 1 to init and on to OpenRC, manage services with rc-service and rc-update, read rc-status, and understand the /etc/init.d and /etc/conf.d structure to write your own services.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Alpine uses OpenRC, not systemd. For those newly coming from Ubuntu, this difference is the biggest adjustment. Episode 5 dissects OpenRC from the boot chain to writing your own services, so you'll stop searching for systemctl everywhere.

After this episode, you'll be comfortable with the three main commands rc-service, rc-update, and rc-status, understand where services are defined, and be able to write a simple init script for your own applications.

The Boot Chain: from PID 1 to OpenRC

Replacing systemd

When the system boots, the kernel runs the first process — PID 1 — which on Alpine is init from BusyBox (or sbin/init). Init then calls OpenRC (/sbin/openrc), which runs the service scripts in the runlevel in parallel. There's no large management daemon like systemd; all the logic lives in shell scripts.

Look at the PID 1 process and the active runlevel:

Check init and the runlevel
ps -p 1 -o pid,comm,args
rc-status

The rc-status output shows the services running in the default runlevel along with their status. The init scripts live in /etc/init.d/, and each service has its variable configuration in /etc/conf.d/.

Managing Services: rc-service and rc-update

Service Operations

rc-service is the counterpart of systemctl start/stop/restart/status:

Manage services with rc-service
rc-service sshd start
rc-service sshd status
rc-service sshd restart
rc-service sshd stop

rc-update controls which services run at boot by adding them to a runlevel:

Enable a service at boot
rc-update add sshd default
rc-update del sshd default
rc-update show

The rc-update show output lists all services and the runlevels they're registered in. The pattern to remember: rc-service for manual operations, rc-update for autostart.

Status and Dependencies

To see the overall status and dependencies between services:

Check status and dependencies
rc-status
rc-status --all
rc-dependency-tree

rc-status --all shows services in all runlevels. If a service fails to start, rc-status flags it and you can check its logs in /var/log/.

The /etc/init.d and /etc/conf.d Structure

Separate Scripts and Configuration

OpenRC's key concept: scripts in /etc/init.d/ contain the logic, while user-modifiable variables live in /etc/conf.d/. These are the files you'll edit often:

OpenRC configuration locations
/etc/init.d/sshd     - script service sshd
/etc/conf.d/sshd     - variabel konfigurasi sshd
/etc/init.d/nginx    - script service nginx
/etc/conf.d/nginx    - variabel konfigurasi nginx

Change a service's configuration by editing its conf.d file, then restart:

Edit the configuration then restart the service
vi /etc/conf.d/sshd
rc-service sshd restart

Note that OpenRC uses variables in conf.d, not directives like systemd's Environment=. Open /etc/conf.d/sshd and you'll see variables like rc_ulimit and sshd_opts.

Writing Your Own Init Script

A Simple Service Example

To understand how OpenRC works, let's write a small service. Create a script at /etc/init.d/hello:

A simple init script
#!/sbin/openrc-run
 
name="hello"
description="Servis contoh OpenRC"
command="/usr/bin/printf"
command_args="hello from openrc"
command_args_foreground="yes"
 
depend() {
    need net
}

Make it executable, run it, and register it in the default runlevel:

Enable the hello service
chmod +x /etc/init.d/hello
rc-service hello start
rc-update add hello default
rc-status

The rc-status output now shows hello as started. The command and command_args variables are how OpenRC runs the binary; the depend() block declares that the service needs the network.

Troubleshooting Tips

When a Service Fails to Start

When a service won't start, these three diagnostic steps almost always suffice:

Diagnose an OpenRC service
rc-service nginx status
rc-service nginx restart
tail -20 /var/log/messages
  • rc-service nginx status gives the current status.
  • restart reloads the configuration after changes.
  • General logs are available at /var/log/messages (provided by the BusyBox syslog).

If the error relates to a wrong variable, check /etc/conf.d/nginx. If the service isn't found, make sure the package is installed — for example apk add nginx for the nginx service.

Closing

Episode 5 dissected OpenRC thoroughly: the boot chain from PID 1, service management with rc-service and rc-update, the /etc/init.d and /etc/conf.d structure, and how to write a simple init script.

Key takeaways:

  • OpenRC replaces systemd; there's no systemctl in Alpine.
  • rc-service handles start, stop, restart, and status.
  • rc-update adds services to the default runlevel at boot.
  • rc-status shows service and runlevel states.
  • Init scripts live in /etc/init.d, configuration variables in /etc/conf.d.
  • A custom service is just one shell script with a depend block.

In the next episode, episode 6, we'll discuss users, groups, and privileges — creating users with adduser and addgroup, leveraging the wheel group, and configuring doas as a sudo replacement in /etc/doas.d.

Learn Alpine Linux - OpenRC: Init System & Service Management | Learn Alpine Linux