Minimal Ubuntu and i3 Setup
Here are notes I wrote down for setting up a minimal Ubuntu installation on a laptop, with i3 as the tiling window manager.
Why Ubuntu?
There are a plethora of linux distributions. Initially I wanted to use Debian because of its stability. The primarily purpose of this installation is to act as a host OS for multiple guest VMs. However, I decided to go with Ubuntu because of the vast community support and resources available online.
Why Ubuntu server?
Wanted to install the “desktop” libraries myself instead of using the default ones in the Ubuntu Desktop installer. Should be fine since from Ubuntu 12 onwards, desktop and server versions use the same kernel.
Pre-requisites
- Ethernet connection (otherwise might run into wifi issues with Ubuntu Server installation)
Install Ubuntu Server
Download installer.
- First we need to download the installer. While we can use the main installer, the alternative installer allows us to do extra operations such as reusing partitions, which is what I needed.
- I recommend just installing the alternative installer.
Walk through installer, Make a root (/) and home (/home) partition.
Reboot
Network (Optional)
Feel free to skip this section if you don’t need WiFi.
Switching from Ethernet to WiFi
There are many ways to configure wifi. Let’s pick the easiest approach and install the network-manager
to help us configure wifi connection. Install the package and enable the service:
sudo apt install network-manager
sudo systemctl start NetworkManager.service
sudo systemctl enable NetworkManager.service
Disable systemd-networkd-wait-online check
Now that we have WiFi configured, we can ditch our ethernet connection and remove the cable. However now the wait-online
service/daemon will hang during startup (probably because its looking for the ethernet connection). To avoid waiting too long (~2 minutes for me), let’s disable the service:
systemctl disable systemd-networkd-wait-online.service
and also prevent other services from starting it:
systemctl mask systemd-networkd-wait-online.service
Reference:
Keyboard and Shell (optional):
Again, feel free to skip these if you satisfied with the current keyboard and shell. However in my opinion, the modifications below improve the experience of editing files in the terminal.
Keyboard
Personally I prefer switching CapsLock key with the left CTRL key. We can do that by modifying /etc/default/keyboard
:
XKBOPTIONS="ctrl:swapcaps"
If too lazy to manually edit file, run this command:
sudo sed -i 's/XKBOTPIONS=""/XKBOPTIONS="ctrl:swapcaps"' /etc/default/keyboard
sed
replaces lines that match the pattern. i.e.s/<text_to_replace>/<replacement_text>/
.-i
saves the result into the same input file. Otherwise, by default, the result ofsed
are piped to stdout.
Change Shell
I prefer using zsh
instead of bash for its auto completion features. Let’s install that right now:
sudo apt install zsh
Run zsh:
zsh
Follow prompt to save options. Example resulting .zshrc
:
# Lines configured by zsh-newuser-install
HISTFILE=~/.histfile
HISTSIZE=1000
SAVEHIST=1000
setopt appendhistory autocd beep extendedglob nomatch
unsetopt notify
bindkey -e
# End of lines configured by zsh-newuser-install
# The following lines were added by compinstall
zstyle :compinstall filename '/home/ren/.zshrc'
autoload -Uz compinit
compinit
# End of lines added by compinstall
Finally, let’s change the default shell to zsh:
chsh -s /bin/zsh
Then logout
and login to see changes.
Install Desktop
That was a lot of commands if you went through the optional sections; more is yet to come! Now let’s get started on the main task of configuring a lightweight desktop.
X Window System
We’ll need a display server so let’s install the one most widely used; Xorg:
sudo apt install xinit
Notes:
- Configuration files are stored in
/etc/X11/xinit/
. - If
~/.xinitrc
is not specified,/etc/X11/xinit/xinitrc
will run.- Same override logic applies for
~/.xserverrc
.
- Same override logic applies for
For now, we don’t have to worry about adding any configuration for X.
Reference:
Adding a terminal emulator
Because we plan on using a terminal in a GUI environment, we need to install a terminal emulator.
There are so many terminal emulators out there, all with varying degrees of features, quality, pouplarity, maintainability, etc. I suggest doing some research if you have the time and care strongly about which one to use.
I pesonally picked rxvt-unicode
.
Changing terminal colors and font (Optional)
We can make the terminal easier on the eyes with base 16 color scheme. I You can choose whichever colour shceme you want; I chose solarized-dark-256
.
Let’s fetch the dark color scheme and save it as ~/.Xresources
:
curl https://raw.githubusercontent.com/chriskempson/base16-xresources/master/xresources/base16-solarized-dark-256.Xresources >> ~/.Xresources
xrdb -load ~/.Xresources
And change the default font type and size by appending this to ~/.Xresources
:
URxvt.font: xft:DejaVuSansMono:size=10
Tiling Window Manager
Now we finally get to installing the tiling window manager!
Similar to the situation with terminal emulators, there are quite a few window managers to choose from. I chose i3 because of its been in use for awhile, is well-known, and extensible (also easy potential migration to sway for future Wayland support).
sudo apt install i3
Now start X
:
startx
There will be prompts to create a config file, and to choose which key as your
Exiting i3
To exit i3, press <mod>-<shift>-e
. Pressing ‘Yes’ with the mouse will stop the session.
If you didn’t install a terminal emulator previously, you might be frustrated that pressing the button doesn’t do anything. In this case, you’ll have to either: - Force shutdown and boot up your computer via power management (e.g, press and hold power button) - Go to another tty
(virtual terminal) via <ctrl>-<alt>-<f2...?>
and login. For my laptop, Fn2…Fn6 corresponds to tty2…tty6.
Improving the desktop experience (Optional, but recommended):
We officially have a minimal functioning desktop! However we’re missing a few common functionality that one expects from a desktop environment (screen brightness, sound, volume, etc.).
Here are some optional configuration for a better user experience.
Note:
- can use
xev
to figure out keycodes of function keys. - Reload i3 config with
<mod>+shift+c
to test changes.
Screen Backlight
Now that we have i3 installed, we can add key bindings to adjust screen brightness.
First lets download and install a program to control backlights.
There is no package available in the main ubuntu repositories, so we have to download from github before installing:
curl -O -L https://github.com/haikarainen/light/releases/download/v1.2/light_1.2_amd64.deb
sudo dpkg -i light_1.2_amd64.deb
Unfortunately, at the time of writing, the debian package incorrectly installs the udev rules. However, this will be fixed in the latest release. Meanwhile, we can simply move the udev rules file over:
sudo mv /usr/lib/udev/rules.d/90-backlight.rules /lib/udev/rules.d/90-backlight.rules
Next, we can add the following keybindings to ~/.config/i3/config
:
# increase brightness
bindsym XF86MonBrightnessUp exec "light -A 5"
# decrease brightness
bindsym XF86MonBrightnessDown exec "light -U 5"
reboot
your computer to see the changes.
Screen Color Temperature
If the screen colors are bothering your eyes, we can adjust the color temperature with a program such as redshift:
sudo apt install redshift
Because redshift currently does not prepackage a systemd service file, we need to write our own.
Alternatively, we can simply start redshift when i3 is loaded. Add the following to the bottom of .config/i3/config
:
exec --no-startup-id redshift
Reference:
- https://brokkr.net/2016/09/21/a-systemd-service-unit-for-redshift/
- https://i3wm.org/docs/userguide.html#_automatically_starting_applications_on_i3_startup
Lock screen/sleep
i3
comes with i3lock
, which we can run on command line to bring up a lock screen. However, it would be nice if we could:
- lock screen when computer goes to sleep
- make sure locker doesn’t stay on forever (to avoid battery drain)
First let’s create the script to lock the screen. We’ll use the included i3lock
locker. We also set dpms to reduce screen power consumption.
Create ~/.config/i3/lock.sh
with the contents:
#!/bin/sh
set -e
xset s off dpms 0 10 0
i3lock --color=333333 --ignore-empty-password --show-failed-attempts --nofork
xset s off -dpms
Dont’ forget to make it executable:
sudo chmod +x ~/.config/i3/lock.sh
Now let’s install xss-lock
, which simplifies hooking up locker program to events from X screen saver and systemd’s login manager.
sudo apt install xss-lock
Lastly, modify ~/.config/i3/config
:
exec --no-startup-id xss-lock -- ~/.config/i3/lock.sh
Optionally, we can also add a keybinding for locking screen: (I chose a function key)
bindsym XF86Tools exec --no-startup-id sleep 1 && xset dpms force suspend
Reference:
- Thanks to _tkmn for solution from a Reddit thread:https://www.reddit.com/r/i3wm/comments/9ebemt/locking_i3_when_lid_of_laptop_is_closed/
External Monitor
For configuring screen layouts (including adding an external monitor), we can use xrandr
for configuring display output(s).
We can use xrandr
on CLI, but personally, I think a GUI would be easier to use for this type of task. We’re going to install arandr
:
sudo apt install arandr
arandr
Sound
If we want sound, we can install Pulseaudio, which architectually sits atop of ALSA.
The PulseAudio Volume Control GUI is convenient to use, so let’s install it:
sudo apt install pavucontrol
Add keybindings to ~/.config/i3/config
:
# increase volume
bindsym XF86AudioRaiseVolume exec "pactl set-sink-mute 0 false ; pactl set-sink-volume 0 +5%"
# decrease volume
bindsym XF86AudioLowerVolume exec "pactl set-sink-mute 0 false ; pactl set-sink-volume 0 -5%"
# mute volume
bindsym XF86AudioMute exec "pactl set-sink-mute 0 toggle"
Test volume:
speaker-test
Note:
- Some apps, such as
firefox
, might requirepulseaudio
.
Autostart X after logging in on tty
It can be tedioius to always type startx
when we login to our computer. We can write some small shell code to run the command on startup.
Add the following .bash_profile
or .zprofile
, depending on which shell you use:
if [[ ! $DISPLAY && $XDG_VTNR -eq 1 ]]; then
startx
fi
After exiting i3, user will remain logged in. If we don’t want to remain logged in, then use exec startx
instead of startx
.
Reference:
Summary
This took longer than I thought it would, but now we have a custom, minimal, ubuntu distro on our laptop. Installing the distro and the tiling window manager was enough to have a bare, usable desktop. However, a lot more work was required to get closer to a typical desktop environment (wifi, adjusting screen, etc.).
Hopefully these notes are helpful in setting up your minimal desktop environment! Next time, we’ll look into setting up ZFS and KVM together for managing virtual machines.