SystemsArticle / 002

Artix s6-frontend for systemd users

Managing packaged, custom, and persistent user services without learning every low-level s6 command first.

As of July 13, 2026, the Artix system repository carries s6-frontend 0.0.1.2, s6 2.15.0.0, s6-rc 0.6.1.1, s6-linux-init 1.2.0.1, and s6-base 3.2. The Artix s6 wiki still teaches the older direct s6-rc, s6-svc, and s6-db-reload interface. Those commands remain underneath the system, but current Artix installations should use the s6 frontend for normal system administration. (Artix) This guide assumes Artix s6 is already installed and booting. It is a service-management guide, not an in-place migration guide from systemd.

The central rule:
s6 live controls what is happening now.
s6 set controls what should be available and enabled after the service database is installed and at the next boot.

Most mistakes come from treating “start” and “enable” as the same operation. They are deliberately separate in s6-frontend. (Skarnet)

1. What the different s6 components do

Systemd combines initialization, process supervision, dependency management, logging interfaces, user managers, timers, cgroups, and other functions into one project. Artix’s s6 stack separates those responsibilities.

ComponentPurposeRough systemd comparison
s6-linux-initBoots and shuts down the machinePID 1 and shutdown portion of systemd
s6-svscanRoot of a supervision treeProcess-supervision infrastructure
s6-superviseKeeps one long-running process alivePer-service restart supervision
s6-rcHandles services, dependencies, bundles, and state changesService dependency/state engine
s6-frontendProvides the unified s6 commandThe closest equivalent to systemctl

The comparisons are intentionally approximate. In Artix, s6-svscan becomes PID 1, launches supervisors, and provides the root of the supervision tree. s6-rc then manages machine state on top of that tree, while s6-frontend turns the lower-level commands into a single administrative interface. (Artix Wiki)

Vocabulary

TermMeaning
LongrunA daemon or other process intended to remain alive
OneshotA short operation that changes state, such as mounting or initialization
BundleA named collection of longruns, oneshots, or other bundles
StoreA directory containing text-format service definitions
Repositorys6-rc’s organized view of all services found in the stores
Working setThe offline prescription being edited by s6 set
Compiled databaseThe service graph generated from the working set
Live databaseThe database currently controlling the running system

A longrun has a run program. A oneshot has an up command and optionally a down command. A bundle represents several services under one name. Dependencies apply to atomic services—longruns and oneshots—while bundles provide grouping. (Skarnet)

The complete flow is:

service stores
      ↓
s6 repository sync
      ↓
current working set
      ↓
s6 set commit
      ↓
compiled database
      ↓
s6 live install
      ↓
current live database and next boot

2. Inspect a fresh Artix s6 installation

Start by confirming what is installed and what PID 1 is running:

pacman -Q s6-base s6-frontend s6 s6-rc s6-linux-init

s6 version

ps -p 1 -o pid=,comm=,args=

sudo s6 set status -e
sudo s6 live status

On a normal Artix s6 installation, PID 1 should be s6-svscan. s6 set status -e shows the non-essential services in the current working set, while s6 live status shows services in the current live database. These outputs are not supposed to be identical: one describes boot policy and the other describes runtime state. (Artix Wiki)

The frontend has nested help:

s6 help
s6 live help
s6 set help
s6 process help
s6 repository help
s6 system help

Inspect Artix’s configured paths before modifying anything:

sudo grep -E \
  '^[[:space:]]*(scandir|livedir|repodir|bootdb|stmpdir|storelist)[[:space:]]*=' \
  /etc/s6-frontend.conf

Upstream defaults include /run/service for the scan directory, /run/s6-rc for the live database, /var/lib/s6-rc/repository for the repository, and a package store plus an administrator store. Artix may override those defaults, so the installed configuration is authoritative. (Skarnet)

3. The systemd-to-s6 translation table

Use <service> for a bundle or service-manager name such as foo. Use <service>-srv only when directly addressing the supervised daemon.

systemd operationCurrent s6-frontend operation
systemctl status foosudo s6 live status foo
Detailed daemon statussudo s6 process status foo-srv
systemctl is-active foosudo s6 live status foo
systemctl is-enabled foosudo s6 set status foo
systemctl start foosudo s6 live start foo
systemctl stop foosudo s6 live stop foo
Dependency-aware restartsudo s6 live restart foo
Restart only the daemonsudo s6 process restart -w foo-srv
systemctl enable foos6 set enable, then check, commit, live install
systemctl enable --now fooEnable sequence, then s6 live start foo
systemctl disable foos6 set disable, then check, commit, live install
systemctl disable --now fooStop it, then run the disable sequence
systemctl mask fooStop it, then s6 set mask, commit, and live install
systemctl unmask foos6 set unmask, commit, and live install
systemctl list-unitssudo s6 live status
systemctl list-unit-filessudo s6 set status -e
systemctl daemon-reloadFor changed service definitions: repository sync, commit, install
systemctl reload fooSend the daemon its documented reload signal, if supported
journalctl -u fooRead the service’s dedicated logger, application log, or catch-all log

s6 live understands bundles, oneshots, longruns, dependencies, and reverse dependencies. s6 process bypasses that graph and controls one supervised longrun directly. As such, s6 process is useful for daemon-level intervention, but it is not a replacement for s6 live or s6 set. (Skarnet)

There is no reason to rebuild the service database merely because /etc/foo.conf changed. Repository synchronization is for service-definition changes, such as adding, removing, or editing a source directory. Application configuration changes normally require only an application reload or restart.


4. Installing and finding packaged services

Artix commonly separates an application from its init-specific service package:

sudo pacman -S PACKAGE PACKAGE-s6

For example, an application may be installed as foo, while its service definitions are supplied by foo-s6. Current Artix repositories continue to use this naming convention. (Artix Wiki)

After installing the service package, find the actual service name rather than assuming it matches the package:

pacman -Ql PACKAGE-s6

sudo s6 repository sync

sudo s6 set status -e | grep -i PACKAGE
sudo s6 live status | grep -i PACKAGE

Package hooks may already synchronize the repository. Running s6 repository sync is still the correct recovery step when a newly installed service does not appear. Upstream requires synchronization whenever a store gains, loses, or changes service definitions. (Skarnet)

Artix service packages traditionally use three related names:

foo       bundle used for normal administration
foo-srv   supervised daemon
foo-log   supervised logger

Manage foo through s6 live and s6 set. Use foo-srv with s6 process only when directly inspecting or restarting the daemon. Starting the bundle also starts its logger and required dependencies. (Artix Wiki)

5. Checking service state

Three commands answer three different questions:

# What should happen at boot?
sudo s6 set status foo

# Is the service-manager object currently up?
sudo s6 live status foo

# What is the detailed state of the supervised daemon?
sudo s6 process status foo-srv

sudo s6 set status foo reports one of four prescriptions:

PrescriptionMeaning
maskedExcluded from the next live database
usableAvailable, but disabled at boot
activeEnabled at boot
alwaysEssential; normally up for the machine’s lifetime

A service can therefore be:

  • active but currently down because it was manually stopped;
  • usable but currently up because it was manually started;
  • masked and absent from the live database entirely.

This separation is intentional and is foundational to understanding s6-frontend. (Skarnet)

6. Starting, stopping, and restarting services now

Always inspect dependency consequences before a major transition:

sudo s6 live start -n foo
sudo s6 live stop -n foo
sudo s6 live restart -n foo

Apply the operation after reviewing the dry run:

sudo s6 live start foo
sudo s6 live stop foo
sudo s6 live restart foo

Starting a service also starts its dependencies. Stopping it also stops services that depend on it. (Skarnet)

The restart trap

sudo s6 live restart foo first stops foo and its reverse dependencies, but it only starts the service names explicitly supplied on the command line. A dependent service brought down during the restart is not automatically brought back unless it was also named. Always inspect -n output before restarting something low in the dependency graph. (Skarnet)

When only the daemon needs restarting and dependency transitions are undesirable:

sudo s6 process restart -w foo-srv

The -w option waits until the replacement process is up and, when supported, ready. (Skarnet)

Killing is not stopping

This command sends a signal:

sudo s6 process kill -s TERM foo-srv

If the daemon exits, its supervisor will normally start it again. To keep it down, use:

sudo s6 live stop foo

or, for direct low-level intervention:

sudo s6 process stop -w foo-srv

A supervised longrun is expected to restart after it dies unless the supervisor has been told to hold it down. (Skarnet)

Do not mistake s6 process start -p or stop -p for boot enablement. Those options modify the longrun’s local down state in the current supervision directory; s6 set remains the boot-policy interface. (Skarnet)

7. Enabling a service at boot

Save the current working set before a significant change:

sudo s6 set save before-foo-change

Then inspect and apply the enable operation:

sudo s6 set enable -n -I pull foo
sudo s6 set enable -I pull foo

sudo s6 set check
sudo s6 set commit
sudo s6 live install

sudo s6 live start foo

This is the practical equivalent of:

systemctl enable --now foo

-I pull makes required dependencies active too. s6 set commit compiles the working set, and s6 live install replaces the live service database while preserving existing service states as much as possible. A newly enabled service is not necessarily started merely because the database was installed, which is why the final s6 live start remains explicit. (Skarnet)

To enable the service for future boots without starting it now, omit:

sudo s6 live start foo

8. Disabling a service

First inspect both runtime and reverse-dependency consequences:

sudo s6 live stop -n foo
sudo s6 set disable -n -I fail foo

When no enabled reverse dependency requires it:

sudo s6 live stop foo
sudo s6 set disable -I fail foo

sudo s6 set check
sudo s6 set commit
sudo s6 live install

To disable it at the next boot while leaving it running now, omit the s6 live stop command.

If other active services depend on it, -I fail stops the operation instead of making an implicit decision. To deliberately disable those reverse dependencies too:

sudo s6 live stop foo
sudo s6 set disable -I pull foo

sudo s6 set check
sudo s6 set commit
sudo s6 live install

For disable, -I pull pulls reverse dependencies downward into the disabled prescription. This can affect more services than expected, which is why the dry run matters. (Skarnet)

9. Masking and unmasking

Disabling keeps a service available for manual startup. Masking removes it from the next live database entirely.

sudo s6 set mask -n -I fail foo
sudo s6 live stop -n foo

After reviewing the result:

sudo s6 live stop foo
sudo s6 set mask -I pull foo

sudo s6 set check
sudo s6 set commit
sudo s6 live install

Because masked services are absent from the replacement database, s6 live install also stops services that no longer exist in that database. (Skarnet)

Unmasking returns the service to usable, meaning available but disabled:

sudo s6 set unmask -I fail foo
sudo s6 set check
sudo s6 set commit
sudo s6 live install

To enable it at boot too:

sudo s6 set enable -I pull foo
sudo s6 set check
sudo s6 set commit
sudo s6 live install
sudo s6 live start foo

10. Making several changes safely

The working set is offline, allowing several changes before one compilation:

sudo s6 set save before-cleanup

sudo s6 set enable -I pull foo
sudo s6 set disable -I pull bar
sudo s6 set mask -I pull unwanted-service

sudo s6 set check
sudo s6 set commit
sudo s6 live install

If s6 set check reports an inconsistency, choose the correction direction deliberately:

# Pull dependencies upward: enable or unmask what is required
sudo s6 set check -F -u

# Push dependents downward: disable or mask what cannot be supported
sudo s6 set check -F -d

Do not run -F blindly. The default downward fix and the optional upward fix express different administrative decisions. (Skarnet)

Restore a saved working set with:

sudo s6 set load before-cleanup
sudo s6 set check
sudo s6 set commit
sudo s6 live install

Loading a saved set changes the offline prescription. It does not alter the live machine until the set is committed and installed. Even then, live states are preserved where possible, so explicitly start or stop services when immediate runtime alignment matters. (Skarnet)

11. Removing a packaged service

Stop the service first:

sudo s6 live stop foo

Remove only its service-definition package:

sudo pacman -R PACKAGE-s6

Then synchronize and install the updated database:

sudo s6 repository sync
sudo s6 repository check
sudo s6 set check
sudo s6 set commit
sudo s6 live install

Removing PACKAGE-s6 normally leaves the application itself installed. Remove PACKAGE separately only when the application is no longer needed.

repository check examines all saved sets, while set check examines the current working set. This distinction matters because a removed service may still be referenced by a saved configuration. (Skarnet)

Do not manually delete package-owned definitions from the package store. Pacman owns those files.


12. Creating a custom system service

A custom system service is appropriate when the daemon should:

  • start before anyone logs in;
  • survive logout;
  • restart after a crash;
  • run under a non-root account;
  • stop cleanly during shutdown.

This is the closest equivalent to a systemd system unit containing User=alice.

Find the administrator store

Inspect storelist:

sudo grep -E \
  '^[[:space:]]*storelist[[:space:]]*=' \
  /etc/s6-frontend.conf

The upstream default administrator store is:

/etc/s6-frontend/s6-rc/sources

Artix may configure a compatibility location such as /etc/s6/adminsv. Use the administrator-owned /etc entry from the installed configuration. Do not edit the package-owned /usr store. (Skarnet)

The examples below use:

LOCAL_STORE=/etc/s6-frontend/s6-rc/sources

Replace that assignment when your configuration names a different administrator store.

Create the daemon definition

This example creates myagent-srv, running as user alice:

sudo install -d -m 0755 \
  "$LOCAL_STORE/myagent-srv" \
  "$LOCAL_STORE/myagent/contents.d"

printf '%s\n' longrun |
  sudo tee "$LOCAL_STORE/myagent-srv/type" >/dev/null

sudo tee "$LOCAL_STORE/myagent-srv/run" >/dev/null <<'EOF'
#!/bin/sh
exec /usr/bin/s6-setuidgid alice \
  /usr/bin/env -i \
    HOME=/home/alice \
    USER=alice \
    LOGNAME=alice \
    PATH=/usr/local/bin:/usr/bin \
    /home/alice/.local/bin/myagent --foreground
EOF

sudo chmod 0755 "$LOCAL_STORE/myagent-srv/run"

Replace:

  • alice with the account that should own the process;
  • /home/alice/.local/bin/myagent with the actual executable;
  • --foreground with the application’s real foreground or no-daemon option.

The final command must remain in the foreground. It must not fork into the background, because s6-supervise needs to remain the parent of the actual daemon. The final exec also ensures that the process being supervised is the daemon rather than an unnecessary shell. s6-setuidgid changes the real and effective UID, GID, and supplementary groups before executing the program. (Skarnet)

Add a bundle

The bundle provides the clean administrative name myagent:

printf '%s\n' bundle |
  sudo tee "$LOCAL_STORE/myagent/type" >/dev/null

sudo touch "$LOCAL_STORE/myagent/contents.d/myagent-srv"

Bundles contain files named after their member services. The files’ contents are irrelevant. (Skarnet)

Add a dependency when one is real

For example, when the executable lives on a separately mounted home filesystem:

sudo s6 set status mount-filesystems

sudo install -d \
  "$LOCAL_STORE/myagent-srv/dependencies.d"

sudo touch \
  "$LOCAL_STORE/myagent-srv/dependencies.d/mount-filesystems"

Only add a dependency after confirming the exact service name exists. Do not copy systemd target names such as network-online.target; s6 dependencies name actual s6-rc services. A file in dependencies.d means the named service must be up before the custom service can be considered for startup. (Skarnet)

Sync, enable, install, and start

sudo s6 repository sync

sudo s6 set status myagent myagent-srv

sudo s6 set enable -n -I pull myagent
sudo s6 set enable -I pull myagent

sudo s6 set check
sudo s6 set commit
sudo s6 live install
sudo s6 live start myagent

Inspect the result:

sudo s6 live status myagent
sudo s6 process status myagent-srv

At this point the service runs as alice, remains independent of Alice’s login session, restarts if it crashes, and is recreated during the next boot.

Editing the service

Edit the persistent source, not /run/service:

sudoedit "$LOCAL_STORE/myagent-srv/run"

Then rebuild and restart:

sudo s6 repository sync
sudo s6 set check
sudo s6 set commit
sudo s6 live install
sudo s6 process restart -w myagent-srv

/run/service and the live s6-rc directories are generated runtime state. Editing them directly creates changes that are transient, inconsistent with the repository, or erased during an update or reboot. (Skarnet)

Removing the custom service

sudo s6 live stop myagent

sudo rm -rf -- \
  "$LOCAL_STORE/myagent" \
  "$LOCAL_STORE/myagent-srv"

sudo s6 repository sync
sudo s6 repository check
sudo s6 set check
sudo s6 set commit
sudo s6 live install

Check the value of LOCAL_STORE before using rm -rf.


13. Translating a systemd unit into an s6 definition

systemd directives6 equivalent
ExecStart=Final exec line in the longrun’s run script
User= and Group=s6-setuidgid or another privilege-dropping tool
Environment=Explicit environment in run, or an env directory
WorkingDirectory=cd in the run script before exec
Requires=Entry in dependencies.d
After=Usually a real dependency or readiness relationship
Restart=alwaysNormal longrun supervision behavior
Type=notifynotification-fd with daemon readiness support
Type=forkingReplace with the daemon’s foreground mode
ExecStop=Normal signal handling, finish, or a separate oneshot
WantedBy=s6 set enable
StandardOutput=journalDedicated logger pipeline or catch-all logger

s6 does not encourage ordering rules that lack an actual dependency. If service A cannot work until B is ready, declare B as a dependency and use readiness notification where necessary. If A merely happened to start after B under systemd, there may be nothing to translate. (Skarnet)

Oneshots

A minimal oneshot source contains:

example-setup/
├── type
├── up
└── down

type contains:

oneshot

up and down contain command lines, for example:

/bin/sh /usr/local/libexec/example-up
/bin/sh /usr/local/libexec/example-down

up is mandatory; down is optional. Although s6-rc parses these files through execline, they may simply invoke ordinary shell scripts. Learning execline is not a prerequisite for basic oneshots. (Skarnet)

14. Logging without journalctl

There is no universal per-service journal database built into s6-frontend. Logs go where the service definition or application sends them.

Artix service packages traditionally provide:

foo-srv → pipe → foo-log → /var/log/foo

The active file in an s6-log directory is normally named current:

sudo tail -F /var/log/foo/current

Inspect the logger independently:

sudo s6 live status foo foo-log
sudo s6 process status foo-srv foo-log
sudo ls -la /var/log/foo

Artix traditionally runs packaged logger processes under the s6log account. To grant a user access where the log group permits it:

sudo usermod -aG s6log "$USER"

Log out and back in for the new supplementary group to apply. (Artix Wiki)

A service without a dedicated logger inherits the supervision tree’s output handling and normally reaches the catch-all logger. For a dedicated logger, define a second longrun using the current s6-rc producer-for, consumer-for, and pipeline-name mechanism. The upstream source-format documentation should be followed rather than copying the older Artix pipeline-line example verbatim. (Skarnet)

15. User services that survive logout and reboot

“User service” can mean two different things:

  1. a system-managed service whose process runs under a user account;
  2. a service managed by an independent supervision tree owned by that user.

The first is simpler. The second gives the user control without sudo.

No process literally survives a reboot. Persistence means that a stored definition causes a new supervised process to be created during the next boot.

Pattern A: system-managed daemon running as a user

The myagent example above already implements this pattern:

root s6-rc database
        ↓
root-owned s6-supervise
        ↓
s6-setuidgid alice
        ↓
Alice's daemon

This is normally the correct design for:

  • Syncthing-style file synchronization;
  • backup servers;
  • local web applications;
  • media indexers;
  • development servers intended to be continuously available;
  • headless agents.

It starts before login, survives logout, runs without root privileges, and restarts after failure. Administration remains a root operation through sudo s6 ....

This pattern is the direct equivalent of a systemd system service containing User=alice. It is not equivalent to systemctl --user.

Pattern B: a true user-controlled s6 tree

A true user tree provides:

system supervision tree
        ↓
user-owned s6-svscan
        ↓
user-owned s6-rc database
        ↓
user services controlled without sudo

The official Artix user-service guide stores user source definitions under:

~/.local/share/s6/sv

and compiled databases under:

~/.local/share/s6/rc

A minimal user longrun looks like this:

~/.local/share/s6/sv/myagent/type
~/.local/share/s6/sv/myagent/run

type:

longrun

run:

#!/bin/sh
exec /home/alice/.local/bin/myagent --foreground

The user’s default bundle can contain the service:

mkdir -p \
  "$HOME/.local/share/s6/sv/default/contents.d"

printf '%s\n' bundle > \
  "$HOME/.local/share/s6/sv/default/type"

touch \
  "$HOME/.local/share/s6/sv/default/contents.d/myagent"

The September 2025 Artix guide states that s6-base provides this helper:

command -v s6-db-reload
s6-db-reload -u

Because the page predates the May 2026 frontend transition, verify that the helper exists on the installed system. Its -u mode compiles and updates the user’s database rather than the root database. The same Artix page documents the manual s6-rc-compile and atomic symlink process when the helper is unavailable. (Artix Wiki)

Make the user tree persistent

A user-owned database alone does not cause anything to start at boot. The official Artix design adds three definitions to the root administrator store:

Root definitionPurpose
local-s6-userStarts s6-svscan under the user account
local-s6-rc-userInitializes the user’s live s6-rc database and starts its default bundle
user-servicesBundle containing the two definitions

The longrun creates a user-owned scan directory under /run, drops privileges with s6-setuidgid, and runs the user’s s6-svscan. The oneshot initializes the user database after the scanner is ready. Because that scanner is itself a child of the root supervision tree, it is respawned if it dies and is not tied to a login shell. (Artix Wiki)

The page writes these definitions under /etc/s6/adminsv. On a current frontend system, put them in the administrator store named by /etc/s6-frontend.conf.

The page’s final root-side commands are legacy. Replace its root s6-db-reload and s6-rc activation with the current frontend sequence:

sudo s6 repository sync

sudo s6 set enable -n -I pull user-services
sudo s6 set enable -I pull user-services

sudo s6 set check
sudo s6 set commit
sudo s6 live install
sudo s6 live start user-services

The root user-services bundle is now part of the boot prescription. During each boot it recreates the user’s supervision tree, which then starts the user’s own default bundle.

Controlling the user tree

The official Artix user recipe uses direct s6-rc commands pointed at the user live directory:

s6-rc -l "/run/$USER/s6-rc" -u change myagent
s6-rc -l "/run/$USER/s6-rc" -d change myagent

s6-rc -l "/run/$USER/s6-rc" -a list

These commands require no root privileges because the user owns that supervision tree and live database. (Artix Wiki)

The frontend can also be configured for the user tree. The s6 command accepts an alternate absolute configuration path through S6_FRONTEND_CONF, while s6-rc explicitly supports non-root users maintaining an alternate repository. Such a configuration must point to the user’s own scandir, livedir, repodir, bootdb, temporary directory, and source store. This is a current upstream capability, but Artix has not yet consolidated it into the official user-service tutorial. (Skarnet)

Environment limitations

A boot-created user tree begins with a clean, deliberately limited environment. It does not naturally inherit the graphical session’s values, such as:

DISPLAY
WAYLAND_DISPLAY
SWAYSOCK
DBUS_SESSION_BUS_ADDRESS

Headless daemons belong in a boot-persistent tree. Programs bound to one graphical login generally belong in the desktop or window-manager startup process, because their sockets and session addresses exist only as part of that session. The Artix user guide explicitly requires values such as HOME, USER, and XDG_RUNTIME_DIR to be supplied when needed. (Artix Wiki)

Removing one user service

As the user:

s6-rc -l "/run/$USER/s6-rc" -d change myagent

rm -rf "$HOME/.local/share/s6/sv/myagent"
rm -f "$HOME/.local/share/s6/sv/default/contents.d/myagent"

s6-db-reload -u

Removing the complete persistent user tree

As root:

sudo s6 live stop user-services

sudo s6 set disable -I pull user-services
sudo s6 set check
sudo s6 set commit
sudo s6 live install

Remove the three root source definitions from the configured administrator store, then synchronize again:

sudo s6 repository sync
sudo s6 repository check
sudo s6 set check
sudo s6 set commit
sudo s6 live install

The user may then remove ~/.local/share/s6 when none of its databases or definitions are needed.


16. Common failures

SymptomCause and correction
unknown serviceThe service is not in the live database. Run repository sync, inspect s6 set status, unmask if needed, then commit and install.
Service is active but downactive is a boot prescription. Start it with s6 live start.
Service is usable but upIt was manually started and will not start automatically next boot.
Killed daemon immediately returnsSupervision is working. Use s6 live stop, not kill.
Restart leaves another service downs6 live restart stopped a reverse dependency but only restarted the explicitly named service.
Custom service exits once per secondIts program exits or daemonizes. Use its foreground mode and final exec.
Changes disappear after rebootThe working set was changed but not committed and installed.
Package installed but service absentInstall its -s6 package and run s6 repository sync.
Service definition edit has no effectEdit the source store, then sync, commit, install, and restart.
Cannot read /var/log/foo/currentCheck ownership and membership in the s6log group.
User service ends with the sessionIt was started from the login session rather than from a root-supervised user tree.
User graphical daemon cannot connectIts boot environment lacks the current display, Wayland, or D-Bus session address.
Masked service cannot startIt is absent from the live database. Unmask, commit, and install first.

These failures all emerge from the same architecture: supervision state, live service-manager state, and offline boot prescription are related, but they are not interchangeable. (Skarnet)

Compact command reference

# Inspect
s6 version
sudo s6 live status
sudo s6 set status -e
sudo s6 live status SERVICE
sudo s6 set status SERVICE
sudo s6 process status SERVICE-SRV

# Runtime
sudo s6 live start SERVICE
sudo s6 live stop SERVICE
sudo s6 live restart -n SERVICE
sudo s6 live restart SERVICE
sudo s6 process restart -w SERVICE-SRV

# Enable at boot
sudo s6 set enable -n -I pull SERVICE
sudo s6 set enable -I pull SERVICE
sudo s6 set check
sudo s6 set commit
sudo s6 live install
sudo s6 live start SERVICE

# Disable at boot
sudo s6 set disable -n -I fail SERVICE
sudo s6 set disable -I fail SERVICE
sudo s6 set check
sudo s6 set commit
sudo s6 live install

# Mask
sudo s6 live stop SERVICE
sudo s6 set mask -I pull SERVICE
sudo s6 set check
sudo s6 set commit
sudo s6 live install

# Unmask
sudo s6 set unmask -I fail SERVICE
sudo s6 set check
sudo s6 set commit
sudo s6 live install

# Service definitions changed
sudo s6 repository sync
sudo s6 repository check
sudo s6 set check
sudo s6 set commit
sudo s6 live install

# Working-set snapshots
sudo s6 set save NAME
sudo s6 set load NAME
sudo s6 set delete NAME

# System control
sudo s6 system reboot
sudo s6 system poweroff
sudo s6 system halt

The native shutdown commands work when the machine uses s6-linux-init and s6-frontend has been configured for it, as Artix’s s6 edition is designed to do. (Skarnet)

Further reading

  1. Current Artix package repository — confirms the versions of s6, s6-frontend, s6-rc, s6-linux-init, and s6-base currently shipped by Artix. (Artix)
  2. s6-frontend overview — the best starting point for understanding why the frontend exists and how offline sets relate to the live database. (Skarnet)
  3. The s6 command — global configuration, alternate configuration files, and the frontend’s major command groups. (Skarnet)
  4. s6 live documentation — runtime status, start, stop, restart, database installation, and the important restart behavior involving reverse dependencies. (Skarnet)
  5. s6 set documentation — enabling, disabling, masking, consistency checks, snapshots, and compilation. (Skarnet)
  6. s6 repository documentation — repository initialization, checks, and synchronization after service-store changes. (Skarnet)
  7. s6 process documentation — direct control of supervised longruns without service-manager dependency transitions. (Skarnet)
  8. s6-rc overview and source format — longruns, oneshots, bundles, dependencies, readiness, logging pipelines, and compilation. (Skarnet)
  9. Supervision and service directories — foreground processes, automatic restarts, privilege dropping, environment setup, and runtime files. (Skarnet)
  10. Artix s6 wiki — useful for Artix architecture, package conventions, and traditional logging layout, but its day-to-day commands predate s6-frontend. (Artix Wiki)
  11. Artix local user-services guide — the complete root-supervised user-tree design, including the local-s6-user, local-s6-rc-user, and user-services definitions. Its root activation commands should be translated to the current frontend sequence shown above. (Artix Wiki)