When I wanted to display the GUI with Docker, I wanted to understand what was happening, so I made a note. I referred to ROS Tutorial, but I think the same applies to other containers.
By the way, How to display GUI with VNC and browser is recommended because it is easy. However, here I will describe the behavior when using the X window system.
X window system A window system often used in UNIX-like operating systems. It consists of a server and a client, and communicates using the X protocol. Since the protocol version is 11, since 1987, the system is also called X11, or simply X. The X implementation is Xorg, which is used by many Linux distributions.
The X server controls input / output devices such as displays, mice, and keyboards. Originally, X itself was created with the intention of displaying and operating the window of a program that runs over the network on the display at hand, with the image of the X server being local and the X client being remote. Of course it works even if the X client is local.
Reference: Mechanism and settings of X Window System
--Socket
In order to display the GUI with Docker, the X client in the Docker container needs to communicate with the host X server. If the X server and X client are on the same computer, this is usually a UNIX-domain socket. The socket file is under `/tmp/.X11-unix```, and you can access it to communicate with the X server. You can access it from inside the container by mounting
`/tmp/.X11-unix``` when starting the Docker container.
--Environment variable DISPLAY
Specify the X server to which the X client connects with `DISPLAY```. The format is ``` hostname: displaynumber.screennumber```. For example, ``` localhost: 0.0```. However, the hostname and screen number can be omitted, so in this case
`: 0may be used. If you add
--env =" DISPLAY "``` to docker run, the environment variables of the host will be reflected in the container.
Then, not only should I set /tmp/.X11-unix
and `` `DISPLAY``` in docker run, but authentication is required to communicate with the X server. Normally the root user cannot access the X server, but you can do it on the host by doing the following: However, this is not recommended for security reasons.
$ xhost +local:root
You can access it by making the UID and GID of the Docker container the same as the host. For example, set the --user option as follows:
$ docker run -it --rm \
--user=$(id -u $USER):$(id -g $USER) \
--env="DISPLAY" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
osrf/ros:melodic-desktop-full
However, in a Docker image that does not have a user other than root set, it will be ``` I have no name!` ``. You can mount the required directory as shown below to have the same user name as the host in the container.
$ docker run -it \
--user=$(id -u $USER):$(id -g $USER) \
--env="DISPLAY" \
--volume="/etc/group:/etc/group:ro" \
--volume="/etc/passwd:/etc/passwd:ro" \
--volume="/etc/shadow:/etc/shadow:ro" \
--volume="/etc/sudoers.d:/etc/sudoers.d:ro" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
osrf/ros:melodic-desktop-full
If the Docker image has a user other than root, it seems that the UID and GID should be set to the same as the host. For example, create the following Dockerfile.
FROM osrf/ros:melodic-desktop-full
#Add new sudo user
ENV USERNAME myNewUserName
RUN useradd -m $USERNAME && \
echo "$USERNAME:$USERNAME" | chpasswd && \
usermod --shell /bin/bash $USERNAME && \
usermod -aG sudo $USERNAME && \
echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/$USERNAME && \
chmod 0440 /etc/sudoers.d/$USERNAME && \
# Replace 1000 with your user/group id
usermod --uid 1000 $USERNAME && \
groupmod --gid 1000 $USERNAME
Build the Dockerfile with the following command and start it to become a container that can display the GUI. (In the Tutorial that I referred to, it was necessary to create and mount an X authentication file, but it worked without it in my environment)
$ docker build -t hoge .
$ docker run -it --rm \
--env="DISPLAY" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
-user="myNewUserName" \
hoge
reference
I got a little better understanding of docker and GUI. However, I'm a little sick because the area around X authentication moved without touching it ...
Recommended Posts