Greetd + Sway + Alpine

2021-06-21

In this post, I’ll go step by step on how to install and use greetd with Sway on Alpine Linux. The greetd project is fairly new so documentation is sparse. Hopefully, this will help others on their journey towards a lightweight and modern desktop environment.

While there are other greeters/login managers that might work. Alot of them depend on their respective desktop environment frameworks. For example, the Alpine package for gdm3 will install 200 dependencies. Assuming you haven’t installed gnome yet. Well, I’m not running Gnome. I’m running Sway. I don’t want all those Gnome dependencies if I don’t really need them. Unfortunately, those extra packages are the backbone of the current modern Linux desktop experience. This post is part of my journey at providing a modern feel, without all of that extra stuff.

Another thing to note is that there is a package for greetd on Alpine. As of now, it is still in testing. Also, there is some extra configuration on the user’s end that has to be done, which I will go over later. So this post will be useful in the future even when the package stabilizes.

In addition to greetd, I’ll also be going over how to install gtkgreet to get a nice GUI login manager. We will be building both greetd and gtkgreet by source, so buckle up!

greetd

Alpine Packages

sudo apk add cargo linux-pam-dev

greetd is written in Rust, so we’ll need cargo. pam is the Linux authentication module used when we login. Basically, the thing that checks the username and password.

Install greetd

Go to the greetd repository, download the latest ref, and decompress it. You’ll then build greetd like any other Rust project.

cargo build --release

This will install necessary rust crates and compile the binary. I would like to point out, as far as Rust projects go, greetd doesn’t have that many dependencies. Props to the author for that.

Once the binary is compiled we need to place it onto our path.

sudo cp target/release/greetd /usr/local/bin/
sudo mkdir /etc/greetd
sudo cp config.toml /etc/greetd/config.toml

I’ll be going over some modifications to the config.toml file in the gtkgreet section. The defualt config.toml will work if you only want a terminal based login session. You will also need to place agreety on your path as well.

sudo cp target/release/agreety /usr/local/bin

There is no harm in having agreety, however, if you want to have a GUI greeter, you wont need this.

Now we need to create the greeter user which will run the greeter program when we login.

sudo useradd -M -G video greeter
sudo chown -R greeter:greeter /etc/greetd/

This is good because we don’t want root to be doing this.

Setting up greetd as an openrc service wasn’t documented, so that was interesting to figure out. The openrc docs are not exactly intuitive. However, I was able to make one based on other examples and a little bit of trial and error. The final product is actually quite simple. Basically we need to make a shell script in /etc/init.d. That directory is where openrc will look for available services.

sudo vi /etc/init.d/greetd

All we need for the shell script is this:

#!/sbin/openrc-run

name="$RC_SVCNAME"
command=/usr/local/bin/greetd

pidfile="/var/run/$RC_SVCNAME.pid"
command_background="yes"

stop() {
       kill `cat /var/run/$RC_SVCNAME.pid`
}

I’m not going to claim to be an expert, so feel free to let me know if I can improve this. Overall this works pretty well.

One can get away with just the command field. However, what I found was that it didn’t allow poweroff and reboot commands to work without forcing those commands. To mitigate this, the script enables direct process control. Hence, the other config details are related to managing the greetd process itself.

Ensure you make the script executable.

sudo chmod +x /etc/init.d/greetd

The last step is to enable the greetd service with openrc.

sudo rc-update add greetd

If you only want a terminal greeter than stop here and reboot. If you would like a GUI greeter then continue.

Before we go about rebooting, we need to setup our GUI greeter program.

gtkgreet

Install necessary Alpine packages.

sudo apk add gtk-layer-shell-dev gtk+3.0-dev json-c-dev meson gcc musl-dev

Download the latest ref from the gtkgreet repository, decompress it, and compile it.

Now build and install the project.

meson build
ninja -C build
sudo ninja -C build install

Easy enough right?! Well the configuration is where things get interesting.

First we need to update /etc/greetd/config.toml.

[terminal]
# The VT to run the greeter on. Can be "next", "current" or a number
# designating the VT.
vt = 1

# The default session, also known as the greeter.
[default_session]

# `agreety` is the bundled agetty/login-lookalike. You can replace `$SHELL`
# with whatever you want started, such as `sway`.
command = "sway --config /etc/greetd/sway-config -d 2> /etc/sway/sway.log"

# The user to run the command as. The privileges this user must have depends
# on the greeter. A graphical greeter may for example require the user to be
# in the `video` group.
user = "greeter"

The main change is the command field. Here we are starting sway with a custom config script.

The script is located at /etc/greetd/sway-config. It looks like this:

# `-l` activates layer-shell mode. Notice that `swaymsg exit` will run after gtkgreet.
exec "gtkgreet -l; swaymsg exit"

bindsym Mod4+shift+e exec swaynag \
-t warning \
-m 'What do you want to do?' \
-b 'Poweroff' 'sudo poweroff' \
-b 'Reboot' 'sudo reboot'

include /etc/sway/config.d/*

Make sure that your greeter user has the ability to be sudo without a password. Personally, I’m using doas, so the config is a bit different.

The final thing we need to do is list the environments that we can start up.

In /etc/greetd/environments do something like this:

sway
bash

Okay so we are almost done! If we run everything as is, we will get a bunch of warning’s coming from sway about dbus sessions and stuff. We need to start sway with a dbus session to remedy that.

Luckily, I was able to find a script here which does just the trick. Thanks Void Linux peoples!

# Session
export XDG_SESSION_TYPE=wayland
export XDG_SESSION_DESKTOP=sway
export XDG_CURRENT_DESKTOP=sway

# D-Bus
# If the session bus is not available it is spawned and wrapper round our program
# Otherwise we spawn our program directly
drs=
if [ -z "${DBUS_SESSION_BUS_ADDRESS}" ]
then
   drs=dbus-run-session
fi

# Environment
# Source environmental variable from all files in PATH_ENVIRONMENT
# file should be named *.conf and have KEY=value format use # for comment
PATH_ENVIRONMENT=$HOME/.config/environment.d
if [ -d "$PATH_ENVIRONMENT" ]; then
  for i in "$PATH_ENVIRONMENT"/*.conf ; do
      if [ -f "$i" ]; then
        set -a; . "$i"; set +a
      fi
  done
fi

exec ${drs} sway "$@"

Place this script on your path. For example: /usr/local/bin/sway-run

Then make sure to add sway-run to /etc/greetd/environments, so it ends up something like this:

sway-run
bash

Finally, you can reboot, login with gtkgreet, and then access Sway!

Now your friends won’t make fun of you for logging in with just a terminal.


Enter your instance's address