
In this article, we will guide you through the process of running X11 applications in Docker on Ubuntu 20.04. Docker is a powerful tool for creating, deploying, and running applications using containerization, while X11 is a protocol that allows the building of graphical user interfaces (GUIs) for Unix-like systems.
Yes, it is possible to run X11 apps in Docker on Ubuntu 20.04. You can achieve this by creating a Dockerfile, setting up an entrypoint script, building the Docker image, and running the container with the appropriate command. Follow the step-by-step guide in the blog post for detailed instructions.
Prerequisites
Before starting, ensure that you have Docker installed on your Ubuntu 20.04 system. If you haven’t installed Docker yet, you can follow the official Docker installation guide.
Step 1: Creating a Dockerfile
First, we need to create a Dockerfile. The Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image.
Create a new file named Dockerfile
with the following content:
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y x11-apps
ARG user=hakon
ARG home=/home/$user
RUN groupadd -g 1000 $user
RUN useradd -d $home -s /bin/bash -m $user -u 1000 -g 1000 \
&& echo $user:ubuntu | chpasswd \
&& adduser $user sudo
WORKDIR $home
USER $user
ENV HOME $home
COPY entrypoint.sh .
ENTRYPOINT ["./entrypoint.sh"]
In this Dockerfile, we are creating an Ubuntu 20.04 container and installing x11-apps
, which is a collection of simple X applications. We are also creating a user and a group with the same name and ID, and setting this user as the default user for the container.
Step 2: Creating the Entrypoint Script
Next, we need to create an entrypoint script. This script will be the first thing that runs when the container starts.
Create a new file named entrypoint.sh
with the following content:
echo "DISPLAY=$DISPLAY"
xclock
echo "Done."
exec bash
This script simply prints the value of the DISPLAY
environment variable, runs the xclock
application (a simple X11 app), and then starts a bash shell.
Step 3: Building the Docker Image
Now that we have our Dockerfile and entrypoint script, we can build our Docker image. Run the following command in the same directory as your Dockerfile:
docker build -t gui-test-ubuntu-2004 .
This command tells Docker to build an image using the Dockerfile in the current directory (.
), and tag it (-t
) with the name gui-test-ubuntu-2004
.
Step 4: Running the Docker Container
Finally, we can run our Docker container with the following command:
docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY \
-h $HOSTNAME -v $HOME/.Xauthority:/home/hakon/.Xauthority gui-test-ubuntu-2004
Let’s break down this command:
-v /tmp/.X11-unix:/tmp/.X11-unix
: This mounts the X11 Unix domain socket from the host into the container. This socket is used by X11 clients to communicate with the X server.-e DISPLAY=$DISPLAY
: This sets theDISPLAY
environment variable inside the container to the same value as on the host. This tells X11 clients where to find the X server.-h $HOSTNAME
: This sets the hostname inside the container to the same value as on the host.-v $HOME/.Xauthority:/home/hakon/.Xauthority
: This mounts the.Xauthority
file from the host into the container. This file is used for X11 authentication.
If everything is set up correctly, you should see an xclock
window appear on your screen.
Troubleshooting
If you encounter the error “Error: Can’t open display: :0” and the GUI window does not show up, there are a few possible solutions:
- Solution 1: Use
x11docker
instead ofdocker
to run the container. Installx11docker
by following the instructions provided here. Then, instead of runningdocker run ... gui-test-ubuntu-2004
, use the commandx11docker --xephyr gui-test-ubuntu-2004
. - Solution 2: Remove the
snap
installation of Docker and reinstall it usingapt-get
. First, remove Docker using the commandsudo snap remove docker
. Then, go to the Docker download page for Ubuntu here and choose your Ubuntu version. Browse topool/stable/
and download the three.deb
files:containerd.io_1.2.13-2_amd64.deb
,docker-ce_19.03.11_3-0_ubuntu-focal_amd64.deb
, anddocker-ce-cli_19.03.11_3-0_ubuntu-focal_amd64.deb
. Install them in the given order using the commands:
sudo apt-get install ./containerd.io_1.2.13-2_amd64.deb
sudo apt-get install ./docker-ce-cli_19.03.11_3-0_ubuntu-focal_amd64.deb
sudo apt-get install ./docker-ce_19.03.11_3-0_ubuntu-focal_amd64.deb
After installation, add your user to the Docker group to avoid using sudo
with Docker commands:
sudo addgroup --system docker
sudo usermod -a -G docker $USER
Restart your computer to activate the new user and group settings. Test the Docker installation by running docker run hello-world
. You should now be able to run the original docker run
command for the X11 app.
Please note that using xhost +
or xhost + local:docker
as a workaround may pose security risks and is generally not recommended.
Conclusion
In this article, we have shown you how to run a simple X11 app in a Docker container on Ubuntu 20.04. This can be a powerful way to run GUI applications in a controlled and isolated environment. However, remember to always consider the security implications of running GUI applications in Docker, especially when dealing with X11 authentication.
Yes, you can run any X11 application in Docker using this method. Just make sure to install the necessary dependencies for your specific application within the Dockerfile.
Yes, you can run multiple X11 applications in the same Docker container. Simply modify the entrypoint script to include the commands for running each application sequentially.
You can pass arguments to the X11 application by modifying the entrypoint script. Simply add the desired arguments to the command that launches the application.
Yes, you can share files between the host and the Docker container. In the docker run
command, you can use the -v
flag to mount a directory from the host into the container, allowing for file sharing.
To remove the Docker image, use the command docker rmi <image_id>
where <image_id>
is the ID of the image you want to remove. To remove the container, use the command docker rm <container_id>
where <container_id>
is the ID of the container you want to remove.