Can you run GUI applications in a Docker container?

前端 未结 22 2862
南旧
南旧 2020-11-22 06:12

How can you run GUI applications in a Docker container?

Are there any images that set up vncserver or something so that you can - for example - add an e

22条回答
  •  半阙折子戏
    2020-11-22 06:48

    While the answer by Jürgen Weigert essentially covers this solution, it wasn't clear to me at first what was being described there. So I'll add my take on it, in case anyone else needs clarification.

    First off, the relevant documentation is the X security manpage.

    Numerous online sources suggest just mounting the X11 unix socket and the ~/.Xauthority file into the container. These solutions often work by luck, without really understanding why, e.g. the container user ends up with the same UID as the user, so there's no need for magic key authorization.

    First off, the Xauthority file has mode 0600, so the container user won't be able to read it unless it has the same UID.

    Even if you copy the file into the container, and change the ownership, there's still another problem. If you run xauth list on the host and container, with the same Xauthority file, you'll see different entries listed. This is because xauth filters the entries depending on where it's run.

    The X client in the container (i.e. GUI app) will behave the same as xauth. In other words, it doesn't see the magic cookie for the X session running on the user's desktop. Instead, it sees the entries for all the "remote" X sessions you've opened previously (explained below).

    So, what you need to do is add a new entry with the hostname of the container and the same hex key as the host cookie (i.e. the X session running on your desktop), e.g.:

    containerhostname/unix:0   MIT-MAGIC-COOKIE-1   
    

    The catch is that the cookie has to be added with xauth add inside the container:

    touch ~/.Xauthority
    xauth add containerhostname/unix:0 . 
    

    Otherwise, xauth tags it in a way that it's only seen outside the container.

    The format for this command is:

    xauth add hostname/$DISPLAY protocol hexkey
    

    Where . represents the MIT-MAGIC-COOKIE-1 protocol.

    Note: There's no need to copy or bind-mount .Xauthority into the container. Just create a blank file, as shown, and add the cookie.

    Jürgen Weigert's answer gets around this by using the FamilyWild connection type to create a new authority file on the host and copy it into the container. Note that it first extracts the hex key for the current X session from ~/.Xauthority using xauth nlist.

    So the essential steps are:

    • Extract the hex key of the cookie for the user's current X session.
    • Create a new Xauthority file in the container, with the container hostname and the shared hex key (or create a cookie with the FamilyWild connection type).

    I admit that I don't understand very well how FamilyWild works, or how xauth or X clients filter entries from the Xauthority file depending where they're run. Additional information on this is welcome.

    If you want to distribute your Docker app, you'll need a start script for running the container that gets the hex key for the user's X session, and imports it into the container in one of the two ways explained previously.

    It also helps to understand the mechanics of the authorization process:

    • An X client (i.e. GUI application) running in the container looks in the Xauthority file for a cookie entry that matches the container's hostname and the value of $DISPLAY.
    • If a matching entry is found, the X client passes it with its authorization request to the X server, through the appropriate socket in the /tmp/.X11-unix directory mounted in the container.

    Note: The X11 Unix socket still needs to be mounted in the container, or the container will have no route to the X server. Most distributions disable TCP access to the X server by default for security reasons.

    For additional information, and to better grasp how the X client/server relationship works, it's also helpful to look at the example case of SSH X forwarding:

    • The SSH server running on a remote machine emulates its own X server.
    • It sets the value of $DISPLAY in the SSH session to point to its own X server.
    • It uses xauth to create a new cookie for the remote host, and adds it to the Xauthority files for both the local and remote users.
    • When GUI apps are started, they talk to SSH's emulated X server.
    • The SSH server forwards this data back to the SSH client on your local desktop.
    • The local SSH client sends the data to the X server session running on your desktop, as if the SSH client was actually an X client (i.e. GUI app).
    • The X server uses the received data to render the GUI on your desktop.
    • At the start of this exchange, the remote X client also sends an authorization request, using the cookie that was just created. The local X server compares it with its local copy.

提交回复
热议问题