Is it possible to display UI in docker running in snap?

Hey there,

Just curious how it would work (if its possible at all), if I want to display a GUI on ubuntu core from a docker container?

From what I understand graphical output goes through wayland, for which the wayland interface needs to be connected to the application that wants to output visuals.

However, I don’t see the wayland interface in docker connections:

Interface                    Plug                               Slot                                 Notes
content                      -                                  docker:docker-registry-certificates  -
content[docker-executables]  azure-iot-edge:docker-executables  docker:docker-executables            manual
content[graphics-core22]     docker:graphics-core22             mesa-core22:graphics-core22          -
docker                       azure-iot-edge:docker              docker:docker-daemon                 manual
docker                       docker:docker-cli                  docker:docker-daemon                 -
docker-support               docker:privileged                  :docker-support                      -
docker-support               docker:support                     :docker-support                      -
firewall-control             docker:firewall-control            :firewall-control                    -
home                         docker:home                        :home                                -
log-observe                  docker:log-observe                 -                                    -
network                      docker:network                     :network                             -
network-bind                 docker:network-bind                :network-bind                        -
network-control              docker:network-control             :network-control                     -
opengl                       docker:opengl                      :opengl                              -
removable-media              docker:removable-media             -                                    -

I do see graphics-core22 interface connecting to mesa-core22.

It’s giving me the following error output:

error: XDG_RUNTIME_DIR not set in the environment.
[00007fd55000b580] gl vout display error: parent window not available
[00007fd55000b580] gles2 vout display error: parent window not available
[00007fd55000b580] xcb vout display error: window not available
[00007fd55000b580] xcb vout display error: window not available
Authorization required, but no authorization protocol specified
[00007fd55000b580] caca vout display error: cannot initialize libcaca
[00007fd55c109e40] main video output error: video output creation failed
[00007fd580f82a20] main decoder error: failed to create video output
[h264 @ 0x7fd580fb7240] get_buffer() failed
[h264 @ 0x7fd580fb7240] thread_get_buffer() failed
[h264 @ 0x7fd580fb7240] decode_slice_header error
[h264 @ 0x7fd580fb7240] no frame!

I’m assming I have to set some variables like XDG_RUNTIME_DIR. I found someone suggesting running docker as follows:

docker run -e XDG_RUNTIME_DIR=/tmp \
           -e WAYLAND_DISPLAY=$WAYLAND_DISPLAY \
           -v $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY:/tmp/$WAYLAND_DISPLAY  \
           --user=$(id -u):$(id -g) \
           imagename waylandapplication

But I’m not sure what the values should be here, and I am confused about whether they would be accessible without connecting a wayland interface?

P.S I am trying to do this because we want to deploy our graphical application through Azure IoT Edge, which deploys through docker images.

On Ubuntu Desktop this works :slight_smile:

snap run docker container run --network=host -e XDG_RUNTIME_DIR=/tmp -e WAYLAND_DISPLAY=wayland-0 -v /tmp/wayland-0:/tmp/wayland-0 --user=1000:1000 vlc_docker

Remains to be tested if this works on Ubuntu Core, I’ll try soon

In general it is a very bad idea to use docker on UbuntuCore, you massively degrade the overall security with it since the docker interface used by the docker snap is massively privileged, so if you do not 100% secure your container workload properly you could break out of confinement…

For that reason i doubt the docker snap will ever be granted access to ubuntu-frame via the wayland interface on core…

It is usually not too hard to repackage a docker workload as snap and I’d always advise this over using the docker snap in production (though indeed it is technically possible to use it)

Thanks for the reply!

Does this mean that using Azure Iot Edge, where workload is deployed through docker, is not a good idea?

@ogra To connect it to wayland, would docker need to be re-packaged to have a wayland plug?

Or is there another way to test this?

I’d expect the iot-edge snap to do the right things when setting up docker internally (at least i hope so :grinning:)

Well, yes, you could re-package docker and add that plug to gain access to the wayland socket of ubuntu-frame… but then you’d have to maintain it yourself which indeed means a lot of extra work… I’d split UI and backend and package the UI as snap

Ok, yea I think we are gonna try this (snapping the frontend), was just curious if it would work :blush:

Back to the snapcraft drawing table it is then :smiley:

1 Like

@ogra I managed to do it as follows:

sudo docker run -e XDG_RUNTIME_DIR=/tmp -e WAYLAND_DISPLAY=wayland-0 -v /run/user/0:/tmp flutter_docker

With ubuntu-frame installed and enabled. This worked on Ubuntu Core. I also managed to do this with a docker managed by IoT Edge.

Do you see any problems with this approach?

1 Like

Apart from my general “don’t use docker on core if you can avoid it, to not waste additional resources over a native snap and to not weaken security” I dont see issues, but you will need to find a way to automate this from a snap.

snaps can not easily execute other snaps, sudo can not be used inside snaps, so if you do not want to shell into each of your devices to manually run this command, you have to find a way to do the above through the docker content interface from some type of agent or config snap.