Skip to content
This repository has been archived by the owner on Mar 27, 2024. It is now read-only.

An experiment making containers using debootstrap and runnning via systemd. You should use distrobox instead.

License

Notifications You must be signed in to change notification settings

rogerbinns/make-app-container

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 

Repository files navigation

This is an experiment. You should consider docker or podman as better alternatives. This is a closer alternative to tools like firejail.

This script creates a container, and then adds a control script in ~/.local/bin which auto-starts the container, runs an app inside, and stops the container afterwards if not still in use. It is like the container is local host program.

This creates a container based on focal (Ubuntu 20.04 LTS) installing the supplied chrome package inside. It is only given access to your screen (--gui) and your host Downloads directory is made available inside.:

make-app-container.py create --gui focal --bind downloads --run google-chrome ~/containers/chrome-container google-chrome-stable_current_amd64.deb

To run, simply run the created control script which should be on your $PATH.:

chrome-container --incognito www.example.com

There are flags to expose gui (X), 3d (mesa/dri), sound (pulseaudio), webcams (v4l) etc, and bind host folders inside, such as ~/Downloads or your Steam library. You can also control what networking is available - none, shared with the host, or being separate from the host.

The major benefit is the container shares nothing from the host, except what you explicitly configure. The control script means no need to manually stop and start the containers.

The configuration is at the top of the control script which you can edit.

The script is written in Python (3.6+). The control script is extracted from inside it.

The containers are created using debootstrap which creates a Debian or Ubuntu root environment in a specified directory. debootstrap is available on most flavours of Linux, not just Debian/Ubuntu.

This script creates a user of the same name and id inside the chroot which keeps permissions consistent with files and directories provided from the host.

The containers are run using systemd-nspawn and machinectl from systemd. The systemd-container package needs to exist inside which means more recent versions of Debian/Ubuntu.

Unfortunately many operations involving the containers require root access on the host. If you configured as a gui application then pkexec is used to get a graphical prompt. Otherwise sudo is used.

The control script starts the container if not already running. It ensures appropriate files and directories are bound (eg for X, pulseaudio, downloads, webcams etc).

Arguments supplied to the control script are then run inside the container, appended to the --run argument if given at creation time. Environment variables are appropriately set for X, pulseaudio, terminal type etc.

Once that exits, the container is shutdown if no other instance of the script is running.

The control script can take additional options. These start with ++ to distinguish them from options going into the container, and must be the first options supplied.

++show:

Shows the commands the script runs

++start / ++stop:

Only start or stop the container. Do not run anything.

++cmd:

Runs the remaining arguments as the command instead of what was configured with --run

You can use machinectl shell to get a shell inside the running container as root or user.

++network on | off | separate | nat:

Overrides the network setting when starting the container

++aptupdate:

Starts the container with networking on and performs apt to download and install updates, then stops the container.

++aptupdateall:

Finds all control scripts in the same directory as this one (there is a marker) and runs ++aptupdate with each one

Any running X application has continual full access to the screen (ie can constantly record) as well as mouse movement and keyboard activity. (Fixing this was one of several motivations behind Wayland.)

You can run a nested X environment as a window inside your existing desktop. Install the package for Xephyr on your host, to provide the window.

The networking option has to be anything except "on". (The abstract namespace for Unix domain sockets is the cause.)

The container will always have a private loopback interface (usually named lo with an address of 127.0.0.1). That means software using loopback in the container will not clash with the host.

Only the loopback inteface will be available, and no network traffic can enter or leave the container.

The container will share the host's network interfaces (except loopback). This works great for apps that make connections. But apps that listen on the network within the container will clash with the same on the host due to the sharing.

This setting makes it impossible to tell if an app is running on the host, or in a container.

A virtual network interface is created for the container so it can run any network services without clashes. Traffic from that interface goes to the host, which then uses network address translation to forward on to the real network. Listening services can be contacted by the host, but not the rest of the network.

You need systemd-networkd running on your host for the host side setup to be done automatically.

A new mac address is added to each existing up network interface and used by the container (macvlan). The container is configured to use DHCP on those to get its own IP address. The container has direct access to the networks as a result, as does the network to the container.

Note that the host and container will not be able to directly talk to each other (a bridge has to be setup). Additional mac addresses can't be added to wifi interfaces.

Steam on Ubuntu 20.10 with graphics, 3d, sound, joysticks etc.:

make-app-container create --gui --mesa --sound --webcam --bind steam --run steam groovy ~/containers/steam ~/Downloads/steam_latest.deb

On starting steam first time it wanted a password to install packages. We do so manually since there is no way (deliberately) for the container user to become root. We also need to enable 32 bit packages:

sudo machinectl shell steam /bin/bash -c 'dpkg --add-architecture i386 ; apt update ; apt install libgl1-mesa-dri:i386 libgl1:i386 libc6:i386 xdg-desktop-portal xdg-desktop-portal-gtk

We are going to run this in a private window, with no access to the display, sound etc using the default matchbox window manager. Some dev packages are also installed (build-essential and git) while libasound is added because code depends on it but doesn't not declare the dependency.:

make-app-container create --gui-private --bind gitconfig --packages build-essential,git,libasound2 --network nat --run code groovy ~/containers/vscode ~/Downloads/code_amd64.deb

Now I can it with vscode. Projects are bound into the container like this:

sudo machinectl bind --mkdir vscode ~/projects/example

About

An experiment making containers using debootstrap and runnning via systemd. You should use distrobox instead.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages