You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
799 lines
23 KiB
799 lines
23 KiB
---
|
|
gitea: none
|
|
include_toc: true
|
|
---
|
|
|
|
# linux-on-desktop
|
|
|
|
My journey to get Alpine + Wayland + River to work on ThinkPad T14 G3 AMD (21CF004PGE)
|
|
|
|
## Preparing hardware
|
|
|
|
Disable secure boot and fn-lock in bios (so that F-keys work as F-keys by default and require Fn for their secondary multimedia functions).
|
|
|
|
## Installing Alpine
|
|
|
|
Follow https://wiki.alpinelinux.org/wiki/Installation
|
|
|
|
Note that you will need to use Rufus; Ventoy does not work on this laptop (hangs after choosing the image).
|
|
|
|
## Postinstall
|
|
|
|
In `/etc/apk/repositories`, comment out 3.16, uncomment edge (main, community, testing),
|
|
since some of the packages we're going to install (river, element-desktop)
|
|
only exist in testing.
|
|
|
|
Then
|
|
```
|
|
doas apk update
|
|
doas apk upgrade
|
|
```
|
|
|
|
## Usable editor by default (not vi)
|
|
|
|
```
|
|
doas apk add micro
|
|
echo "export EDITOR=micro" >>.profile
|
|
echo "permit setenv { EDITOR=\$EDITOR } nopass :wheel as root" | tee -a /etc/doas.d/doas.conf
|
|
```
|
|
|
|
## Installing river
|
|
|
|
```
|
|
doas apk add eudev
|
|
doas setup-udev
|
|
doas apk add mesa-dri-gallium mesa-va-gallium
|
|
doas apk add river river-doc mandoc
|
|
doas apk add adwaita-icon-theme foot ttf-dejavu
|
|
doas rc-update add seatd
|
|
doas rc-service seatd start
|
|
doas addgroup YOURUSER audio
|
|
doas addgroup YOURUSER input
|
|
doas addgroup YOURUSER seat
|
|
doas addgroup YOURUSER video
|
|
doas addgroup YOURUSER wheel
|
|
install -Dm0755 /usr/share/doc/river/examples/init -t ~/.config/river
|
|
```
|
|
|
|
Also:
|
|
```
|
|
doas apk add xwayland
|
|
```
|
|
because the latest river in testing is built in a way that requires xwayland.
|
|
|
|
Try to run with
|
|
```
|
|
XDG_RUNTIME_DIR=/tmp river
|
|
```
|
|
|
|
You should see the blue screen of river. Try to open terminal with Win+Shift+Enter. Try to exit with Win+Shift+E.
|
|
|
|
### Login manager
|
|
|
|
To enter username/password in GUI, get to river after that, and get back to logon screen after exiting river:
|
|
|
|
```
|
|
doas apk add elogind polkit-elogind
|
|
doas rc-update add elogind
|
|
doas rc-service elogind start
|
|
doas apk add greetd greetd-gtkgreet cage
|
|
doas addgroup greetd video
|
|
doas rc-update add greetd
|
|
```
|
|
|
|
change `/etc/greetd/config.toml`
|
|
|
|
```
|
|
command = "cage -s -- gtkgreet"
|
|
```
|
|
|
|
and create `/etc/greetd/environments` with a single line `river`
|
|
|
|
and reboot.
|
|
|
|
I didn't find a way to make cage+gtkgreet handle HiDPI, the text is very tiny.
|
|
|
|
An alternative is agreety, but for some reason it seems that both greeter and standard linux login prompt
|
|
run at the same time on the same terminal, making it impossible to actually login.
|
|
|
|
### Installing Waybar
|
|
|
|
```
|
|
doas apk add waybar font-roboto
|
|
```
|
|
|
|
and add startup section at the end of river init file (`~/.config/river/init`):
|
|
|
|
```
|
|
# startup
|
|
riverctl spawn "waybar"
|
|
```
|
|
|
|
For time to work,
|
|
```
|
|
doas apk add tzdata
|
|
```
|
|
|
|
For icons to work,
|
|
```
|
|
doas apk add font-roboto
|
|
```
|
|
(do not add `font-awesome`, for some reason it looks awful, kerning is terrible, and the text is all-caps in waybar with it)
|
|
|
|
### HiDPI
|
|
|
|
```
|
|
doas apk add kanshi
|
|
mkdir .config/kanshi
|
|
```
|
|
|
|
and create `.config/kanshi/config` with the following:
|
|
```
|
|
profile {
|
|
output eDP-1 enable scale 2.5
|
|
}
|
|
```
|
|
|
|
(`eDP-1` identifier was obtained by installing sway, running sway (by adding it to `/etc/greetd/environments`,
|
|
and in terminal inside sway executing `swaymsg -t get_outputs`).
|
|
|
|
#### HiDPI - cursors
|
|
|
|
And in order to have decently sized mouse cursors instead of the tiniest ones, add the following line to the top of `.config/river/init`:
|
|
|
|
```
|
|
riverctl xcursor-theme Adwaita 24
|
|
```
|
|
|
|
This will only affect river itself, the cursor will stay tiny in waybar and firefox and maybe other applications. To solve this:
|
|
```
|
|
doas apk add gsettings-desktop-schemas
|
|
gsettings set org.gnome.desktop.interface cursor-theme 'Adwaita'
|
|
```
|
|
|
|
#### HiDPI - terminal
|
|
|
|
In terminal (not in terminal emulator in WM; you can always switch to the new terminal with Ctrl+Alt+F2)
|
|
```
|
|
doas apk add terminus font
|
|
setfont /usr/share/console-fonts/ter-132n.psf.gz
|
|
```
|
|
|
|
If it looks decent: change consolefont in `/etc/conf.d/consolefont` to `"ter-132n.psf.gz"` and `doas rc-update add consolefont boot`
|
|
|
|
**Note that this will break your login manager for some reason**
|
|
|
|
### Environment
|
|
|
|
In order to not have to create wrapper scripts for all apps:
|
|
|
|
Create `/usr/local/bin/inga-river` (and later `chmod +x /usr/local/bin/inga-river`) with the following (found in google):
|
|
|
|
```
|
|
#!/bin/sh
|
|
|
|
export GDK_BACKEND=wayland,x11
|
|
export MOZ_ENABLE_WAYLAND=1
|
|
export CLUTTER_BACKEND=wayland
|
|
export QT_QPA_PLATFORM=wayland-egl
|
|
export ECORE_EVAS_ENGINE=wayland-egl
|
|
export ELM_ENGINE=wayland_egl
|
|
export SDL_VIDEODRIVER=wayland
|
|
export _JAVA_AWT_WM_NONREPARENTING=1
|
|
export NO_AT_BRIDGE=1
|
|
export BEMENU_BACKEND=wayland
|
|
|
|
river $@
|
|
```
|
|
|
|
and replace `river` with `inga-river` in `/etc/greetd/environments`.
|
|
|
|
### Keyring
|
|
|
|
`doas apk add gnome-keyring`
|
|
|
|
Add following lines to `/usr/local/bin/inga-river` before the call to river:
|
|
|
|
```
|
|
eval $(gnome-keyring-daemon)
|
|
export SSH_AUTH_SOCK
|
|
```
|
|
|
|
Reboot, login, make sure with `ps aux | grep key` that keyring daemon is running.
|
|
|
|
### Sudo for GUI apps
|
|
|
|
`doas apk add -s polkit-gnome`, and add `riverctl spawn /usr/lib/polkit-gnome/polkit-gnome-authentication-agent` to your river config.
|
|
|
|
### Launcher
|
|
|
|
`doas apk add bemenu`, and then add this line into your river config:
|
|
|
|
```
|
|
riverctl map normal Super R spawn 'pidof bemenu-run || bemenu-run -i -n'
|
|
```
|
|
|
|
### Screenshots
|
|
|
|
`doas apk add wayshot`, then add this line to river config:
|
|
```
|
|
riverctl map normal None Print spawn 'wayshot --stdout | wl-copy'
|
|
```
|
|
|
|
### Clipboard
|
|
|
|
Works by default, use Ctrl+Shift+C and Ctrl+Shift+V in foot
|
|
|
|
### Emoji keyboard
|
|
|
|
`doas apk add rofi-emoji rofi-emoji-wayland wtype font-noto-emoji` and add this line to your river config
|
|
```
|
|
riverctl map normal Super period spawn 'rofi -modi emoji -show emoji'
|
|
```
|
|
|
|
(For some reason it broke after reboot and only copies things to clipboard, even though `wtype` continues to work without any problems)
|
|
|
|
### Notifications
|
|
|
|
```
|
|
doas apk add dunst
|
|
dunst &
|
|
dunstify test
|
|
```
|
|
You should get a notification with the text "test".
|
|
|
|
Then add `riverctl spawn "dunst"` to the startup section of your river config.
|
|
|
|
TODO: [wired-notify](https://github.com/Toqozz/wired-notify) instead of dunst (currently not packaged for alpine)
|
|
|
|
## Other software
|
|
|
|
### Firefox
|
|
|
|
```
|
|
doas apk add firefox
|
|
firefox
|
|
```
|
|
go to `about:support` and make sure that Window Protocol is wayland, not xwayland.
|
|
(it should be wayland because MOZ_ENABLE_WAYLAND is set to 1 by inga-river)
|
|
|
|
For some reason, while sound in general works fine in firefox (after following the steps from Hardware section),
|
|
in WebRTC pages there is crackling much louder than the actual voices, making it unusable for voice/video calls/meetings.
|
|
|
|
### Chrome
|
|
|
|
```
|
|
doas apk add chromium
|
|
```
|
|
|
|
It should also be wayland by default, but you can check it by `doas apk add xeyes && xeyes`.
|
|
|
|
In order for screen sharing to work, go to `chrome://flags/#enable-webrtc-pipewire-capturer` and enable it.
|
|
Note though that every time you screenshare, there will be two promps from xdg-desktop-portal, one for picking a source, and another for actually sharing.
|
|
|
|
### Yubikey
|
|
|
|
```
|
|
doas apk add yubikey-manager
|
|
doas addgroup YOUR_USER plugdev
|
|
```
|
|
(not sure if the two commands above are necessary)
|
|
|
|
Then:
|
|
```
|
|
doas rc-service pcscd start
|
|
doas rc-update add pcscd
|
|
```
|
|
|
|
Yubikey should work in Chrome
|
|
|
|
### Archives
|
|
|
|
`apk install ouch` to avoid having to remember `tar` flags etc, and instead do `ouch decompress archive.tar.gz` (for any archive format).
|
|
|
|
### Git
|
|
|
|
```
|
|
doas apk install git
|
|
git config --global credential.helper --store
|
|
```
|
|
|
|
### Telegram
|
|
|
|
```
|
|
doas apk install telegram-desktop
|
|
```
|
|
|
|
### Element
|
|
|
|
```
|
|
doas apk install element-desktop
|
|
```
|
|
|
|
## Hardware
|
|
|
|
### Sleep
|
|
|
|
With default settings, laptop goes to sleep after some idle period. When it wakes up, the root fs is readonly, meaning that I have to restart the laptop.
|
|
|
|
Adding `acpiphp.disable=1` and `pcie_aspm=off` to grub config does not solve the issue.
|
|
|
|
Disabling S0ix in UEFI only made things worse: even though `cat /sys/power/mem_sleep` reported that S3 (deep) is default,
|
|
after system goes to sleep it is impossible to wake it up, it does not react to key or power button presses.
|
|
|
|
What did solve the issue was:
|
|
* reenable S0ix in BIOS,
|
|
* `doas apk add linux-firmware-amdgpu`,
|
|
* editing `GRUB_CMDLINE_LINUX_DEFAULT` in `/etc/default/grub` to add the following options:
|
|
`acpiphp.disable=1 pcie_aspm=off acpi_osi='Windows 2020' iommu=soft`.
|
|
|
|
Now after waking up (after being suspended with `doas pm-suspend` from `pm-utils` package) root fs is still readwrite.
|
|
But sometimes network disappears after wakeup.
|
|
|
|
For suspend on lid close and unsuspend on open, follow https://wiki.alpinelinux.org/wiki/Suspend_on_LID_close :
|
|
```
|
|
doas mkdir -p /etc/acpi/LID
|
|
doas micro /etc/acpi/LID/00000080
|
|
```
|
|
should have the following content
|
|
```
|
|
#!/bin/sh
|
|
exec pm-suspend
|
|
```
|
|
and then
|
|
```
|
|
doas chmod +x /etc/acpi/LID/00000080
|
|
doas rc-service acpid restart
|
|
```
|
|
|
|
### WiFi
|
|
|
|
At the moment Linux kernel does not support Qualcomm NFA725.
|
|
|
|
Otherwise, alpine wiki describes how to configure WiFi using `iwd`.
|
|
|
|
### Backlight
|
|
|
|
```
|
|
doas apk add light
|
|
doas micro /etc/udev/rules.d/backlight.rules
|
|
```
|
|
add the following lines into backlight.rules to make it possible for all users in video group (not just superusers) to control backlight:
|
|
```
|
|
ACTION=="add", SUBSYSTEM=="backlight", KERNEL=="amdgpu_bl0", RUN+="/bin/chgrp video /sys/class/backlight/%k/brightness"
|
|
ACTION=="add", SUBSYSTEM=="backlight", KERNEL=="amdgpu_bl0", RUN+="/bin/chmod g+w /sys/class/backlight/%k/brightness"
|
|
```
|
|
and then
|
|
```
|
|
doas rc-service udev restart
|
|
```
|
|
Backlight control with Fn+F5/F6 should work now.
|
|
|
|
(`amdgpu_bl0` is specific for this laptop; value for others can be obtained from `/sys/class/backlight/`)
|
|
|
|
### Trackpoint
|
|
|
|
Disregard this:
|
|
|
|
> ```
|
|
>find /sys/devices/platform/i8042/ -name name | xargs grep -Fl TrackPoint
|
|
> ```
|
|
> to find which serio corresponds to trackpoint, then
|
|
> ```
|
|
> echo 70 | doas tee /sys/devices/platform/i8042/serio1/sensitivity
|
|
> ```
|
|
> for reasonably low sensitivity (does not persist; for persistence TODO separate udev rule).
|
|
|
|
Instead of configuring sensitivity, it's probably better to configure pointer speed in river.
|
|
|
|
Find your trackpoint with `riverctl list-inputs | grep -i trackpoint`,
|
|
it will look like `2:10:TPPS/2_Elan_TrackPoint`.
|
|
|
|
Then add the following to your river config:
|
|
```
|
|
riverctl input 2:10:TPPS/2_Elan_TrackPoint accel-profile adaptive
|
|
riverctl input 2:10:TPPS/2_Elan_TrackPoint pointer-accel -0.5
|
|
```
|
|
|
|
### Sound
|
|
|
|
Based on https://wiki.alpinelinux.org/wiki/PipeWire
|
|
|
|
```
|
|
doas apk add dbus dbus-openrc
|
|
doas rc-service dbus start
|
|
doas apk add pipewire wireplumber rtkit alsa-utils pipewire-alsa
|
|
doas addgroup YOURUSER rtkit
|
|
doas addgroup root audio
|
|
alsamixer
|
|
```
|
|
|
|
In alsamixer, use F6 to find the target sound card (most likely 0 is HDMI and 1 is ordinary).
|
|
Remember its number, and in `/usr/share/alsa/alsa.conf`,
|
|
replace `defaults.ctl.card` and `defaults.pcm.card` with the target number.
|
|
|
|
In `/usr/local/bin/inga-river`, replace `river $@` with `dbus-run-session -- river $@`,
|
|
relogin (Ctrl+Shift+E).
|
|
|
|
Then
|
|
```
|
|
doas rc-service alsa start
|
|
doas rc-update add alsa
|
|
/usr/libexec/pipewire-launcher
|
|
```
|
|
|
|
Make sure that everything works (with `wpctl status`, `pw-cat -p YOURFILE.flac`
|
|
or just opening YouTube in FF).
|
|
|
|
Then make pipewire start automatically: in river config, add another startup line:
|
|
```
|
|
riverctl spawn "/usr/libexec/pipewire-launcher"
|
|
```
|
|
|
|
Control microphone and volume with `alsamixer`.
|
|
And change the handlers for XF86Audio (adding `-repeat` and replacing the spawned command):
|
|
```
|
|
riverctl map -repeat $mode None XF86AudioRaiseVolume spawn 'amixer set "Master" 5%+'
|
|
riverctl map -repeat $mode None XF86AudioLowerVolume spawn 'amixer set "Master" 5%-'
|
|
riverctl map $mode None XF86AudioMute spawn 'amixer set "Master" toggle'
|
|
```
|
|
|
|
Note that the internal microphone does not work and is not detected by pipewire.
|
|
Only external microphones work.
|
|
|
|
Mic in browser didn't work, but then it started to work at some point,
|
|
without me seemingly changing anything.
|
|
|
|
#### Mic mute button
|
|
|
|
Create `/etc/acpi/events/lenovo-mutemic` with the following content:
|
|
```
|
|
event=button/micmute MICMUTE 00000080 00000000 K
|
|
action=amixer --card 1 set 'Capture' toggle
|
|
```
|
|
where card number is the one obtained in previous section; and event could be determined by running `acpi_listen` and pressing mic button.
|
|
|
|
Then, after `doas rc-service acpid restart`, mic button should control internal mic capture in alsa and switch internal mic led on and off.
|
|
|
|
### Webcam
|
|
|
|
Should work after following the steps for "Audio".
|
|
|
|
Can be tested in https://webrtc.github.io/test-pages
|
|
|
|
## Additional
|
|
|
|
### Screen sharing
|
|
|
|
```
|
|
doas apk add xdg-desktop-portal xdg-desktop-portal-wlr
|
|
```
|
|
|
|
Create `/usr/local/bin/inga-xdg-desktop-portal-wlr` with the following:
|
|
|
|
```
|
|
#!/bin/sh
|
|
killall /usr/libexec/xdg-desktop-portal
|
|
killall /usr/libexec/xdg-desktop-portal-wlr
|
|
/usr/libexec/xdg-desktop-portal-wlr
|
|
```
|
|
|
|
and to your river config
|
|
```
|
|
riverctl spawn "inga-xdg-desktop-portal-wlr"
|
|
```
|
|
|
|
(for some reason `xdg-desktop-portal` gets started automatically and after that newly started xdg-desktop-portal-wlr does not work;
|
|
we need to kill that xdg-desktop-portal first)
|
|
|
|
### Prevent firefox sharing indicator from taking the entire tile
|
|
|
|
Add the following lines to river config (before the last `exec` line):
|
|
|
|
```
|
|
riverctl float-filter-add title "Firefox — Sharing Indicator"
|
|
riverctl float-filter-add title 'Firefox — Sharing Indicator'
|
|
```
|
|
|
|
(TODO: check which kind of quotes works)
|
|
|
|
## Development (containers)
|
|
|
|
### Unprivileged LXC with routing
|
|
|
|
(based partially on https://linuxcontainers.org/lxc/getting-started and https://wiki.alpinelinux.org/wiki/LXC)
|
|
|
|
#### Networking (host)
|
|
|
|
(assuming that your internet-connected interface is eth0,
|
|
and that you want to use 10.157.1.0/24 subnet for the container)
|
|
|
|
Add the following to `/etc/network/interfaces`:
|
|
```
|
|
auto br0
|
|
iface br0 inet static
|
|
bridge-ports dummy0
|
|
bridge-stp 0
|
|
address 10.157.1.1
|
|
netmask 255.255.255.0
|
|
```
|
|
|
|
and do
|
|
|
|
```
|
|
doas apk add bridge
|
|
doas modprobe dummy
|
|
echo dummy | doas tee -a /etc/modules
|
|
echo 1 | doas tee -a /proc/sys/net/ipv4/ip_forward
|
|
doas apk add iptables
|
|
doas rc-update add iptables
|
|
doas iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE
|
|
doas iptables --append FORWARD --in-interface br0 -j ACCEPT
|
|
doas /etc/init.d/iptables save
|
|
```
|
|
|
|
#### Containers support
|
|
|
|
```
|
|
doas apk add lxc lxcfs lxc-download xz gnupg
|
|
echo "$(id -un):10000000:5000000" | doas tee -a /etc/subuid
|
|
echo "$(id -un):10000000:5000000 | doas tee -a /etc/subgid
|
|
echo "$(id -un) veth br0 10" | doas tee -a /etc/lxc/lxc-usernet
|
|
doas rc-update add cgroups lxc lxcfs dbus
|
|
```
|
|
|
|
#### Creating container
|
|
|
|
Create `~/.config/lxc/CONTAINERNAME.conf" with the following content:
|
|
```
|
|
lxc.net.0.type = veth
|
|
lxc.net.0.flags = up
|
|
lxc.net.0.link = br0
|
|
lxc.net.0.ipv4.address = 10.157.1.2/24 10.157.1.255
|
|
lxc.net.0.ipv4.gateway = 10.157.1.1
|
|
lxc.net.0.veth.pair = veth-if-0
|
|
# this is not a mistype, 500K should be enough for all your nesting needs, and 5M in /etc/subuid should be enough if you want to create any other containers
|
|
lxc.idmap = u 0 10000000 500000
|
|
lxc.idmap = g 0 10000000 500000
|
|
|
|
lxc.include = /usr/share/lxc/config/nesting.conf
|
|
lxc.apparmor.allow_nesting = 1
|
|
lxc.seccomp.allow_nesting = 1
|
|
lxc.mount.auto = proc sys cgroup:rw:force
|
|
```
|
|
|
|
Then:
|
|
```
|
|
lxc-create -n CONTAINERNAME -f .config/lxc/CONTAINERNAME.conf -t download
|
|
# pick OS (alpine/edge/amd64 in my case)
|
|
lxc-start -n CONTAINERNAME # make sure it does not produce any errors
|
|
lxc-attach --clear-env -n CONTAINERNAME
|
|
```
|
|
|
|
You'll get into a container root console.
|
|
|
|
(but still inside this container `apk cgroups start` will produce errors
|
|
and mount everything in /sys/fs/cgroups except for openrc as nobody:nobody,
|
|
and won't mount openrc at all, and nested containers won't work.)
|
|
|
|
#### Networking (container)
|
|
|
|
In container root console, check if network is up with `ifconfig`.
|
|
If there are no IPv4 address for eth0, you'll have to configure it manually,
|
|
by editing `/etc/network/interfaces`.
|
|
The easiest way to do it is by
|
|
```
|
|
doas micro ~/.local/share/lxc/CONTAINERNAME/rootfs/etc/network/interfaces`
|
|
```
|
|
on the host.
|
|
|
|
In the end the file should look like
|
|
```
|
|
auto eth0
|
|
iface eth0 inet static
|
|
address 10.157.1.2
|
|
netmask 255.255.255.0
|
|
gateway 10.157.1.1
|
|
hostname $(hostname)
|
|
```
|
|
|
|
Then `rc-service networking restart`, and check `ifconfig`.
|
|
If everything is right, there should be an ipv4 address in `ifconfig`,
|
|
and `ping 10.157.1.1` inside container and `ping 10.157.1.2` inside host should work.
|
|
|
|
`ping 8.8.8.8` inside container should work too, thanks for routing.
|
|
|
|
Now, if `ping google.com` does not work, configure DNS in container:
|
|
|
|
```
|
|
echo nameserver 8.8.8.8 >> /etc/resolv.conf
|
|
echo nameserver 8.8.4.4 >> /etc/resolv.conf
|
|
```
|
|
|
|
(or add them using micro on the host, as you did for interfaces)
|
|
|
|
Make sure `ping 8.8.8.8` works.
|
|
APK should work too: `apk add micro neofetch`
|
|
|
|
#### Creating an user inside container
|
|
|
|
In container root shell:
|
|
```
|
|
adduser -g USERNAME USERNAME
|
|
adduser USERNAME wheel
|
|
echo "permit persist :wheel" >> /etc/doas.d/doas.conf
|
|
```
|
|
|
|
Now exit root shell (just with `exit`), and try `lxc-console -n CONTAINERNAME`.
|
|
You should be able to log in using the new username and password.
|
|
(To exit lxc console, use Ctrl+A, Q).
|
|
|
|
### Alternatively: unprivileged LXC using LXD
|
|
|
|
#### Security notes
|
|
|
|
Note that with LXD, unprivileged containers run under root, which is not supposed to give them any extra privileges
|
|
(source: https://discuss.linuxcontainers.org/t/privileged-and-unprivileged-containers/12060/2), but this implies that:
|
|
|
|
Containers can only be managed with LXD using root access.
|
|
Which means either `doas` for every command (including connecting to the container shell),
|
|
or adding your user to the `lxd` group which will have access to LXD daemon,
|
|
**which will effectively give your user passwordless sudo (since access to LXD daemon can trivially be used to gain root privileges),
|
|
so that any process running under your user can trivially gain root privileges on the host**
|
|
(which is for some reason not considered by LXD maintainers to be a problem).
|
|
|
|
**DO NOT add your user to the `lxd` group, and DO NOT uncomment ` --group lxd` in `/etc/conf.d/lxd`**
|
|
|
|
Instead the secure way of doing things would probably be to only use lxd as a root,
|
|
and connect to the container using ssh.
|
|
|
|
#### Containers support
|
|
|
|
As simple as
|
|
```
|
|
apk add lxd lxd-client lxcfs dbus
|
|
rc-update add lxc
|
|
rc-update add lxd
|
|
rc-update add lxcfs
|
|
rc-update add dbus
|
|
doas reboot
|
|
```
|
|
|
|
Networking with routing should work automatically.
|
|
|
|
#### Creating container
|
|
|
|
```
|
|
doas lxc launch images:alpine/edge -c security.nesting=true -c security.privileged=false -c security.idmap.isolated=true -c security.idmap.size=6553600 test-alpine-container
|
|
doas lxc exec test-alpine-container -- /bin/ash
|
|
```
|
|
Networking should work inside of container.
|
|
|
|
### OpenSSH
|
|
|
|
With password-based auth (not recommended): in container (from root, `lxc-attach`/`lxc exec`)
|
|
|
|
```
|
|
apk add openssh
|
|
rc-update add sshd
|
|
rc-service sshd start
|
|
```
|
|
|
|
Check IP of container with `ifconfig`, and then on host,
|
|
```
|
|
doas apk add openssh-client
|
|
ssh CONTAINER_IP
|
|
```
|
|
|
|
With keys-based auth:
|
|
```
|
|
ssh-keygen -t ed25519
|
|
ssh-copy-id CONTAINER_IP
|
|
```
|
|
|
|
(Also make sure that `echo $SSH_AUTH_SOCK` is not empty; it shouldn't be if gnome-keyring-daemon is configured properly.)
|
|
|
|
### Webdev
|
|
|
|
#### Accessing dev sites running inside container
|
|
|
|
In container: `doas apk add squid`, and edit `/etc/squid/squid/conf` accordingly
|
|
(most likely you'll only need to change local network definition to match the subnet shared between the host and the container).
|
|
|
|
Then:
|
|
```
|
|
doas rc-update add squid
|
|
doas rc-service squid start
|
|
```
|
|
|
|
(Note that squid requires devfs service to be running).
|
|
|
|
In host, create new FF profile (`about:profiles`) for that purpose, and configure it to use squid proxy running inside of container.
|
|
|
|
#### VS Code Remote
|
|
|
|
Note that VS Code (and all related products) has a protection intended to prevent OSS variants from connecting to proprietary versions of VS code.
|
|
However, apparently, it is implemented in such a way that it prevents even different OSS products from connecting to each other.
|
|
Only "Code OSS" is packaged for Alpine (until https://gitlab.alpinelinux.org/alpine/aports/-/issues/14860 is implemented);
|
|
and only VSCodium has official server-side builds, so you'll need to use custom server-side builds with Code OSS.
|
|
|
|
Steps to get it running, assuming that you already have keyring and key-based SSH auth (with non-RSA key) configured:
|
|
|
|
|
|
In container (one of the sources: https://github.com/microsoft/vscode-remote-release/issues/6347):
|
|
```
|
|
doas apk add gcompat libstdc++ curl bash git procps
|
|
```
|
|
and enable `AllowTcpForwarding` and `PermitTunnel` in `/etc/ssh/sshd_config`.
|
|
|
|
On host (where you intend to run IDE client):
|
|
|
|
`doas apk add code-oss`
|
|
|
|
Using e.g. Firefox, download `vscodium-reh-linux-x64-...` for a relevant build (with a version matching to code-oss)
|
|
from https://github.com/VSCodium/vscodium/releases
|
|
|
|
Unpack it: `cd Downloads && ouch decompress vscodium-reh-... --dir vscodium`
|
|
|
|
Edit `/usr/lib/code-oss/resources/app/package.json` to make it mimic VSCodium (looking at `package.json` from unpacked VSCodium).
|
|
In my experience, changing `name`, removing `distro`, and adding `release` fields was enough.
|
|
(Make sure that `version` fields are identical between installed Code OSS and downloaded VSCodium package.)
|
|
|
|
Edit `/usr/lib/code-oss/resources/app/product.json` to make it mimic VSCodium (looking at `product.json` from unpacked VSCodium).
|
|
In my experience, changing `nameShort`, `nameLong`, `applicationName`, `dataFolderName`, `win32MutexName`,
|
|
`licenseUrl`, `serverApplicationName`, `serverDataFolderName`, `win32DirName`, `win32NameVersion`, `win32RegValueName`,
|
|
`linuxIconName`, `reportIssueUrl` and `date` fields,
|
|
and adding `updateUrl`, `quality` and `commit` fields was enough.
|
|
But most of these fields are probably irrelevant and can be left as is.
|
|
|
|
Run `code-oss`, add "Open Remote - SSH" extension by jeanp413.
|
|
Go to its settings, and set "Server Download Url Template" to
|
|
`https://github.com/gitpod-io/openvscode-server/releases/download/openvscode-server-v${version}/openvscode-server-v${version}-${os}-${arch}.tar.gz`
|
|
(otherwise it will download VSCodium server-side builds by default).
|
|
Exit `code-oss`.
|
|
|
|
Add `"enable-proposed-api": ["jeanp413.open-remote-ssh"]` at the root level of `~/.vscode-oss/argv.json`.
|
|
|
|
Run `code-oss` again, you'll get remote button under the marketplace button.
|
|
Go there, add your host, right-click it, connect.
|
|
Connection should be successful, and you should see "connected to remote" on Code OSS main screen.
|
|
"Open folder" should take you to the remote directory structure, allowing you to open projects hosted in container.
|
|
All code-related extensions will also work in remote context, isolated from the parent system and unable to affect it,
|
|
no matter what malicious npm packages get installed into container.
|
|
|
|
### Docker
|
|
|
|
For container terminal apps to be usable:
|
|
|
|
```
|
|
doas apk add ncurses-terminfo
|
|
```
|
|
|
|
#### (inside LXC)
|
|
|
|
TODO once nesting in LXC works (reference: https://discuss.linuxcontainers.org/t/lxc-on-alpine-host-sys-fs-cgroup-is-not-mounted-into-unprivileged-alpine-guest/15026/1)
|
|
|
|
#### (inside LXD)
|
|
|
|
As simple as
|
|
```
|
|
doas apk add docker
|
|
doas rc-update docker start
|
|
doas docker run hello-world
|
|
```
|
|
in the guest.
|
|
|
|
For networked docker containers, `doas lxc config edit CONTAINERNAME`,
|
|
add `linux.kernel_modules: br_netfilter` to the `config:` section,
|
|
and restart container (`doas lxc restart CONTAINERNAME`).
|
|
|
|
## TODO
|
|
|
|
* Fix internal mic
|
|
* Docker in containers ran by unprivileged users
|
|
* Make river usable
|
|
* Make waybar usable (+waybar fonts)
|
|
* nushell + starship instead of ash
|
|
* Mail client
|
|
* Fix call audio in firefox
|
|
* WiFi
|
|
|