You are not logged in.
I've wanted to try this in a while but never had time. But due to the vacation and the social distancing rules, I have way too much time on my hands so there is no excuse to delay this any further.
The goal is to get BL running in a container inside an Ubuntu host.
In case you don't know, containers are the shiny new thing in Linux virtualization. They are kind of like VMs, but much more lightweight, as programs run natively on the real hardware instead of on emulated devices. There is isolation in place that prevents them from interacting directly with your other processes and the filesystem. But they will run side-by-side your other processes with no overhead.
If you've ever used chroot, you could say that containers are a much more evolved form of that.
There are many ways to start containers under linux. There are popular tools that help with that, called "container engines". I will use docker, as that is the most popular one.
You can think of docker as the container equivalent of virtualbox. But it is much better!
Docker has the concept of "images", which are snapshots of the popular distros, either minimalistic or with various packages preinstalled. They are built using files called "dockerfiles", that are kind of like makefiles, that let you make your own custom image.
Most distros have official docker images. Debian has one as well. Unfotunately, there is no image for BL.
The plan is to start with a minimalistic debian image which we slowly transform into BL.
I don't have more detailed steps in mind, and I am not entirely sure what is needed. I will post here all the steps I do, right or wrong. Including blunders, that is fine as we learn from them.
Enough talk, time to get my hands dirty with this.
Offline
Part 1: installing docker.
Normally one would install docker from the package manager.
However, the Ubuntu package is a little old, and it does not support something called rootless mode.
This is a feature in docker 20 that allows you to be a sort of fake root inside the container, without actually being root on the host system. This is useful since it reduces the blast radius of any bad mistake we might do in the container.
So I am installing the latest stable docker version, following instructions from https://docs.docker.com/get-docker/
Uninstalling old versions
sudo apt-get remove docker docker.io containerd runc
Add docker repo and install
Following the instructions from:
https://docs.docker.com/engine/install/
For ubuntu host:
sudo apt update
sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
Add your user to the docker group:
sudo groupadd docker
sudo usermod -aG docker $USER
And now relog (you could also run sudo -u $USER bash and work in that shell in case you really cannot relog right now).
Enable rootless mode
Linux magic allows a non-root user from outside the container appear as root
inside the container, without being an actual root on the host system.
This makes it very hard to damage your host by running commands as root
inside the container. At least in theory.
We need to install this package:
sudo apt install uidmap
Then run just once:
sudo dockerd --userns-remap="default:default"
We write the following to the docker settings file:
sudo echo '{ "userns-remap": "dockremap" }' > /etc/docker/daemon.json
And we restart docker:
sudo service docker restart
To check that the magic worked:
1. Check that dockremap user has been created:
id dockremap
uid=111(dockremap) gid=121(dockremap) groups=121(dockremap)
2. Check that user id mappings have been created:
$ grep dockremap /etc/subuid
dockremap:231072:65536
$ grep dockremap /etc/subgid
dockremap:231072:65536
3. Check that the following directory exists and is owned by uid/gid 231072:
sudo ls -lah /var/lib/docker/231072.231072/
total 52K
drwx------ 13 231072 231072 4.0K Dec 25 14:19 .
drwx--x--x 16 root root 4.0K Dec 25 14:17 ..
drwx--x--x 4 root root 4.0K Dec 25 14:18 buildkit
drwx------ 2 231072 231072 4.0K Dec 25 14:18 containers
drwx------ 3 root root 4.0K Dec 25 14:18 image
drwxr-x--- 3 root root 4.0K Dec 25 14:18 network
drwx------ 3 231072 231072 4.0K Dec 25 14:19 overlay2
drwx------ 4 root root 4.0K Dec 25 14:18 plugins
drwx------ 2 root root 4.0K Dec 25 14:19 runtimes
drwx------ 2 root root 4.0K Dec 25 14:18 swarm
drwx------ 2 231072 231072 4.0K Dec 25 14:19 tmp
drwx------ 2 root root 4.0K Dec 25 14:18 trust
drwx------ 2 231072 231072 4.0K Dec 25 14:19 volumes
4. Check that docker works by starting the hello-world container:
docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:1a523af650137b8accdaed439c17d684df61ee4d74feac151b5b337bd29e7eec
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
If you get the error:
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/create: dial unix /var/run/docker.sock: connect: permission denied.
You need to add your user to docker group and relog.
5. Pull the latest debian image, start a container and run bash inside:
docker run -it debian /bin/bash
Unable to find image 'debian:latest' locally
latest: Pulling from library/debian
6c33745f49b4: Pull complete
Digest: sha256:22d4552b9f96fd0ea943cb846d58b069d4df297673636055a3d984b3ccac6a28
Status: Downloaded newer image for debian:latest
root@7997e9d0612f:/# whoami
root
Run htop outside, check that container is not running as root:
PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
25043 root 20 0 109M 7848 6668 S 0.0 0.0 0:00.04 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 7997e9d0612f4067a8fd723d8c72cf0dc8eab6320e1f7f74262543d466f5afc6 -address /run/containerd/containerd.sock
25065 231072 20 0 3864 3316 2844 S 0.0 0.0 0:00.02 /bin/bash
Notice how outside the container, the user running bash is actually 231072.
This is exactly what we wanted.
Last edited by o9000 (2020-12-25 14:58:05)
Offline
Part 2: Converting debian into bunsenlabs, manually
In the second part, I am converting the debian container into bunsen.
The whole process is manual (entering CLIs) and changes will be lost
when exiting the container.
The purpose of this step is to experiment and learn what steps
are needed to be run automatically via the dockerfile in the next part.
The good page at https://www.bunsenlabs.org/repositories.html
explains that BunsenLabs Lithium corresponds to Debian Buster,
and we can convert debian into bunsen by adding the bunsen repos.
First, let's check that our container is running debian buster:
root@7997e9d0612f:/# lsb_release -a
bash: lsb_release: command not found
No luck. The debian docker image is minimalist, with very few packages installed.
Let's use the manual way:
cat /etc/issue
Debian GNU/Linux 10 \n \l
cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
We're good, this is indeed Debian Buster.
Let's add the bunsen repo key via manual install of the keyring package:
wget https://eu.pkg.bunsenlabs.org/debian/pool/main/b/bunsen-keyring/bunsen-keyring_2020.10.10+bl10-1_all.deb
bash: wget: command not found
Bummer. We have to install wget first:
apt update
apt install wget
Download and add the bunsen keyring:
wget https://eu.pkg.bunsenlabs.org/debian/pool/main/b/bunsen-keyring/bunsen-keyring_2020.10.10+bl10-1_all.deb
dpkg -i bunsen-keyring_2020.10.10+bl10-1_all.deb
Selecting previously unselected package bunsen-keyring.
(Reading database ... 7496 files and directories currently installed.)
Preparing to unpack bunsen-keyring_2020.10.10+bl10-1_all.deb ...
Unpacking bunsen-keyring (2020.10.10+bl10-1) ...
Setting up bunsen-keyring (2020.10.10+bl10-1) ...
It worked. Now add the bunsen repos to apt sources:
root@7997e9d0612f:/# cat /etc/apt/sources.list
# deb http://snapshot.debian.org/archive/debian/20201209T232235Z buster main
deb http://deb.debian.org/debian buster main
# deb http://snapshot.debian.org/archive/debian-security/20201209T232235Z buster/updates main
deb http://security.debian.org/debian-security buster/updates main
# deb http://snapshot.debian.org/archive/debian/20201209T232235Z buster-updates main
deb http://deb.debian.org/debian buster-updates main
root@7997e9d0612f:/# echo 'deb http://pkg.bunsenlabs.org/debian lithium main' >> /etc/apt/sources.list
root@7997e9d0612f:/# echo 'deb http://pkg.bunsenlabs.org/debian buster-backports main' >> /etc/apt/sources.list
Let's update the apt database:
root@7997e9d0612f:/# apt update
Hit:1 http://deb.debian.org/debian buster InRelease
Hit:2 http://security.debian.org/debian-security buster/updates InRelease
Hit:3 http://deb.debian.org/debian buster-updates InRelease
Get:4 http://eu.pkg.bunsenlabs.org/debian lithium InRelease [6362 B]
Get:5 http://eu.pkg.bunsenlabs.org/debian buster-backports InRelease [5154 B]
Get:6 http://eu.pkg.bunsenlabs.org/debian lithium/main amd64 Packages [11.2 kB]
Get:7 http://eu.pkg.bunsenlabs.org/debian buster-backports/main amd64 Packages [1301 B]
Fetched 12.5 kB in 1s (23.1 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
1 package can be upgraded. Run 'apt list --upgradable' to see it.
Great! It scanned the bunsenlabs repos without any errors.
Let's search for some bunsen packages:
root@7997e9d0612f:/# apt search bunsen
Sorting... Done
Full Text Search... Done
bunsen-common/lithium 10.2.6-1 all
Various shared files for BunsenLabs
bunsen-configs/lithium 10.7.1-1 all
config files for BunsenLabs Linux
...
Tons of them. We will install the big meta package:
root@7997e9d0612f:/# apt install bunsen-meta-all
Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:
The following packages have unmet dependencies:
bunsen-meta-all : Depends: amd64-microcode but it is not installable
Depends: firmware-b43-installer but it is not installable
Depends: firmware-b43legacy-installer but it is not installable
Depends: firmware-linux but it is not installable
Depends: firmware-realtek but it is not installable
Depends: firmware-iwlwifi but it is not installable
Depends: intel-microcode but it is not installable
Depends: unrar but it is not installable
E: Unable to correct problems, you have held broken packages.
Not good. Let's see why amd64-microcode is not installable:
root@7997e9d0612f:/# apt search amd64-microcode
Sorting... Done
Full Text Search... Done
root@7997e9d0612f:/#
Crickets. This is a good thing: it's not a package conflict. We are just missing some repositories.
Luckily this is easy to solve. The good page https://wiki.debian.org/SourcesList
nicely points out that there is a contrib repo and a non-free repo in addition to
main, which is the only one we have:
root@7997e9d0612f:/# cat /etc/apt/sources.list
# deb http://snapshot.debian.org/archive/debian/20201209T232235Z buster main
deb http://deb.debian.org/debian buster main
...
So let's add them. First, we install nano, and then we edit the file:
apt install nano
nano /etc/apt/sources.list
...
The file now looks like this:
cat /etc/apt/sources.list
# deb http://snapshot.debian.org/archive/debian/20201209T232235Z buster main
deb http://deb.debian.org/debian buster main contrib non-free
# deb http://snapshot.debian.org/archive/debian-security/20201209T232235Z buster/updates main
deb http://security.debian.org/debian-security buster/updates main contrib non-free
# deb http://snapshot.debian.org/archive/debian/20201209T232235Z buster-updates main
deb http://deb.debian.org/debian buster-updates main
deb http://pkg.bunsenlabs.org/debian lithium main
deb http://pkg.bunsenlabs.org/debian buster-backports main
We run once again apt update and search for the missing package:
root@7997e9d0612f:/# apt update
root@7997e9d0612f:/# apt search amd64-microcode
Sorting... Done
Full Text Search... Done
amd64-microcode/stable,now 3.20181128.1 amd64 [installed,automatic]
Processor microcode firmware for AMD CPU
Great! It's there now. Let's install the bunsen meta package:
apt install bunsen-meta-all
This downloads about 1200 packages and estimates about 3.4 GB of additional disk space usage.
Now we have a system where we can install packages. So far so good!
Offline
Wow! Just . . Wow! You Rock
My understanding from what you wrote is that the standard Debian repos won't work for this? That you are building in Ubuntu?
Normally one would install docker from the package manager.
However, the Ubuntu package is a little old, and it does not support something called rootless mode.
Would I be wasting my time to try this in a straight Debian build?
Offline
My host system is Ubuntu, but docker should would work just fine on a Debian host as well.
Installing docker from the docker repo may be required if the distro packaged version is older than 20. Version 20 introduced rootless mode, which allows you to run containers as non-root.
Without rootless mode, there is a risk that some of the commands you run as root inside the container will affect the host system. The host and guest share the same kernel, so you can break things if you are not careful. Rootless mode protects you from this.
Note that this is just about the step of installing docker. What runs inside as a container remains the same.
Here is how to check the version of docker that you have installed:
docker --version
Docker version 20.10.1, build 831ebea
Last edited by o9000 (2020-12-25 15:49:57)
Offline
Part 3: Creating a bunsenlabs base image via Dockerfile
We have seen in part 2 how to create a container manually. Let's now build with through a dockerfile.
Dockerfiles are text files that describe how you want docker to customize a base image for you. Let's see how that works on the fly.
First, create a dockerfile on your host system (not inside the container, you can forget about that for now):
touch Dockerfile
For now, we will write just the following inside:
FROM debian:latest
This describes a container that is identical to the latest debian image.
We can build a container from the dockerfile with the following command:
$ docker build --tag bunsen:0.1 .
Sending build context to Docker daemon 5.12kB
Step 1/1 : FROM debian:latest
---> 6d6b00c22231
Successfully built 6d6b00c22231
Successfully tagged bunsen:0.1
This creates an image named bunsen, with version 0.1 from the Dockerfile found in the current directory.
We can check which images we have locally with:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bunsen 0.1 6d6b00c22231 2 weeks ago 114MB
debian buster 6d6b00c22231 2 weeks ago 114MB
debian latest 6d6b00c22231 2 weeks ago 114MB
hello-world latest bf756fb1ae65 11 months ago 13.3kB
Note how the bunsen image shows up with version 0.1.
There is a problem with our Dockerfile: we based it on debian:latest. For now, that happens to be buster, but that might change, and there will be a mismatch between the debian repos and the bunsen repos.
Let's fix that by adding buster explicitly as base image:
FROM debian:buster
We can see that buster is a supported tag for the debian image on: https://hub.docker.com/_/debian
Let's now rebuild the bunsen image:
docker build --tag bunsen:0.1 .
Sending build context to Docker daemon 5.12kB
Step 1/1 : FROM debian:buster
buster: Pulling from library/debian
Digest: sha256:22d4552b9f96fd0ea943cb846d58b069d4df297673636055a3d984b3ccac6a28
Status: Downloaded newer image for debian:buster
---> 6d6b00c22231
Successfully built 6d6b00c22231
Successfully tagged bunsen:0.1
Before doing anything else, let's check that it works:
$ docker run -it bunsen:0.1 /bin/bash
root@d6e1a9e1e3fc:/# whoami
root
root@d6e1a9e1e3fc:/# exit
exit
Great! We have a working image built from Dockerfile.
Still, this is a debian image, not yet bunsen. Let's see how we can customize it through the dockerfile as we did in step 2 manually.
We can run commands from the Dockerfile with RUN statements like this:
FROM debian:buster
RUN apt-get update
RUN apt-get install -y sudo wget curl nano
Each statement is executed by Docker in order when building the bunsen image:
docker build --tag bunsen:0.1 . [147/187]
Sending build context to Docker daemon 5.12kB
Step 1/3 : FROM debian:buster
---> 6d6b00c22231
Step 2/3 : RUN apt-get update
---> Running in 3b5b84747bec
Get:1 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB]
Get:2 http://deb.debian.org/debian buster InRelease [121 kB]
Get:3 http://deb.debian.org/debian buster-updates InRelease [51.9 kB]
Get:4 http://security.debian.org/debian-security buster/updates/main amd64 Packages [256 kB]
Get:5 http://deb.debian.org/debian buster/main amd64 Packages [7907 kB]
Get:6 http://deb.debian.org/debian buster-updates/main amd64 Packages [7860 B]
Fetched 8411 kB in 1s (6212 kB/s)
Reading package lists...
Removing intermediate container 3b5b84747bec
---> 305f338cfe92
Step 3/3 : RUN apt-get install -y sudo wget curl nano
---> Running in 3eb8b25ff306
Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
ca-certificates krb5-locales libcurl4 libgssapi-krb5-2 libk5crypto3
libkeyutils1 libkrb5-3 libkrb5support0 libldap-2.4-2 libldap-common
libnghttp2-14 libpcre2-8-0 libpsl5 librtmp1 libsasl2-2 libsasl2-modules
libsasl2-modules-db libssh2-1 libssl1.1 lsb-base openssl publicsuffix
Suggested packages:
krb5-doc krb5-user libsasl2-modules-gssapi-mit
| libsasl2-modules-gssapi-heimdal libsasl2-modules-ldap libsasl2-modules-otp
libsasl2-modules-sql spell
The following NEW packages will be installed:
ca-certificates curl krb5-locales libcurl4 libgssapi-krb5-2 libk5crypto3
libkeyutils1 libkrb5-3 libkrb5support0 libldap-2.4-2 libldap-common
libnghttp2-14 libpcre2-8-0 libpsl5 librtmp1 libsasl2-2 libsasl2-modules
libsasl2-modules-db libssh2-1 libssl1.1 lsb-base nano openssl publicsuffix
sudo wget
0 upgraded, 26 newly installed, 0 [code]
FROM debian:buster
RUN apt-get update
RUN apt-get install -y sudo wget curl nano
RUN wget https://eu.pkg.bunsenlabs.org/debian/pool/main/b/bunsen-keyring/bunsen-keyring_2020.10.10+bl10-1_all.deb
RUN dpkg -i bunsen-keyring_2020.10.10+bl10-1_all.deb
[/code]to remove and 1 not upgraded.
Need to get 7941 kB of archives.
After this operation, 22.0 MB of additional disk space will be used.
Get:1 http://security.debian.org/debian-security buster/updates/main amd64 libssl1.1 amd64 1.1.1d-0+deb10u4 [1538 kB]
Get:2 http://deb.debian.org/debian buster/main amd64 nano amd64 3.2-3 [544 kB]
...
Successfully built 0cc46e6797a8
Successfully tagged bunsen:0.1
If we start bash in the container, we can see that wget is installed:
$ docker run -it bunsen:0.1 /bin/bash
root@accac8c9bc64:/# which wget
/usr/bin/wget
root@accac8c9bc64:/#
Let's add the commands needed to install the bunsen keyring:
FROM debian:buster
RUN apt-get update
RUN apt-get install -y sudo wget curl nano
RUN wget https://eu.pkg.bunsenlabs.org/debian/pool/main/b/bunsen-keyring/bunsen-keyring_2020.10.10+bl10-1_all.deb
RUN dpkg -i bunsen-keyring_2020.10.10+bl10-1_all.deb
If we rebuild the image, we notice something interesting:
$ docker build --tag bunsen:0.1 .
Sending build context to Docker daemon 5.12kB
Step 1/5 : FROM debian:buster
---> 6d6b00c22231
Step 2/5 : RUN apt-get update
---> Using cache
---> 305f338cfe92
Step 3/5 : RUN apt-get install -y sudo wget curl nano
---> Using cache
---> 0cc46e6797a8
Step 4/5 : RUN wget https://eu.pkg.bunsenlabs.org/debian/pool/main/b/bunsen-keyring/bunsen-keyring_2020.10.10+bl10-1_all.deb
---> Running in 142290f8c17d
--2020-12-25 16:23:24-- https://eu.pkg.bunsenlabs.org/debian/pool/main/b/bunsen-keyring/bunsen-keyring_2020.10.10+bl10-1_all.deb
Resolving eu.pkg.bunsenlabs.org (eu.pkg.bunsenlabs.org)... 78.47.156.207, 2a01:4f8:c17:2c09::2
Connecting to eu.pkg.bunsenlabs.org (eu.pkg.bunsenlabs.org)|78.47.156.207|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 11276 (11K) [application/octet-stream]
Saving to: 'bunsen-keyring_2020.10.10+bl10-1_all.deb'
0K .......... . 100% 62.7M=0s
2020-12-25 16:23:24 (62.7 MB/s) - 'bunsen-keyring_2020.10.10+bl10-1_all.deb' saved [11276/11276]
Removing intermediate container 142290f8c17d
---> 16206f8a0b7a
Step 5/5 : RUN dpkg -i bunsen-keyring_2020.10.10+bl10-1_all.deb
---> Running in 932ccf7476ec
Selecting previously unselected package bunsen-keyring.
(Reading database ... 7450 files and directories currently installed.)
Preparing to unpack bunsen-keyring_2020.10.10+bl10-1_all.deb ...
Unpacking bunsen-keyring (2020.10.10+bl10-1) ...
Setting up bunsen-keyring (2020.10.10+bl10-1) ...
Removing intermediate container 932ccf7476ec
---> 4ee34ef607f3
Successfully built 4ee34ef607f3
Successfully tagged bunsen:0.1
This time, docker skipped the commands needed to update the repo and install wget, curl and nano. It just displayed "Using cache".
This is because docker stores a snapshot of the image filesystem as it was after executing each line of the Dockerfile. If you add new lines or change existing ones, it will start work based on the image state from the last unchanged line. This makes the process of editing images with Dockerfiles extremely fast!
Let's now edit the apt sources file. We could do it with some shell magic in RUN commands, but that is tricky. Instead, we will create the sources file on the host, and copy it into the image with the COPY statement:
touch sources.list
nano sources.list
Paste inside:
deb http://deb.debian.org/debian buster main contrib non-free
deb http://security.debian.org/debian-security buster/updates main contrib non-free
deb http://deb.debian.org/debian buster-updates main
deb http://pkg.bunsenlabs.org/debian lithium main
deb http://pkg.bunsenlabs.org/debian buster-backports main
Update the Dockerfile:
FROM debian:buster
RUN apt-get update
RUN apt-get install -y sudo wget curl nano
RUN wget https://eu.pkg.bunsenlabs.org/debian/pool/main/b/bunsen-keyring/bunsen-keyring_2020.10.10+bl10-1_all.deb
RUN dpkg -i bunsen-keyring_2020.10.10+bl10-1_all.deb
COPY sources.list /etc/apt/sources.list
Now if we build the bunsen image, we see that it copies the sources.list file to the container:
$ docker build --tag bunsen:0.1 .
Sending build context to Docker daemon 6.144kB
Step 1/6 : FROM debian:buster
---> 6d6b00c22231
Step 2/6 : RUN apt-get update
---> Using cache
---> 305f338cfe92
Step 3/6 : RUN apt-get install -y sudo wget curl nano
---> Using cache
---> 0cc46e6797a8
Step 4/6 : RUN wget https://eu.pkg.bunsenlabs.org/debian/pool/main/b/bunsen-keyring/bunsen-keyring_2020.10.10+bl10-1_all.deb
---> Using cache
---> 16206f8a0b7a
Step 5/6 : RUN dpkg -i bunsen-keyring_2020.10.10+bl10-1_all.deb
---> Using cache
---> 4ee34ef607f3
Step 6/6 : COPY sources.list /etc/apt/sources.list
---> 5a51f1b8f47c
Successfully built 5a51f1b8f47c
Successfully tagged bunsen:0.1
Great! Now let's run apt-update and install the bunsen meta package. There is one issue at this step: we have seen in the manual procedure that the bunsen meta package pulls some packages that ask for configuration during installation. We want to avoid that. So we also set the DEBIAN_FRONTEND noninteractive environment variable in the dockerfile:
FROM debian:buster
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y sudo wget curl nano
RUN wget https://eu.pkg.bunsenlabs.org/debian/pool/main/b/bunsen-keyring/bunsen-keyring_2020.10.10+bl10-1_all.deb
RUN dpkg -i bunsen-keyring_2020.10.10+bl10-1_all.deb
COPY sources.list /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y bunsen-meta-all
Finally, we build the image:
docker build --tag bunsen:0.1 .
This takes a while until it downloads and installs all packages. The image size becomes around 3.4 GB:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
bunsen 0.1 bfcc2ed5ca79 About a minute ago 3.4GB
<none> <none> 5a51f1b8f47c 9 minutes ago 155MB
debian buster 6d6b00c22231 2 weeks ago 114MB
debian latest 6d6b00c22231 2 weeks ago 114MB
hello-world latest bf756fb1ae65 11 months ago 13.3kB
From this point on, it's important to avoid changing the above lines in the Dockerfile and only add lines below instead, so that the cached snapshot is used in further image customizations. Otherwise, you will have to wait until it downloads and installs all packages again.
Offline
Are you OK if we put a link to this in the Scripts&Tips section?
Be Excellent to Each Other...
The Bunsenlabs Lithium Desktop » Here
FORUM RULES and posting guidelines «» Help page for forum post formatting
Artwork on DeviantArt «» BunsenLabs on DeviantArt
Offline
Feel free to link/move it anywhere you wish, as long as it is clear this is experimental and a work-in-progress.
Offline
Part 4: GUI
This is a first attempt to get a GUI working.
Since we are running BL inside a container, we have a problem: there is no graphics card there.
Typically, there are a few options to get graphical applications working:
share the host X11 socket with the container
over ssh from host with X forwarding
run a virtual X11 server inside the container and VNC to it from the host
The first option gives very good performance, but only allows running apps one by one. Moreover, since the host X11 server is used, there will be no BL desktop, panel and window manager. This defeats the purpose of running a well customized distro like BL, so I will not try it.
The second option is similar, but with worse performance, since the connection is tunneled over SSH.
The only viable option is to use VNC.
The idea is the following:
1. We install xvfb in the container, and run it as X11 server. Xvfb does not require a graphics card.
2. Xvfb will launch an openbox session when started. Further apps will be started from the openbox autostart file.
3. We install a VNC server in the container and have it serve the Xvfb display.
4. We install a VNC client on the host, and connect to the VNC server.
Let's do this.
First, we install xvfb and the vnc server via Dockerfile:
RUN apt-get install -y x11vnc xvfb
Then, we need to setup the graphical session. So far, we worked with the container as root. We don't want to do that inside a graphical session. So let's create a non-root user inside the container, via the Dockerfile. We will call the user bob, inspired by a certain scientist: https://en.wikipedia.org/wiki/Robert_Bunsen
RUN groupadd -g 1000 bob
RUN adduser --disabled-password --uid 1000 --gid 1000 --gecos bob bob
USER bob
ENV HOME /home/bob
ENV USER bob
WORKDIR /home/bob
Let's create an openbox autostart file:
cat <<EOF > autostart
tint2 -c /etc/xdg/tint2/tint2rc &
x11vnc -display :99 -forever -shared -passwd 123 &
EOF
This file just starts tint2 and x11vnc. We use the convention that display :99 is the one inside the container. You should use a more secure password than 123.
We now change the Dockerfile to add the autostart file to bob's home folder, and to start xvfb when the container is started:
COPY autostart /home/bob/.config/openbox/autostart
ENV DISPLAY :99
CMD xvfb-run -s :99 -s '-screen 0 1024x768x24 -ac' openbox-session
Next, we build the container:
docker build --tag bunsen:0.1 .
We start it in a different way than before: we listen on the VNC port (5900) on localhost, and we no longer specify /bin/bash as an entry point (instead, the CMD command will be executed):
docker run -p 127.0.0.1:5900:5900 -it bunsen:0.1
If all works well, you should see a lot of output from the VNC server and graphical applications inside the container.
You should also see that port 5900 is open in listening mode on the host:
$ netstat -natpu | grep 5900
tcp 0 0 127.0.0.1:5900 0.0.0.0:* LISTEN 11671/docker-proxy
Let's connect to the server with a VNC client:
sudo apt install tigervnc-viewer
vncviewer 127.0.0.1:5900
The end result:
Full Dockerfile:
FROM debian:buster
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y sudo wget curl nano
RUN wget https://eu.pkg.bunsenlabs.org/debian/pool/main/b/bunsen-keyring/bunsen-keyring_2020.10.10+bl10-1_all.deb
RUN dpkg -i bunsen-keyring_2020.10.10+bl10-1_all.deb
COPY sources.list /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y bunsen-meta-all
RUN apt-get install -y x11vnc xvfb
RUN groupadd -g 1000 bob
RUN adduser --disabled-password --uid 1000 --gid 1000 --gecos bob bob
USER bob
ENV HOME /home/bob
ENV USER bob
WORKDIR /home/bob
COPY autostart /home/bob/.config/openbox/autostart
ENV DISPLAY :99
CMD xvfb-run -s :99 -s '-screen 0 1024x768x24 -ac' openbox-session
Note that this does not look at all like a BL desktop. The wallpaper is black, the window decorations are off, and pstree looks strange: there is no init system listed, just xvfb and some userspace daemons.
We will try to address that in the next post.
Offline
Part 5: Using the BL GUI
The reason why we had an empty desktop environment in the previous part was that the user was missing all BL-specific configs from his home folder.
We can see how these are populated in a normal BL install in https://github.com/BunsenLabs/bunsen-configs
BL expects the user to run bunsenlabs-session instead of openbox-session. In turn, bunsenlabs-session executes bl-user-setup --install, which populates the user home directory on the first login.
Let's change that in the dockerfile:
CMD xvfb-run -s :99 -s '-screen 0 1024x768x24 -ac' bunsenlabs-session
The problem is that now the VNC server is not executed anymore. We need a different approach. We create a custom startup script that executes the VNC server as well as xvfb, and spawns the BL session:
cat <<EOF > docker-entrypoint
#!/bin/bash
export DISPLAY=:99
sh -c "while :; do x11vnc -display $DISPLAY -forever -shared -passwd 123 ; sleep 1 ; done" &
exec xvfb-run -s $DISPLAY -s '-screen 0 1024x768x24 -ac' bunsenlabs-session
EOF
chmod +x docker-entrypoint
I ran x11vnc in a loop, since it exits if started before xvfb. It's a hack but it works.
We update the dockerfile to copy the entrypoint to bob's home directory and use it as CMD:
FROM debian:buster
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y sudo wget curl nano
RUN wget https://eu.pkg.bunsenlabs.org/debian/pool/main/b/bunsen-keyring/bunsen-keyring_2020.10.10+bl10-1_all.deb
RUN dpkg -i bunsen-keyring_2020.10.10+bl10-1_all.deb
COPY sources.list /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y bunsen-meta-all
RUN apt-get install -y x11vnc xvfb
RUN groupadd -g 1000 bob
RUN adduser --disabled-password --uid 1000 --gid 1000 --gecos bob bob
COPY docker-entrypoint /home/bob/docker-entrypoint
RUN chown bob:bob /home/bob/docker-entrypoint
USER bob
ENV HOME /home/bob
ENV USER bob
WORKDIR /home/bob
CMD /home/bob/docker-entrypoint
Build and run:
docker build --tag bunsen:0.1 .
docker run -p 127.0.0.1:5900:5900 -it bunsen:0.1
Connect to it over VNC:
vncviewer 127.0.0.1:5900
End result:
We finally achieved the BunsenLabs look!
Last edited by o9000 (2020-12-25 18:43:15)
Offline
Part 6: Essential tuning
The user we created before does not have a password. This is a problem as I cannot become root to install packages.
We need to tweak the dockerfile to either give the user a password, or give it passwordless sudo rights. I'm going for the latter since it is easier:
FROM debian:buster
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y sudo wget curl nano
RUN wget https://eu.pkg.bunsenlabs.org/debian/pool/main/b/bunsen-keyring/bunsen-keyring_2020.10.10+bl10-1_all.deb
RUN dpkg -i bunsen-keyring_2020.10.10+bl10-1_all.deb
COPY sources.list /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y bunsen-meta-all
RUN apt-get install -y x11vnc xvfb
RUN groupadd -g 1000 bob
RUN adduser --disabled-password --uid 1000 --gid 1000 --gecos bob bob
RUN usermod -aG sudo bob
RUN echo 'bob ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
COPY docker-entrypoint /home/bob/docker-entrypoint
RUN chown bob:bob /home/bob/docker-entrypoint
USER bob
ENV HOME /home/bob
ENV USER bob
WORKDIR /home/bob
CMD /home/bob/docker-entrypoint
Then we have to rebuild the image. Finally, we see that sudo works.
Offline
Things that do not work (yet):
sound
probably anything that requires 3D acceleration
no persistence: the container resets to initial state once the user exits; all files created inside are lost
If anyone wants to try and fix some of the above, you are welcome! For now, I will stop here.
Offline
Wow! This is super interesting.
Bookmarked.
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), idle Twitterings and GitStuff )
Online