您可以在Docker容器中運行GUI應用程序嗎?

本文翻譯自:Can you run GUI applications in a Docker container?

How can you run GUI applications in a Docker container? 如何在Docker容器中運行GUI應用程序?

Are there any images that set up vncserver or something so that you can - for example - add an extra speedbump sandbox around say Firefox? 是否有設置vncserver圖像或其他東西,例如,您可以在Firefox周圍添加一個額外的speedbump沙箱?


#1樓

參考:https://stackoom.com/question/16NWr/您可以在Docker容器中運行GUI應用程序嗎


#2樓

You can simply install a vncserver along with Firefox :) 您可以簡單地與Firefox一起安裝vncserver :)

I pushed an image, vnc/firefox, here: docker pull creack/firefox-vnc 我在這裏推送了一個圖像vnc / firefox: docker pull creack/firefox-vnc

The image has been made with this Dockerfile: 該鏡像已使用以下Dockerfile生成:

# Firefox over VNC
#
# VERSION               0.1
# DOCKER-VERSION        0.2

FROM    ubuntu:12.04
# Make sure the package repository is up to date
RUN     echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN     apt-get update

# Install vnc, xvfb in order to create a 'fake' display and firefox
RUN     apt-get install -y x11vnc xvfb firefox
RUN     mkdir ~/.vnc
# Setup a password
RUN     x11vnc -storepasswd 1234 ~/.vnc/passwd
# Autostart firefox (might not be the best way to do it, but it does the trick)
RUN     bash -c 'echo "firefox" >> /.bashrc'

This will create a Docker container running VNC with the password 1234 : 這將創建一個運行VNC且密碼爲1234的Docker容器:

For Docker version 18 or newer: 對於Docker 18或更高版本:

docker run -p 5900:5900 -e HOME=/ creack/firefox-vnc x11vnc -forever -usepw -create

For Docker version 1.3 or newer: 對於Docker 1.3或更高版本:

docker run -p 5900 -e HOME=/ creack/firefox-vnc x11vnc -forever -usepw -create

For Docker before version 1.3: 對於1.3版之前的Docker:

docker run -p 5900 creack/firefox-vnc x11vnc -forever -usepw -create

#3樓

You can also use subuser: https://github.com/timthelion/subuser 您還可以使用子用戶: https : //github.com/timthelion/subuser

This allows you to package many gui apps in docker. 這使您可以將許多gui應用程序打包在docker中。 Firefox and emacs have been tested so far. 到目前爲止,Firefox和emacs已經過測試。 With firefox, webGL doesn't work though. 使用firefox,webGL不能正常工作。 Chromium doesn't work at all. 鉻根本不起作用。

EDIT: Sound works! 編輯:聲音有效!

EDIT2: In the time since I first posted this, subuser has progressed greatly. EDIT2:自從我第一次發佈此內容以來,子用戶有了很大的進步。 I now have a website up subuser.org , and a new security model for connecting to X11 via XPRA bridging . 我現在在subuser.org上擁有一個網站,以及一個用於通過XPRA橋接連接到X11的新安全模型。


#4樓

Here's a lightweight solution that avoids having to install any X server, vnc server or sshd daemon on the container. 這是一個輕量級的解決方案,可以避免在容器上安裝任何X服務器, vnc服務器或sshd守護程序。 What it gains in simplicity it loses in security and isolation. 它在簡單性方面獲得的好處在安全性和隔離性方面失去了。

It assumes that you connect to the host machine using ssh with X11 forwarding. 假定您使用帶有X11轉發功能的ssh連接到主機。

In the sshd configuration of the host, add the line 在主機的sshd配置中,添加以下行

X11UseLocalhost no

So that the forwarded X server port on the host is opened on all interfaces (not just lo ) and in particular on the Docker virtual interface, docker0 . 以便主機上轉發的X服務器端口在所有接口(不僅是lo )上都打開,尤其是在Docker虛擬接口docker0

The container, when run, needs access to the .Xauthority file so that it can connect to the server. 容器在運行時需要訪問.Xauthority文件,以便它可以連接到服務器。 In order to do that, we define a read-only volume pointing to the home directory on the host (maybe not a wise idea!) and also set the XAUTHORITY variable accordingly. 爲了做到這一點,我們定義了一個指向主機上主目錄的只讀卷(可能不是一個明智的主意!),並相應地設置了XAUTHORITY變量。

docker run -v $HOME:/hosthome:ro -e XAUTHORITY=/hosthome/.Xauthority

That is not enough, we also have to pass the DISPLAY variable from the host, but substituting the hostname by the ip: 這還不夠,我們還必須從主機傳遞DISPLAY變量,但用ip替換主機名:

-e DISPLAY=$(echo $DISPLAY | sed "s/^.*:/$(hostname -i):/")

We can define an alias: 我們可以定義一個別名:

 alias dockerX11run='docker run -v $HOME:/hosthome:ro -e XAUTHORITY=/hosthome/.Xauthority -e DISPLAY=$(echo $DISPLAY | sed "s/^.*:/$(hostname -i):/")'

And test it like this: 並像這樣測試它:

dockerX11run centos xeyes

#5樓

With docker data volumes it's very easy to expose xorg's unix domain socket inside the container. 使用docker數據卷,很容易將xorg的unix域套接字公開到容器內。

For example, with a Dockerfile like this: 例如,使用這樣的Dockerfile:

FROM debian
RUN apt-get update
RUN apt-get install -qqy x11-apps
ENV DISPLAY :0
CMD xeyes

You could do the following: 您可以執行以下操作:

$ docker build -t xeyes - < Dockerfile
$ XSOCK=/tmp/.X11-unix/X0
$ docker run -v $XSOCK:$XSOCK xeyes

This of course is essentially the same as X-forwarding. 當然,這本質上與X轉發相同。 It grants the container full access to the xserver on the host, so it's only recommended if you trust what's inside. 它授予容器對主機上xserver的完全訪問權限,因此僅在您信任其中的內容時才建議使用。

Note: If you are concerned about security, a better solution would be to confine the app with mandatory- or role-based- access control. 注意:如果您擔心安全性,那麼更好的解決方案是使用強制性基於角色的訪問控制來限制應用程序。 Docker achieves pretty good isolation, but it was designed with a different purpose in mind. Docker實現了很好的隔離,但是在設計時考慮了不同的目的。 Use AppArmor , SELinux , or GrSecurity , which were designed to address your concern. 使用AppArmorSELinuxGrSecurity旨在解決您的問題。


#6樓

Xauthority becomes an issue with newer systems. Xauthority成爲新系統的問題。 I can either discard any protection with xhost + before running my docker containers, or I can pass in a well prepared Xauthority file. 我可以在運行Docker容器之前放棄使用xhost +進行的任何保護,也可以傳入準備充分的Xauthority文件。 Typical Xauthority files are hostname specific. 典型的Xauthority文件是特定於主機名的。 With docker, each container can have a different host name (set with docker run -h), but even setting the hostname of the container identical to the host system did not help in my case. 使用docker,每個容器可以具有不同的主機名(使用docker run -h設置),但是即使將容器的主機名設置爲與主機系統相同也不能解決我的問題。 xeyes (I like this example) simply would ignore the magic cookie and pass no credentials to the server. xeyes(我喜歡這個示例)只會忽略魔術cookie,並且不會將憑據傳遞給服務器。 Hence we get an error message 'No protocol specified Cannot open display' 因此,我們收到一條錯誤消息“未指定協議,無法打開顯示”

The Xauthority file can be written in a way so that the hostname does not matter. Xauthority文件的編寫方式可以使主機名無關緊要。 We need to set the Authentication Family to 'FamilyWild'. 我們需要將身份驗證系列設置爲“ FamilyWild”。 I am not sure, if xauth has a proper command line for this, so here is an example that combines xauth and sed to do that. 我不確定xauth是否爲此使用了正確的命令行,因此這是結合xauth和sed來執行此操作的示例。 We need to change the first 16 bits of the nlist output. 我們需要更改nlist輸出的前16位。 The value of FamilyWild is 65535 or 0xffff. FamilyWild的值爲65535或0xffff。

docker build -t xeyes - << __EOF__
FROM debian
RUN apt-get update
RUN apt-get install -qqy x11-apps
ENV DISPLAY :0
CMD xeyes
__EOF__
XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth
xauth nlist :0 | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
docker run -ti -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH -e XAUTHORITY=$XAUTH xeyes
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章