Docker 컨테이너 에서 GUI 응용 프로그램을 어떻게 실행할 수 있습니까?
vncserver
예를 들어 Firefox와 같은 추가적인 스피드 범프 샌드 박스를 추가 할 수 있도록 설정 한 이미지가 있습니까?
Docker 컨테이너 에서 GUI 응용 프로그램을 어떻게 실행할 수 있습니까?
vncserver
예를 들어 Firefox와 같은 추가적인 스피드 범프 샌드 박스를 추가 할 수 있도록 설정 한 이미지가 있습니까?
답변:
Firefox와 함께 간단히 vncserver를 설치할 수 있습니다 :)
vnc / firefox 이미지를 여기에 넣었습니다. docker pull creack/firefox-vnc
이 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'
암호로 VNC를 실행하는 Docker 컨테이너가 생성됩니다 1234
.
Docker 버전 18 이상인 경우 :
docker run -p 5900:5900 -e HOME=/ creack/firefox-vnc x11vnc -forever -usepw -create
Docker 버전 1.3 이상 :
docker run -p 5900 -e HOME=/ creack/firefox-vnc x11vnc -forever -usepw -create
버전 1.3 이전의 Docker의 경우 :
docker run -p 5900 creack/firefox-vnc x11vnc -forever -usepw -create
docker inspect <container id>
또는 간단히 함으로써 docker ps
방금 찾은 포트로 호스트의 IP에 연결합니다)
Xauthority는 최신 시스템에서 문제가됩니다. 도커 컨테이너를 실행하기 전에 xhost +로 보호를 취소하거나 잘 준비된 Xauthority 파일을 전달할 수 있습니다. 일반적인 Xauthority 파일은 호스트 이름에 따라 다릅니다. docker를 사용하면 각 컨테이너마다 다른 호스트 이름 (docker run -h로 설정)을 가질 수 있지만 컨테이너의 호스트 이름을 호스트 시스템과 동일하게 설정해도 도움이되지 않습니다. xeyes (이 예제가 마음에 듭니다)는 단순히 매직 쿠키를 무시하고 자격 증명을 서버에 전달하지 않습니다. 따라서 '프로토콜을 지정하지 않았습니다. 디스플레이를 열 수 없습니다'라는 오류 메시지가 나타납니다.
호스트 이름이 중요하지 않도록 Xauthority 파일을 작성할 수 있습니다. 인증 패밀리를 'FamilyWild'로 설정해야합니다. xauth에 적절한 명령 줄이 있는지 확실하지 않으므로 xauth와 sed를 결합하는 예제가 있습니다. nlist 출력의 첫 16 비트를 변경해야합니다. 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
-v $XSOCK:$XSOCK -v $XAUTH:$XAUTH
로 짧아 질 수 있습니다-v $XSOCK -v $XAUTH
:0
로 $DISPLAY
. xauth nlist $DISPLAY | ...
그리고 의미 docker run -ti -e DISPLAY=$DISPLAY ...
합니다. 일반적으로 X DISPLAY는 :0
이지만 항상 그런 것은 아닙니다 (특히 ssh -X를 통해 연결하는 경우는 아님).
/tmp/.docker.xauth
는 600
권한 이있는 파일을 만듭니다 . 결과적으로 docker container 내부의 xauth가 파일을 읽을 수 없습니다. xauth list
도커 컨테이너 내에서 실행 하여 확인할 수 있습니다 . 이 문제를 해결하기 위해 명령 chmod 755 $XAUTH
뒤에 추가 xauth nlist :0 | ...
했습니다.
방금이 블로그 항목을 찾아서 여기에 공유하고 싶습니다. 그것이 가장 좋은 방법이라고 생각하고 너무 쉽기 때문입니다.
http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/
장점 :
+ 도커 컨테이너에 x 서버 항목 없음
+ vnc 클라이언트 / 서버 필요
없음
+ x 전달을 사용하는 ssh 없음 + 훨씬 작은 도커 컨테이너
단점 :
-호스트에서 x 사용 (보안 샌드 박싱 용이 아님)
언젠가 링크가 실패하는 경우 가장 중요한 부분을 여기에
넣었습니다.
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y firefox
# Replace 1000 with your user / group id
RUN export uid=1000 gid=1000 && \
mkdir -p /home/developer && \
echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
echo "developer:x:${uid}:" >> /etc/group && \
echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
chmod 0440 /etc/sudoers.d/developer && \
chown ${uid}:${gid} -R /home/developer
USER developer
ENV HOME /home/developer
CMD /usr/bin/firefox
이미지를 빌드하십시오.
docker build -t firefox .
실행 명령 :
docker run -ti --rm \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
firefox
물론 당신은 또한 실행 명령 에서이 작업을 수행 할 수 있습니다 sh -c "echo script-here"
힌트 : 오디오는 https://stackoverflow.com/a/28985715/2835523을 참조하십시오.
apt-get -y install sudo
를 만들려면 Dockerfile 에 설치해야한다고 생각 /etc/sudoers.d
합니다.
$ xhost +
도커 데이터 볼륨을 사용하면 컨테이너 내부에 xorg의 유닉스 도메인 소켓을 노출하는 것이 매우 쉽습니다.
예를 들어 다음과 같은 Dockerfile을 사용하십시오.
FROM debian
RUN apt-get update
RUN apt-get install -qqy x11-apps
ENV DISPLAY :0
CMD xeyes
다음을 수행 할 수 있습니다.
$ docker build -t xeyes - < Dockerfile
$ XSOCK=/tmp/.X11-unix/X0
$ docker run -v $XSOCK:$XSOCK xeyes
물론 이것은 X 전달과 본질적으로 동일합니다. 컨테이너는 호스트의 xserver에 대한 전체 액세스 권한을 부여하므로 내부 내용을 신뢰하는 경우에만 권장됩니다.
참고 : 보안이 염려되는 경우 더 나은 솔루션은 앱을 필수 또는 역할 기반 액세스 제어 로 제한하는 것 입니다. Docker는 매우 우수한 격리를 달성하지만 다른 목적을 염두에두고 설계되었습니다. 우려 사항을 해결하도록 설계된 AppArmor , SELinux 또는 GrSecurity를 사용하십시오 .
xhost +
호스트에서 사용 하십시오.
xhost +local
필요합니다. ~/.Xauthority
그러나 컨테이너에서 파일을 사용 가능 하게하여 자체 인증 할 수 있도록하는 것이 좋습니다.
Can't open display: :0
. 어떤 아이디어?
xhost +si:localuser:$USER
컨테이너를 시작하는 단지 사용자에게 권한을 부여 할 수 있습니다.
https://github.com/timthelion/subuser 하위 사용자를 사용할 수도 있습니다.
이를 통해 많은 GUI 응용 프로그램을 docker에 패키지 할 수 있습니다. Firefox와 emacs는 지금까지 테스트되었습니다. 파이어 폭스에서는 webGL이 작동하지 않습니다. Chromium이 전혀 작동하지 않습니다.
편집 : 소리가 작동합니다!
EDIT2 : 내가 이것을 처음 게시 한 이후로 하위 사용자가 크게 발전했습니다. 이제 웹 사이트 subuser.org 와 XPRA 브리징을 통해 X11에 연결하기위한 새로운 보안 모델이 있습니다 .
Jürgen Weigert 는 우분투에서 나에게 가장 적합한 대답을했지만 OSX에서는도 커가 VirtualBox 내부에서 실행되므로 더 이상 작업하지 않으면 솔루션이 작동하지 않습니다.
다음과 같은 추가 재료로 작업하고 있습니다.
OSX에 대한이 답변을 개선하기위한 사용자 의견에 감사드립니다 .X의 소켓 전달이 안전한지 확실하지 않지만 도커 컨테이너를 로컬로만 실행하는 것이 용도입니다.
또한 스크립트는 로컬 무선 네트워크에 있기 때문에 항상 임의의 IP이므로 기기의 IP 주소를 얻는 것이 쉽지 않다는 점에서 약간 취약합니다.
컨테이너를 시작하는 데 사용하는 BASH 스크립트 :
#!/usr/bin/env bash
CONTAINER=py3:2016-03-23-rc3
COMMAND=/bin/bash
NIC=en0
# Grab the ip address of this box
IPADDR=$(ifconfig $NIC | grep "inet " | awk '{print $2}')
DISP_NUM=$(jot -r 1 100 200) # random display number between 100 and 200
PORT_NUM=$((6000 + DISP_NUM)) # so multiple instances of the container won't interfer with eachother
socat TCP-LISTEN:${PORT_NUM},reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\" 2>&1 > /dev/null &
XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth.$USER.$$
touch $XAUTH
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
docker run \
-it \
--rm \
--user=$USER \
--workdir="/Users/$USER" \
-v "/Users/$USER:/home/$USER:rw" \
-v $XSOCK:$XSOCK:rw \
-v $XAUTH:$XAUTH:rw \
-e DISPLAY=$IPADDR:$DISP_NUM \
-e XAUTHORITY=$XAUTH \
$CONTAINER \
$COMMAND
rm -f $XAUTH
kill %1 # kill the socat job launched above
이 방법으로 xeyes와 matplotlib을 사용할 수 있습니다.
MobaXterm을 사용하는 Windows 7 이상에서는 조금 더 쉽습니다.
run_docker.bash
:
#!/usr/bin/env bash
CONTAINER=py3:2016-03-23-rc3
COMMAND=/bin/bash
DISPLAY="$(hostname):0"
USER=$(whoami)
docker run \
-it \
--rm \
--user=$USER \
--workdir="/home/$USER" \
-v "/c/Users/$USER:/home/$USER:rw" \
-e DISPLAY \
$CONTAINER \
$COMMAND
error: XDG_RUNTIME_DIR not set in the environment.
하고 Error: cannot open display: VAIO:0.0
. 이런 식으로 만난 적이 있습니까?
다른 답변에서 언급했듯이 공유 호스트 표시 : 0에는 두 가지 단점이 있습니다.
xev
또는 xinput
로 키 로깅 이 가능하고로로 호스트 응용 프로그램을 원격 제어 할 수 있습니다 xdotool
.--ipc=host
).Xephyr에서이 문제를 해결하는 도커 이미지를 실행하는 예제 스크립트 아래
--cap-drop ALL --security-opt no-new-privileges
. 또한 컨테이너 사용자는 루트 가 아닙니다 .이 스크립트는 먼저 Xephyr에서 호스트 창 관리자를 실행하고, 두 번째는 도커 이미지, 선택적으로 세 번째로 이미지 명령을 실행할 인수를 예상합니다. docker에서 데스크탑 환경을 실행하려면 호스트 창 관리자 대신 ":"을 사용하십시오.
Xephyr 창을 닫으면 docker container 응용 프로그램이 종료됩니다. 도커 응용 프로그램을 종료하면 Xephyr 창이 닫힙니다.
예 :
xephyrdocker "openbox --sm-disable" x11docker/lxde pcmanfm
xephyrdocker : x11docker/lxde
xephyrdocker xfwm4 --device /dev/snd jess/nes /games/zelda.rom
xephyrdocker 스크립트 :
#! /bin/bash
#
# Xephyrdocker: Example script to run docker GUI applications in Xephyr.
#
# Usage:
# Xephyrdocker WINDOWMANAGER DOCKERIMAGE [IMAGECOMMAND [ARGS]]
#
# WINDOWMANAGER host window manager for use with single GUI applications.
# To run without window manager from host, use ":"
# DOCKERIMAGE docker image containing GUI applications or a desktop
# IMAGECOMMAND command to run in image
#
Windowmanager="$1" && shift
Dockerimage="$*"
# Container user
Useruid=$(id -u)
Usergid=$(id -g)
Username="$(id -un)"
[ "$Useruid" = "0" ] && Useruid=1000 && Usergid=1000 && Username="user$Useruid"
# Find free display number
for ((Newdisplaynumber=1 ; Newdisplaynumber <= 100 ; Newdisplaynumber++)) ; do
[ -e /tmp/.X11-unix/X$Newdisplaynumber ] || break
done
Newxsocket=/tmp/.X11-unix/X$Newdisplaynumber
# cache folder and files
Cachefolder=/tmp/Xephyrdocker_X$Newdisplaynumber
[ -e "$Cachefolder" ] && rm -R "$Cachefolder"
mkdir -p $Cachefolder
Xclientcookie=$Cachefolder/Xcookie.client
Xservercookie=$Cachefolder/Xcookie.server
Xinitrc=$Cachefolder/xinitrc
Etcpasswd=$Cachefolder/passwd
# command to run docker
# --rm created container will be discarded.
# -e DISPLAY=$Newdisplay set environment variable to new display
# -e XAUTHORITY=/Xcookie set environment variable XAUTHORITY to provided cookie
# -v $Xclientcookie:/Xcookie:ro provide cookie file to container
# -v $NewXsocket:$NewXsocket:ro Share new X socket of Xephyr
# --user $Useruid:$Usergid Security: avoid root in container
# -v $Etcpasswd:/etc/passwd:ro /etc/passwd file with user entry
# --group-add audio Allow access to /dev/snd if shared with '--device /dev/snd'
# --cap-drop ALL Security: disable needless capabilities
# --security-opt no-new-privileges Security: forbid new privileges
Dockercommand="docker run --rm \
-e DISPLAY=:$Newdisplaynumber \
-e XAUTHORITY=/Xcookie \
-v $Xclientcookie:/Xcookie:ro \
-v $Newxsocket:$Newxsocket:rw \
--user $Useruid:$Usergid \
-v $Etcpasswd:/etc/passwd:ro \
--group-add audio \
--env HOME=/tmp \
--cap-drop ALL \
--security-opt no-new-privileges \
$(command -v docker-init >/dev/null && echo --init) \
$Dockerimage"
echo "docker command:
$Dockercommand
"
# command to run Xorg or Xephyr
# /usr/bin/Xephyr an absolute path to X server executable must be given for xinit
# :$Newdisplaynumber first argument has to be new display
# -auth $Xservercookie path to cookie file for X server. Must be different from cookie file of client, not sure why
# -extension MIT-SHM disable MIT-SHM to avoid rendering glitches and bad RAM access (+ instead of - enables it)
# -nolisten tcp disable tcp connections for security reasons
# -retro nice retro look
Xcommand="/usr/bin/Xephyr :$Newdisplaynumber \
-auth $Xservercookie \
-extension MIT-SHM \
-nolisten tcp \
-screen 1000x750x24 \
-retro"
echo "X server command:
$Xcommand
"
# create /etc/passwd with unprivileged user
echo "root:x:0:0:root:/root:/bin/sh" >$Etcpasswd
echo "$Username:x:$Useruid:$Usergid:$Username,,,:/tmp:/bin/sh" >> $Etcpasswd
# create xinitrc
{ echo "#! /bin/bash"
echo "# set environment variables to new display and new cookie"
echo "export DISPLAY=:$Newdisplaynumber"
echo "export XAUTHORITY=$Xclientcookie"
echo "# same keyboard layout as on host"
echo "echo '$(setxkbmap -display $DISPLAY -print)' | xkbcomp - :$Newdisplaynumber"
echo "# create new XAUTHORITY cookie file"
echo ":> $Xclientcookie"
echo "xauth add :$Newdisplaynumber . $(mcookie)"
echo "# create prepared cookie with localhost identification disabled by ffff,"
echo "# needed if X socket is shared instead connecting over tcp. ffff means 'familiy wild'"
echo 'Cookie=$(xauth nlist '":$Newdisplaynumber | sed -e 's/^..../ffff/')"
echo 'echo $Cookie | xauth -f '$Xclientcookie' nmerge -'
echo "cp $Xclientcookie $Xservercookie"
echo "chmod 644 $Xclientcookie"
echo "# run window manager in Xephyr"
echo $Windowmanager' & Windowmanagerpid=$!'
echo "# show docker log"
echo 'tail --retry -n +1 -F '$Dockerlogfile' 2>/dev/null & Tailpid=$!'
echo "# run docker"
echo "$Dockercommand"
} > $Xinitrc
xinit $Xinitrc -- $Xcommand
rm -Rf $Cachefolder
이 스크립트는 x11docker Wiki 에서 유지됩니다 . 고급 스크립트 인 x11docker 는 GPU 가속, 웹캠 및 프린터 공유 등과 같은 기능도 지원합니다.
다음 은 컨테이너에 X
서버, vnc
서버 또는 sshd
데몬 을 설치하지 않아도되는 간단한 솔루션입니다 . 단순성으로 얻는 것은 보안과 격리에서 잃어 버립니다.
그것은 당신이 사용하여 호스트 시스템에 연결한다고 가정 ssh
으로 X11
전달.
에서 sshd
호스트의 구성, 줄을 추가
X11UseLocalhost no
따라서 호스트의 전달 된 X 서버 포트가 모든 인터페이스 (뿐만 아니라 lo
) 및 특히 Docker 가상 인터페이스에서 열리도록합니다 docker0
.
컨테이너는 실행될 때 .Xauthority
서버에 연결할 수 있도록 파일에 액세스해야 합니다. 이를 위해 호스트의 홈 디렉토리를 가리키는 읽기 전용 볼륨을 정의하고 (현명한 아이디어는 아닙니다!) XAUTHORITY
변수를 적절하게 설정합니다 .
docker run -v $HOME:/hosthome:ro -e XAUTHORITY=/hosthome/.Xauthority
이것으로 충분하지 않으며 호스트에서 DISPLAY 변수를 전달해야하지만 ip로 호스트 이름을 대체해야합니다.
-e DISPLAY=$(echo $DISPLAY | sed "s/^.*:/$(hostname -i):/")
별명을 정의 할 수 있습니다.
alias dockerX11run='docker run -v $HOME:/hosthome:ro -e XAUTHORITY=/hosthome/.Xauthority -e DISPLAY=$(echo $DISPLAY | sed "s/^.*:/$(hostname -i):/")'
다음과 같이 테스트하십시오.
dockerX11run centos xeyes
.Xauthority
파일 자체를 마운트하면 됩니다 -v $HOME/.Xauthority:/root/.Xauthority -e XAUTHORITY=/root/.Xauthority
.
--net=host
컨테이너에서 포트를 열면 호스트에서도 열릴 것입니다.
Jürgen Weigert 의 답변 이 본질적으로이 솔루션을 다루고 있지만 처음에는 거기에 설명 된 내용이 명확하지 않았습니다. 다른 사람이 설명이 필요한 경우를 대비하여 테이크를 추가하겠습니다.
먼저 관련 문서는 X 보안 맨 페이지 입니다.
수많은 온라인 소스는 X11 유닉스 소켓과 ~/.Xauthority
파일을 컨테이너에 마운트하는 것을 제안 합니다. 이러한 솔루션은 종종 컨테이너 사용자가 사용자와 동일한 UID로 끝나는 이유를 실제로 이해하지 못해 운이 좋게 작동하므로 매직 키 인증이 필요하지 않습니다.
먼저 Xauthority 파일의 모드는 0600이므로 컨테이너 사용자는 동일한 UID가 없으면 파일을 읽을 수 없습니다.
파일을 컨테이너에 복사하고 소유권을 변경하더라도 여전히 다른 문제가 있습니다. xauth list
동일한 Xauthority
파일 을 사용하여 호스트 및 컨테이너에서 실행 하면 다른 항목이 나열됩니다. xauth
실행 위치에 따라 항목을 필터링 하기 때문 입니다.
컨테이너의 X 클라이언트 (예 : GUI 앱)는와 동일하게 작동합니다 xauth
. 다시 말해, 사용자의 데스크탑에서 실행중인 X 세션의 매직 쿠키가 표시되지 않습니다. 대신, 이전에 연 모든 "원격"X 세션에 대한 항목이 표시됩니다 (아래에 설명 됨).
따라서 컨테이너의 호스트 이름과 호스트 쿠키와 동일한 16 진 키 (예 : 데스크탑에서 실행중인 X 세션)를 사용하여 새 항목을 추가해야합니다.
containerhostname/unix:0 MIT-MAGIC-COOKIE-1 <shared hex key>
캐치는 xauth add
컨테이너 내부에 쿠키를 추가해야한다는 것입니다 .
touch ~/.Xauthority
xauth add containerhostname/unix:0 . <shared hex key>
그렇지 않으면 xauth
컨테이너 외부에서만 볼 수있는 방식으로 태그를 지정합니다.
이 명령의 형식은 다음과 같습니다.
xauth add hostname/$DISPLAY protocol hexkey
어디 .
대표 MIT-MAGIC-COOKIE-1
프로토콜을.
참고 :.Xauthority
컨테이너 에 복사하거나 바인드 마운트 할 필요가 없습니다 . 표시된대로 빈 파일을 만들고 쿠키를 추가하십시오.
Jürgen Weigert 의 답변은 FamilyWild
연결 유형을 사용하여 호스트에서 새 권한 파일을 작성하고 컨테이너에 복사 하여이 문제를 해결합니다. 먼저을 ~/.Xauthority
사용하여 현재 X 세션에 대한 16 진 키를 추출합니다 xauth nlist
.
따라서 필수 단계는 다음과 같습니다.
FamilyWild
연결 유형 으로 쿠키를 작성하십시오 .FamilyWild
작동 방식 xauth
또는 X 클라이언트가 실행 위치에 따라 Xauthority 파일에서 항목을 필터링 하는 방법을 잘 이해하지 못한다는 것을 인정 합니다. 이에 대한 추가 정보는 환영합니다.
Docker 앱을 배포하려면 사용자의 X 세션에 대한 16 진 키를 가져 와서 앞에서 설명한 두 가지 방법 중 하나로 컨테이너로 가져 오는 컨테이너를 실행하기위한 시작 스크립트가 필요합니다.
또한 권한 부여 프로세스의 메커니즘을 이해하는 데 도움이됩니다.
$DISPLAY
./tmp/.X11-unix
컨테이너에 마운트 된 디렉토리 의 해당 소켓을 통해 X 서버로 해당 항목을 전달합니다 .참고 : X11 Unix 소켓은 여전히 컨테이너에 마운트해야합니다. 그렇지 않으면 컨테이너에 X 서버에 대한 경로가 없습니다. 대부분의 배포는 보안상의 이유로 기본적으로 X 서버에 대한 TCP 액세스를 비활성화합니다.
추가 정보를 얻고 X 클라이언트 / 서버 관계의 작동 방식을보다 잘 이해하려면 SSH X 전달의 예를 살펴 보는 것도 도움이됩니다.
$DISPLAY
SSH 세션 의 값이 자체 X 서버를 가리 키도록 설정합니다.xauth
원격 호스트에 대한 새로운 쿠키를 생성하고,에 추가 Xauthority
로컬 및 원격 사용자를위한 파일입니다.이것은 가볍지 않지만 전체 데스크톱 가상화와 도커 기능 패리티를 제공하는 훌륭한 솔루션입니다. Ubuntu 및 CentOS 용 Xfce4 또는 IceWM이 모두 작동하며이 noVNC
옵션을 사용하면 브라우저를 통해 쉽게 액세스 할 수 있습니다.
https://github.com/ConSol/docker-headless-vnc-container
의 vncserver noVNC
와 함께 실행 됩니다 tigerVNC
. 그런 다음 startx
주어진 창 관리자를 호출 합니다. 또한 libnss_wrapper.so
사용자의 비밀번호 관리를 에뮬레이트하는 데 사용됩니다.
xpra
루트가없는 도커 에서도 시도 했습니다. 루트리스 X. xpra
는 가장 적합한 IMO였으며 VNC보다 효율적입니다.
--device /dev/...
하고 필요한 --cap
권한을 설정 하지 않으면 장착 장치가 데스크탑 (gvfs)에 표시되지 않습니다 . 그것은 격리의 목적을 상실하지만 장치를 통과 할 수 있습니다. 약간의 조정으로 VNC에서 그놈 / KDE를 실행할 수 있다고 생각합니다. Nvidia 카드 (VNC 또는 Xpra 없음)가있는 도커에서 여러 개의 X를 실행 했으므로 확실히 가능합니다.
http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/에 제공된 솔루션 은 컨테이너 내부에서 GUI 응용 프로그램을 시작하는 쉬운 방법 인 것 같습니다 (Firefox를 사용해 보았습니다) 우분투 14.04 이상)하지만 저자가 게시 한 솔루션에 약간의 추가 변경이 필요하다는 것을 알았습니다.
특히 컨테이너를 실행하기 위해 저자는 다음과 같이 언급했습니다.
docker run -ti --rm \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
firefox
그러나 (같은 사이트에 대한 특정 의견을 기반으로) 두 가지 추가 옵션이 있음을 발견했습니다.
-v $HOME/.Xauthority:$HOME/.Xauthority
과
-net=host
파이어 폭스가 제대로 작동하려면 컨테이너를 실행하는 동안 지정해야합니다.
docker run -ti --rm \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v $HOME/.Xauthority:$HOME/.Xauthority \
-net=host \
firefox
해당 페이지의 정보와 다음 추가 결과가 포함 된 도커 이미지를 만들었습니다. https://hub.docker.com/r/amanral/ubuntu-firefox/
/tmp/.X11-unix
소켓을 전혀 통과시키지 못한다는 것을 알았 습니다. 그것은 단지 마운팅 .Xauthority
과 작동합니다 --net=host
.
/tmp/.X11-unix
도 커가 고정 디렉토리에서 볼륨 마운트를 자동으로 거부하므로 볼륨으로 사용하면 더 이상 작동하지 않습니다.
--network=host
. 컨테이너가 호스트의 네트워크 스택에 대한 전체 액세스 권한을 부여하므로 수행하려는 작업에 따라 바람직하지 않을 수 있습니다. 데스크탑에서 컨테이너화 된 GUI를 실행하는 것만으로도 문제가되지 않습니다.
lord.garbage 는 VNC, SSH 및 X11 전달을 사용하지 않고 컨테이너에서 GUI 앱을 실행 하는 또 다른 솔루션 이 있습니다 . 여기에도 언급되어 있습니다 .
나는 파티에 늦게 해요,하지만 XQuartz의 길을 가고 싶지 않아 맥 사용자를 위해, 여기에 데스크탑 환경 (XFCE)를 사용하여, 페도라 이미지 구축 작업 예입니다 Xvfb
및 VNC
. 간단하고 작동합니다.
Mac에서는 에 연결 하는 화면 공유 (기본) 응용 프로그램을 사용하여 액세스 할 수 있습니다 localhost:5901
.
도커 파일 :
FROM fedora
USER root
# Set root password, so I know it for the future
RUN echo "root:password123" | chpasswd
# Install Java, Open SSL, etc.
RUN dnf update -y --setopt=deltarpm=false \
&& dnf install -y --setopt=deltarpm=false \
openssl.x86_64 \
java-1.8.0-openjdk.x86_64 \
xorg-x11-server-Xvfb \
x11vnc \
firefox \
@xfce-desktop-environment \
&& dnf clean all
# Create developer user (password: password123, uid: 11111)
RUN useradd -u 11111 -g users -d /home/developer -s /bin/bash -p $(echo password123 | openssl passwd -1 -stdin) developer
# Copy startup script over to the developer home
COPY start-vnc.sh /home/developer/start-vnc.sh
RUN chmod 700 /home/developer/start-vnc.sh
RUN chown developer.users /home/developer/start-vnc.sh
# Expose VNC, SSH
EXPOSE 5901 22
# Set up VNC Password and DisplayEnvVar to point to Display1Screen0
USER developer
ENV DISPLAY :1.0
RUN mkdir ~/.x11vnc
RUN x11vnc -storepasswd letmein ~/.x11vnc/passwd
WORKDIR /home/developer
CMD ["/home/developer/start-vnc.sh"]
start-vnc.sh
#!/bin/sh
Xvfb :1 -screen 0 1024x768x24 &
sleep 5
x11vnc -noxdamage -many -display :1 -rfbport 5901 -rfbauth ~/.x11vnc/passwd -bg
sleep 2
xfce4-session &
bash
# while true; do sleep 1000; done
필요한 경우 링크 된 readme 에서 빌드 및 실행 명령을 확인하십시오.
Jürgen Weigert 의 답변을 바탕으로 몇 가지 개선 사항이 있습니다.
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_DIR=/tmp/.docker.xauth
XAUTH=$XAUTH_DIR/.xauth
mkdir -p $XAUTH_DIR && touch $XAUTH
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
docker run -ti -v $XSOCK:$XSOCK -v $XAUTH_DIR:$XAUTH_DIR -e XAUTHORITY=$XAUTH xeyes
유일한 차이점은 $ XAUTH 파일을 배치하고 $ XAUTH 파일 대신 $ XAUTH_DIR 디렉토리를 도커 컨테이너에 마운트하는 데 사용되는 $ XAUTH_DIR 디렉토리를 생성한다는 것입니다.
이 방법의 장점은 / tmp에 $ XAUTH_DIR이라는 빈 폴더를 만들고 모드를 777로 변경하는 /etc/rc.local에 명령을 작성할 수 있다는 것입니다.
tr '\n' '\000' < /etc/rc.local | sudo tee /etc/rc.local >/dev/null
sudo sed -i 's|\x00XAUTH_DIR=.*\x00\x00|\x00|' /etc/rc.local >/dev/null
tr '\000' '\n' < /etc/rc.local | sudo tee /etc/rc.local >/dev/null
sudo sed -i 's|^exit 0.*$|XAUTH_DIR=/tmp/.docker.xauth; rm -rf $XAUTH_DIR; install -m 777 -d $XAUTH_DIR\n\nexit 0|' /etc/rc.local
시스템 재시작시, 사용자 로그인 전에 컨테이너의 재시작 정책이 "항상"인 경우 docker는 $ XAUTH_DIR 디렉토리를 자동으로 마운트합니다. 사용자 로그인 후 ~ / .profile에 $ XAUTH 파일을 생성하는 명령을 작성할 수 있으며 컨테이너는이 $ XAUTH 파일을 자동으로 사용합니다.
tr '\n' '\000' < ~/.profile | sudo tee ~/.profile >/dev/null
sed -i 's|\x00XAUTH_DIR=.*-\x00|\x00|' ~/.profile
tr '\000' '\n' < ~/.profile | sudo tee ~/.profile >/dev/null
echo "XAUTH_DIR=/tmp/.docker.xauth; XAUTH=\$XAUTH_DIR/.xauth; touch \$XAUTH; xauth nlist \$DISPLAY | sed -e 's/^..../ffff/' | xauth -f \$XAUTH nmerge -" >> ~/.profile
결국 컨테이너는 시스템을 다시 시작하고 사용자가 로그인 할 때마다 Xauthority 파일을 자동으로 가져옵니다.
다른 솔루션은 작동하지만 여기에 대한 솔루션이 docker-compose
있습니다.
이 오류를 해결하려면 $ DISPLAY 및 .X11-unix를 docker에 전달하고 docker를 시작한 사용자에게 xhost에 대한 액세스 권한을 부여해야합니다.
docker-compose.yml
파일 내 :
version: '2'
services:
node:
build: .
container_name: node
environment:
- DISPLAY
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
터미널 또는 스크립트에서 :
xhost +si:localuser:$USER
xhost +local:docker
export DISPLAY=$DISPLAY
docker-compose up
Nvidia 드라이버를 사용한 OpenGL 렌더링의 경우 다음 이미지를 사용하십시오.
https://github.com/thewtex/docker-opengl-nvidia
다른 OpenGL 구현의 경우 이미지가 호스트와 동일한 구현인지 확인하십시오.
유사 @Nick 의 대답했지만, 그의 해결책은 나를 위해 작동하지 않았다.
먼저을 실행하여 socat을 brew install socat
설치하고 XQuartz를 설치 하십시오 ( https://www.xquartz.org/ )
그런 다음 의견 섹션의 다음 단계 ( http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/ )를 따르십시오 .
1. in one mac terminal i started:
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
2. and in another mac terminal I ran:
docker run -ti --rm \
-e DISPLAY=$(ipconfig getifaddr en0):0 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
firefox
데비안 도커 컨테이너에서도 CLion을 시작할 수있었습니다.
BRIDGE 네트워크가있는 Docker. 디스플레이 관리자 lightdm이있는 Ubuntu 16.04의 경우 :
cd /etc/lightdm/lightdm.conf.d
sudo nano user.conf
[Seat:*]
xserver-allow-tcp=true
xserver-command=X -listen tcp
더 많은 개인 권한을 사용할 수 있습니다
xhost +
docker run --volume="$HOME/.Xauthority:/root/.Xauthority:rw" --env="DISPLAY=$HOST_IP_IN_BRIDGE_NETWORK:0" --net=bridge $container_name
이미 이미지를 작성한 경우의 또 다른 대답 :
sudo없이 docker를 호출하십시오 (docker 를 수정하는 방법 : 허가 거부 문제가 있음 )
호스트와 컨테이너 공유간에 동일한 사용자 및 홈 및 암호 공유 (팁 : 사용자 이름 대신 사용자 ID 사용)
드라이버 종속 라이브러리가 제대로 작동하는 dev 폴더
플러스 X11 앞으로.
docker run --name=CONTAINER_NAME --network=host --privileged \
-v /dev:/dev \
-v `echo ~`:/home/${USER} \
-p 8080:80 \
--user=`id -u ${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" \
-it REPO:TAG /bin/bash
많은 것들이 동일하다면 도커를 사용하는 요점은 무엇입니까? 글쎄, 내가 생각할 수있는 한 가지 이유는 패키지 depency hell ( https://en.wikipedia.org/wiki/Dependency_hell ) 을 극복하는 것입니다 .
따라서 이러한 유형의 사용법은 내가 생각하는 개발자에게 더 적합합니다.
echo ~
: / home / $ {USER} --user = id -u ${USER}
--env = "DISPLAY"--volume = "/ etc / passwd : / etc / passwd : ro "-it REPO : TAG / bin / bash
나는 USB 카메라를 사용하여 비디오 스트림을 실행했다. opencv
에서 docker
다음 단계를 수행하여를 :
도 커가 X 서버에 액세스하도록 허용
xhost +local:docker
X11 Unix 소켓 및 X 인증 파일 작성
XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth
적절한 권한 추가
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
Qt 렌더링 속도를 "기본"으로 설정하여 X11 렌더링 엔진을 우회하지 않습니다.
export QT_GRAPHICSSYSTEM=native
Qt에게 MIT-SHM (공유 메모리)을 사용하지 말라고 알려주십시오-그렇게하면 보안 측면에서 더 안전해야합니다
export QT_X11_NO_MITSHM=1
docker run 명령 업데이트
docker run -it \
-e DISPLAY=$DISPLAY \
-e XAUTHORITY=$XAUTH \
-v $XSOCK:$XSOCK \
-v $XAUTH:$XAUTH \
--runtime=nvidia \
--device=/dev/video0:/dev/video0 \
nvcr.io/nvidia/pytorch:19.10-py3
참고 : 프로젝트를 완료하면 액세스 제어를 기본값으로 되돌립니다. xhost -local:docker
자세한 내용은: Docker와 함께 GUI 사용