本文翻譯自: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. 使用AppArmor , SELinux或GrSecurity旨在解決您的問題。
#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