GUI uygulamalarını Docker kapsayıcısında çalıştırabilir misiniz?


409

GUI uygulamalarını Docker kapsayıcısında nasıl çalıştırabilirsiniz ?

vncserverÖrneğin Firefox dediği yere ekstra bir speedbump sanal alanı ekleyebileceğiniz herhangi bir resim veya başka bir şey var mı?


Bu soru Windows için değil, sadece Linux (yaş ve cevapların içeriği temel alınarak) ile ilgilidir. Öyleyse, bunu açıklığa kavuşturmak için başlığı düzenleyebilir miyiz? Teşekkürler
UuDdLrLrSs


Yanıtlar:


238

Firefox ile birlikte bir vncserver yükleyebilirsiniz :)

Ben burada bir görüntü, vnc / firefox itti: docker pull creack/firefox-vnc

Görüntü bu Dockerfile ile yapılmıştır:

# 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'

Bu, VNC'yi şu parolayla çalıştıran bir Docker konteyneri oluşturur 1234:

Docker sürüm 18 veya daha yenisi için:

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

Docker sürüm 1.3 veya daha yeni sürümler için:

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

Sürüm 1.3'ten önceki Docker için:

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

2
Bunu uzaktan görüntülemek için VNC istemcisini nasıl kullanırım? IP + bağlantı noktasında yazmak işe yaramıyor gibi görünüyor.
user94154

17
İlk olarak, tahsis edilen bağlantı noktasını kontrol etmeniz gerekir (yaparak docker inspect <container id>veya basitçe docker ps, daha sonra bulduğunuz bağlantı noktası ile ana makinenizin
ipine bağlanırsınız

9
creackfirefox-vnc görüntüsü hatayla başarısız oluyor: VNC şifresini girin: stty: standart giriş: Cihaz aygıtları için uygun olmayan ioctl: Böyle bir dosya veya dizin yok stty: standart giriş: x11vnc -usepw: aygıtı için uygun ioctl kullanılacak bir şifre bulamadı.
alfonsodev


7
Kullanıcı adı yok, şifre yanıtta açıkça belirtiliyor ve herhangi bir vnc istemcisi yapacak. Benim durumumda, doğal osx olanı seviyorum. (bulucudan + K komutuna basın ve vnc: // <docker ip>: <kapsayıcıya maruz kalan bağlantı noktası>
öğesine bağlanın

195

Xauthority daha yeni sistemlerle ilgili bir sorun haline geliyor. Docker kaplarımı çalıştırmadan önce xhost + ile herhangi bir korumayı atabilirim veya iyi hazırlanmış bir Xauthority dosyasına geçebilirim. Tipik Xauthority dosyaları ana bilgisayar adına özeldir. Docker ile her kapsayıcı farklı bir ana bilgisayar adına sahip olabilir (docker run -h ile ayarlanır), ancak ana bilgisayarın sistemiyle aynı olan kabın ana bilgisayar adını ayarlamak bile benim durumuma yardımcı olmadı. xeyes (Bu örneği beğendim) sadece sihirli çerezi görmezden gelir ve sunucuya hiçbir kimlik bilgisi vermez. Bu nedenle 'Protokol belirtilmedi' Ekran açılamıyor 'hata mesajı alıyoruz

Xauthority dosyası, ana bilgisayar adının önemli olmayacağı şekilde yazılabilir. Kimlik Doğrulama Ailesi'ni 'FamilyWild' olarak ayarlamamız gerekiyor. Emin değilim, eğer xauth bunun için uygun bir komut satırına sahipse, işte bunu yapmak için xauth ve sed'i birleştiren bir örnek var. Nlist çıktısının ilk 16 bitini değiştirmemiz gerekiyor. FamilyWild değeri 65535 veya 0xffff'dir.

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

8
Sadece bir not, -v $XSOCK:$XSOCK -v $XAUTH:$XAUTHkısaltılabilir-v $XSOCK -v $XAUTH
Piotr Aleksander Chmielowski

2
@PiotrAleksanderChmielowski benim için çalışmadı, Docker sürüm 1.12.0, yapı 8eab29e
tbc0

14
@Dirk: Sen değiştirmek isteyebilirsiniz :0ile $DISPLAY. Bu xauth nlist $DISPLAY | ...ve anlamına gelir docker run -ti -e DISPLAY=$DISPLAY .... Genellikle X DISPLAY, :0her zaman değil (ve özellikle ssh -X ile bağlanıyorsanız).
johndodo

4
Ubuntu 16.04'te xauth /tmp/.docker.xauthdosyayı izinlerle oluşturur 600. Bu, docker kapsayıcısının içindeki xauth'un dosyayı okuyamamasına neden olur. xauth listDocker kapsayıcısının içinde çalışarak doğrulayabilirsiniz . Bunu çözmek chmod 755 $XAUTHiçin xauth nlist :0 | ...komuttan sonra ekledim .
Abai

2
@Abai 444 veya 644 yeterliyse neden 755 kullanılıyor?
Daniel Alder

68

Bu blog girişini buldum ve burada sizinle paylaşmak istiyorum çünkü bunu yapmanın en iyi yolu olduğunu ve çok kolay olduğunu düşünüyorum.

http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/

Artıları:
+ docker kapsayıcısında x sunucu
yok + vnc istemci / sunucu gerekli değil
+ x iletimli ssh yok
+ çok daha küçük docker kapsayıcıları

İNŞAAT:
- anasistemde x kullanma (güvenli korumalı alan anlamına gelmez)

bağlantı bir gün başarısız olacak durumunda ben burada en önemli kısmını koydu:
dockerfile:

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

resmi oluştur:

docker build -t firefox .

ve run komutu:

docker run -ti --rm \
   -e DISPLAY=$DISPLAY \
   -v /tmp/.X11-unix:/tmp/.X11-unix \
   firefox

tabii ki bunu run komutunda da yapabilirsiniz sh -c "echo script-here"

İPUCU: ses için şuraya bakın: https://stackoverflow.com/a/28985715/2835523


Bunu Windows 7'de nasıl yapabilirim? Bir X sunucusu kurmam gerekir mi?
walksignison

3
Buradaki çoğu yanıt olarak, bu sadece windows X sunucusu pencere sistemini destekleyene kadar sadece unix için geçerlidir.
A. Binzxxxxxx

X sunucusunu Windows'a yüklediğimde veya hatta bir X sunucusunu Docker kapımla paketlediğimde işe yarayabileceğini düşünüyor musunuz?
walksignison

1
Klasör apt-get -y install sudooluşturmak için Dockerfile'a da yüklemeniz gerektiğini düşünüyorum /etc/sudoers.d.
mulg0r

1
herhangi bir ana bilgisayardan X'e bağlantılara izin vermek de gerekebilir$ xhost +
Bandoos

52

Liman işçisi veri birimlerinde, xorg'un unix alan soketini kap içinde göstermek çok kolaydır.

Örneğin, böyle bir Dockerfile ile:

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

Aşağıdakileri yapabilirsiniz:

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

Bu elbette X-yönlendirme ile aynıdır. Kapsayıcıya ana bilgisayardaki xserver'a tam erişim izni verir, bu nedenle yalnızca içeride ne olduğuna güveniyorsanız önerilir.

Not: Güvenlik konusunda endişeleriniz varsa, uygulamayı zorunlu veya rol tabanlı erişim kontrolüyle sınırlamak daha iyi bir çözüm olacaktır . Docker oldukça iyi bir izolasyon sağlar, ancak farklı bir amaç düşünülerek tasarlanmıştır. Endişenizi gidermek için tasarlanmış AppArmor , SELinux veya GrSecurity kullanın .


5
Ayrıca xhost gibi bir araç kullanarak diğer sunuculardan X Sunucusuna erişime izin vermeniz gerekir. Tamamen açmak xhost +için ana bilgisayarda kullanın .
Tully

3
@Tully sadece xhost +localgereklidir. Ancak ~/.Xauthoritydosyayı kapta kullanılabilir hale getirmek daha iyi olur , böylece kendini doğrulayabilir.
Aryeh Leib Taurog

3
Mac'te çalıştırmayı başardınız mı (boot2docker kullanarak)?
Karl Forner

4
Bu benim için daha önce docker 1.5 ile bir Ubuntu 14.04 dizüstü bilgisayarda oldukça iyi çalışıyordu; ama şimdi benim için hata ile Ubuntu 15.04, docker 1.6.2'de başarısız oluyor Can't open display: :0. Herhangi bir fikir?
cboettig

6
Ben xhost +si:localuser:$USERsadece konteyneri başlatan kullanıcıya yetki verirdim.
Nick Breen

26

Alt kullanıcıyı da kullanabilirsiniz: https://github.com/timthelion/subuser

Bu, birçok gui uygulamasını docker'da paketlemenizi sağlar. Firefox ve emacs şu ana kadar test edilmiştir. Firefox ile webGL çalışmıyor. Chromium hiç çalışmıyor.

EDIT: Ses çalışıyor!

EDIT2: Bunu ilk yayınladığımdan bu yana, alt kullanıcı çok ilerledi. Artık subuser.org'da bir web sitem ve XPRA köprüleme yoluyla X11'e bağlanmak için yeni bir güvenlik modelim var .


3
Subuser'ın hala çok yeni ve nispeten test edilmediğini lütfen unutmayın. Herhangi bir sorunla karşılaşırsanız lütfen hata raporları gönderin!
timthelion

Yapabileceğin herhangi bir yol varsa X11'den kaçınırdım. Katil uygulamanız docker'da tor proxy'yi çalıştırıyor ve güvenlik duvarı vb. Tüm ağı tor docker üzerinden zorlayacak şekilde bir çocuk docker'da eklentileri olan tam bir tarayıcı çalıştırıyor olacaktı. Zengin içeriğe izin verdiğiniz için web kullanılabilirliği için mevcut tarayıcı tarayıcı paketinde turlar yayınlanır.
Will

1
X11 güvenliği ile sorun sizin için mi? Yoksa bunun pencerelerle çalışmasını mı istiyorsunuz? Yoksa bunun uzaktan çalışmasını mı istiyorsunuz? Yukarıdakilerin hepsi? Ben vnc ile bu iş yapmak oldukça mümkün olduğunu düşünüyorum (gerçi vnc bağımlılık ekler çünkü varsayılan yöntem yapmak olmaz). Subuser'ın uzaktan çalışmasını sağlamak gerçekten mümkün / anlamlı değildir. Ayrıca var: github.com/rogaha/docker-desktop ama hata raporlarından xpra gerçek hayatta kullanılamayabilir gibi görünüyor.
timthelion

24

OSX

Jürgen Weigert , Ubuntu'da benim için çalışan en iyi cevaba sahip, ancak OSX'te docker, VirtualBox'ın içinde çalışıyor ve böylece çözüm biraz daha çalışmadan çalışmıyor.

Bu ek bileşenlerle çalıştım:

  1. Xquartz (OSX artık X11 sunucusu ile gelmiyor)
  2. socat ile soket yönlendirme (demlemek kurulum socat)
  3. kabı başlatmak için bash betiği

OSX için bu cevabı geliştirmek için kullanıcı yorumlarını takdir ediyorum, X için soket yönlendirmenin güvenli olup olmadığından emin değilim, ancak amacım docker kapsayıcısını sadece yerel olarak çalıştırmak için.

Ayrıca, komut dosyası biraz kırılgandır, çünkü yerel kablosuz ağımızda olduğu için makinenin IP adresini almak kolay değildir, bu yüzden her zaman rastgele bir IP'dir.

Kapsayıcıyı başlatmak için kullandığım BASH betiği:

#!/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 ve matplotlib'in bu yaklaşımla çalışmasını sağlayabiliyorum.

Windows 7 ve sonraki sürümleri

MobaXterm ile Windows 7 ve sonraki sürümlerde biraz daha kolay:

  1. Windows için MobaXterm'i yükleyin
  2. MobaXterm'i başlat
  3. Yapılandırma X sunucusu: Ayarlar -> X11 (sekme) -> set X11 Uzaktan Erişim için tam
  4. Kapsayıcıyı başlatmak için bu BASH komut dosyasını kullanın

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

PC üzerinde çalışan xeyes


bash betiği ile ne demek istediğini anlamadım - nasıl pencerelerde çalıştırmak?
deller

@deller GIT kullanarak pencerelerde yazılım geliştirme yapıyorum, bu yüzden kullanabileceğim GIT-bash kabuğuna sahibim.
Nick

Adımları takip ettim. Ancak, ben almak error: XDG_RUNTIME_DIR not set in the environment.ve Error: cannot open display: VAIO:0.0. Böyle bir şeyle karşılaştın mı?
user3275095

1
Kullanıcı bulunamadı yani "passwd dosyasında eşleşen giriş yok" ile ilgili bir hata alıyorum Herhangi bir olası satış?
walksignison

19

Ana bilgisayar ekranını paylaşma: Diğer yanıtlarda belirtildiği gibi 0'ın iki dezavantajı vardır:

  • Bazı X güvenlik sızıntıları nedeniyle kap izolasyonunu bozar. Örneğin, xevveya ile keylogging xinputmümkündür ve ile ana bilgisayar uygulamalarının uzaktan kontrolü xdotool.
  • Uygulamalar, MIT-SHM uzantısı için paylaşılan paylaşılan bellek eksik olduğundan işleme hataları ve kötü RAM erişim hatalarına sahip olabilir. (İzolasyon ayrıştırma seçeneği ile de sabitlenebilir --ipc=host).

Xephyr'de bu sorunları ele alan bir docker görüntüsü çalıştırmak için örnek bir komut dosyasının altında.

  • Docker uygulamaları iç içe bir X sunucusunda çalışırken X güvenlik sızıntılarını önler.
  • RAM erişim hatalarını önlemek için MIT-SHM devre dışı.
  • Konteyner güvenliği ile iyileştirildi --cap-drop ALL --security-opt no-new-privileges. Ayrıca kapsayıcı kullanıcısı kök değil .
  • Xephyr ekranına erişimi kısıtlamak için bir X çerezi oluşturulur.

Komut dosyası, önce Xephyr'de çalıştırılacak bir ana bilgisayar pencere yöneticisi, ikincisi bir docker görüntüsü, isteğe bağlı olarak üçüncü olarak bir görüntü komutu yürütülecek bazı argümanlar bekler. Docker'da bir masaüstü ortamı çalıştırmak için, ana makine pencere yöneticisi yerine ":" kullanın.

Xephyr penceresinin kapatılması liman işçisi konteyner uygulamalarını sonlandırır. Kenetlenmiş uygulamaların sonlandırılması Xephyr penceresini kapatır.

Örnekler:

  • xephyrdocker "openbox --sm-disable" x11docker/lxde pcmanfm
  • xephyrdocker : x11docker/lxde
  • xephyrdocker xfwm4 --device /dev/snd jess/nes /games/zelda.rom

xephyrdocker betiği:

#! /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

Bu komut dosyası x11docker wiki'de tutulur . Daha gelişmiş bir komut dosyası, GPU hızlandırma, web kamerası ve yazıcı paylaşımı ve benzeri özellikleri de destekleyen x11docker'dır .


18

Kapsayıcıya herhangi bir Xsunucu, vncsunucu veya sshdarka plan programı yüklemeye gerek kalmayan hafif bir çözüm . Sadelikte kazandığı şey güvenlik ve izolasyonda kaybeder.

Yönlendirme sshile ana makineye bağlandığınızı varsayar X11.

Gelen sshdkonağın yapılandırma satırı ekleyin

X11UseLocalhost no

Böylece ana bilgisayarda iletilen X sunucusu bağlantı noktası tüm arabirimlerde (sadece değil lo) ve özellikle Docker sanal arabiriminde açılır docker0.

Kapsayıcı çalıştırıldığında, .Xauthoritysunucuya bağlanabilmesi için dosyaya erişmesi gerekir . Bunu yapmak için, ana bilgisayardaki ana dizini işaret eden salt okunur bir birim tanımlarız (akıllıca bir fikir olmayabilir!) Ve XAUTHORITYdeğişkeni buna göre ayarladık .

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

Bu yeterli değil, ayrıca DISPLAY değişkenini ana bilgisayardan geçirmeliyiz, ancak ana bilgisayar adını ip ile değiştirmeliyiz:

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

Bir takma ad tanımlayabiliriz:

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

Ve şu şekilde test edin:

dockerX11run centos xeyes

2
(Bu güvenilen uygulamalar için mükemmeldir, ama, X-yönlendirmeyi kaçınmak istiyorum korumalı alan her türlü için..)
Will

1
Bunun yerine kabın içine bütün ev dizinini monte istemiyorsanız sadece monte edebilirsiniz .Xauthoritydosyayı kendisi: -v $HOME/.Xauthority:/root/.Xauthority -e XAUTHORITY=/root/.Xauthority.
Robert Haines

2
Değiştirmek yerine , komut için X11UseLocalhostek seçeneği de kullanabilirsiniz ( burada bulunur ). --net=hostdocker run
ingomueller.net

--net=hostkonteynerde bir liman açarsanız şu an kötü bir fikirdir, ev sahibinde de açık olacaktır ...
MrR

16

Jürgen Weigert'in yanıtı esasen bu çözümü kapsıyor olsa da, ilk başta orada tarif edilen şey benim için net değildi. Bu yüzden, başka birinin açıklığa ihtiyacı olması durumunda, buna katılıyorum.

Öncelikle, ilgili belgeler X güvenlik kılavuzudur .

Birçok çevrimiçi kaynak sadece X11 unix soketinin ve ~/.Xauthority dosyayı konteynere . Bu çözümler genellikle, örneğin kap kullanıcısı, kullanıcıyla aynı UID ile sonuçlandığını gerçekten anlamadan, genellikle şans eseri çalışır, bu nedenle sihirli anahtar yetkilendirmesine gerek yoktur.

Öncelikle, Xauthority dosyasında 0600 modu vardır, bu nedenle kapsayıcı kullanıcısı aynı UID'ye sahip olmadığı sürece okuyamaz.

Dosyayı kapsayıcıya kopyalayıp sahibini değiştirseniz bile, başka bir sorun daha vardır. Eğer çalıştırırsanız xauth listkonak ve konteyner üzerinde, aynı ile Xauthoritydosyanın, listelenen farklı girişleri göreceksiniz. Bunun nedeni xauth, girdilerin çalıştığı yere göre filtrelenmesidir.

Kaptaki X istemcisi (yani GUI uygulaması) ile aynı şekilde davranacaktır xauth. Başka bir deyişle, kullanıcının masaüstünde çalışan X oturumu için sihirli çerezi görmez. Bunun yerine, daha önce açtığınız tüm "uzak" X oturumlarının girişlerini görür (aşağıda açıklanmıştır).

Yapmanız gereken, kapsayıcı ana bilgisayar adı ve ana bilgisayar çerezi (örn. Masaüstünüzde çalışan X oturumu) ile aynı hex anahtarıyla yeni bir giriş eklemektir.

containerhostname/unix:0   MIT-MAGIC-COOKIE-1   <shared hex key>

Yakalama, çerezin xauth addkabın içine eklenmesi gerektiğidir :

touch ~/.Xauthority
xauth add containerhostname/unix:0 . <shared hex key>

Aksi takdirde, xauthetiketi yalnızca kap dışında görünecek şekilde etiketler.

Bu komutun biçimi:

xauth add hostname/$DISPLAY protocol hexkey

Burada protokolü .temsil eder MIT-MAGIC-COOKIE-1.

Not:.Xauthority Kabın içine kopyalanmasına veya bağlanmasına gerek yoktur . Gösterildiği gibi boş bir dosya oluşturun ve çerezi ekleyin.

Jürgen Weigert'in yanıtı FamilyWild, ana bilgisayarda yeni bir yetki dosyası oluşturmak ve kapsayıcıya kopyalamak için bağlantı türünü kullanarak bu sorunu çözer . İlk gelen mevcut x oturumu için altıgen anahtarı ayıklar unutmayın ~/.Xauthoritykullanarak xauth nlist.

Yani gerekli adımlar:

  • Kullanıcının geçerli X oturumu için çerezin onaltılık anahtarını çıkarın.
  • Kapsayıcıda kapsayıcı ana bilgisayar adı ve paylaşılan hex anahtarıyla yeni bir Xauthority dosyası oluşturun (veya FamilyWildbağlantı türüyle bir tanımlama bilgisi oluşturun ).

Nasıl FamilyWildçalıştığını ya xauthda X istemcilerinin çalıştıkları yere bağlı olarak Xauthority dosyasındaki girdileri nasıl filtrelediğini çok iyi anlamadığımı itiraf ediyorum . Bu konuda ek bilgi kabul edilir.

Docker uygulamanızı dağıtmak istiyorsanız, kullanıcının X oturumu için onaltılık anahtarı alan kapsayıcıyı çalıştırmak ve daha önce açıklanan iki yoldan biriyle kapsayıcıya aktarmak için bir başlangıç ​​komut dosyasına ihtiyacınız vardır.

Ayrıca, yetkilendirme sürecinin mekaniğini anlamaya yardımcı olur:

  • Kapta çalışan bir X istemcisi (yani GUI uygulaması), Xauthority dosyasında kabın ana bilgisayar adıyla ve değeriyle eşleşen bir çerez girdisi arar $DISPLAY.
  • Eşleşen bir giriş bulunursa, X istemcisi yetkilendirme isteğiyle /tmp/.X11-unixbirlikte kapsayıcıya takılı dizindeki uygun yuva aracılığıyla X sunucusuna iletir.

Not: X11 Unix soketinin hala kaba takılması gerekir, aksi takdirde kabın X sunucusuna giden yolu yoktur. Çoğu dağıtım, güvenlik nedeniyle X sunucusuna TCP erişimini devre dışı bırakır.

Ek bilgi ve X istemci / sunucu ilişkisinin nasıl çalıştığını daha iyi kavramak için, SSH X yönlendirme örneğine bakmak da yararlıdır:

  • Uzak bir makinede çalışan SSH sunucusu kendi X sunucusunu taklit eder.
  • $DISPLAYSSH oturumundaki değerini kendi X sunucusunu gösterecek şekilde ayarlar .
  • xauthUzak ana bilgisayar için yeni bir çerez oluşturmak için kullanır ve Xauthorityhem yerel hem de uzak kullanıcılar için dosyalara ekler .
  • GUI uygulamaları başlatıldığında, SSH'nin taklit edilmiş X sunucusuyla konuşurlar.
  • SSH sunucusu bu verileri yerel masaüstünüzdeki SSH istemcisine geri iletir.
  • Yerel SSH istemcisi, verileri SSH istemcisi sanki bir X istemcisiymiş gibi (yani GUI uygulaması) masaüstünüzde çalışan X sunucusu oturumuna gönderir.
  • X sunucusu, GUI'yi masaüstünüzde oluşturmak için alınan verileri kullanır.
  • Bu alışverişin başlangıcında, uzak X istemcisi de yeni oluşturulan çerezi kullanarak bir yetkilendirme isteği gönderir. Yerel X sunucusu, yerel kopyasıyla karşılaştırır.

12

Bu hafif değil, docker özellik tam masaüstü sanallaştırma ile parite veren güzel bir çözümdür. Ubuntu ve CentOS için hem Xfce4 hem de IceWM çalışır ve noVNCseçenek tarayıcı aracılığıyla kolay erişim sağlar.

https://github.com/ConSol/docker-headless-vnc-container

'S vncserver'ın noVNCyanı sıra çalışır tigerVNC. Sonra startxverilen Pencere Yöneticisi'ni çağırır . Ayrıca libnss_wrapper.so, kullanıcılar için parola yönetimini taklit etmek için kullanılır.


bunu test eden var mı?
guilhermecgs

3
@guilhermecgs evet ve iyi çalışıyor. O zamandan beri xpra, rootsuz X olan docker'da da denedim . xpraEn uygun IMO idi ve VNC'den daha verimli.
dashesy

Açık olmak gerekirse ... Bu görüntü ile tam bir masaüstü deneyimi (GNOME, KDE) alabilir miyim?
guilhermecgs

Sadece Xfce4 ve IceWM denedim (ki bu repoda). Tabii ki deneyim sınırlı olacak, örneğin bağlantı istasyonuna geçip --device /dev/...gerekli --capayrıcalıkları ayarlamadığınız sürece montaj cihazları masaüstünde (gvfs) görünmeyecek . Bu, çevreleme amacını yener, ancak cihazlardan geçebilirsiniz. Bazı ince ayarlarla VNC altında GNOME / KDE çalıştırmanın mümkün olduğuna inanmalıyım. Nvidia kartları (VNC veya Xpra yok) ile docker'da birden fazla X koştum, bu yüzden kesinlikle yapılabilir.
dashesy

Şimdiye kadar denemedik. Bununla ilgili en büyük zorluk, çalışan bir D-Bus arka plan programı getirmek olacaktır. GNOME veya KDE masaüstü bilgisayarların çoğunun bunlara ihtiyacı olacaktır. Mayıs ubuntu-masaüstü-LXDE-vnc projesi size orada yardımcı olur.
toschneck

11

Http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/ adresinde verilen çözüm, GUI uygulamalarını konteynerlerin içinden başlatmanın kolay bir yolu gibi görünüyor (Firefox için denedim 14.04), ancak yazar tarafından gönderilen çözümde küçük bir ek değişiklik gerektiğini buldum.

Özellikle, kabı çalıştırmak için yazar şunları söyledi:

    docker run -ti --rm \
    -e DISPLAY=$DISPLAY \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    firefox

Ama buldum (aynı sitede belirli bir yoruma dayanarak) iki ek seçenek

    -v $HOME/.Xauthority:$HOME/.Xauthority

ve

    -net=host 

firefox'un düzgün çalışması için kapsayıcı çalıştırılırken belirtilmesi gerekir:

    docker run -ti --rm \
    -e DISPLAY=$DISPLAY \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -v $HOME/.Xauthority:$HOME/.Xauthority \
    -net=host \
    firefox

Bu sayfadaki bilgileri ve bu ek bulguları içeren bir liman işçisi resmi oluşturdum: https://hub.docker.com/r/amanral/ubuntu-firefox/


3
/tmp/.X11-unixSoketi hiç geçemediğini bile buldum . Sadece montaj .Xauthorityve ile çalışır --net=host.
CMCDragonkai

2
Bu aslında bugünlerde çalışan tek çözüm. /tmp/.X11-unixBirim olarak kullanıldığında artık çalışmaz, çünkü docker yapışkan dizinlerden birim bağlamalarını sessizce reddeder.
Christian Hujer

1
Bence hangi dağıtımı kullandığınıza bağlı. X11 Unix soketini kesinlikle CentOS'a bağlayabilirsiniz. Ne yaptığını anlamak da önemlidir --network=host. Kapsayıcıya, ne yapmaya çalıştığınıza bağlı olarak istenmeyen ana bilgisayarın ağ yığınına tam erişim sağlar. Masaüstünüzde kapsayıcı GUI'leri çalıştırmakla uğraşıyorsanız, önemli değil.
orodbhen


7

Bir GUI uygulamasını başsız çalıştırmak istiyorsanız, burada okuyun . Yapmanız gereken sanal bir monitör xvfbveya benzeri bir yazılım oluşturmaktır. Selenyum testlerini örneğin tarayıcılarda yapmak istiyorsanız bu çok yararlıdır.

Hiçbir yerde bahsedilmeyen bir şey, bazı yazılımların aslında Linux kapları ile kum boks kullanmasıdır. Örneğin --privileged, kapsayıcıyı çalıştırırken uygun bayrağı kullanmazsanız Chrome asla normal şekilde çalışmaz .


6

Geç partiye değilim, ama XQuartz yolda gitmek istemiyorum Mac kullanıcıları için, burada Masaüstü Ortamı (xfce) kullanarak, bir Fedora Resmi inşa eden çalışma örneğidir Xvfbve VNC. Çok basit ve çalışıyor:

Mac bilgisayarlarda, ona bağlanan Ekran Paylaşımı (varsayılan) uygulamasını kullanarak erişebilirsiniz localhost:5901.

Dockerfile:

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

İsterseniz / ihtiyacınız varsa , bağlantılı benioku derleme ve çalıştırma komutları için kontrol edin .


5

Jürgen Weigert'in cevabına dayanarak, bazı iyileştirmelerim var:

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

Tek fark, $ XAUTH dosyasını yerleştirmek ve $ XAUTH dosyası yerine $ XAUTH dosyası yerleştirmek için kullanılan bir $ XAUTH_DIR dizini oluşturmasıdır.

Bu yöntemin yararı / tmp içinde $ XAUTH_DIR adında boş bir klasör oluşturmak ve modunu 777 olarak değiştirmek için /etc/rc.local içinde bir komut yazabilmenizdir.

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

Sistem yeniden başlatıldığında, kullanıcı oturum açmadan önce, kabın yeniden başlatma ilkesi "her zaman" ise docker $ XAUTH_DIR dizinini otomatik olarak bağlar. Kullanıcı oturum açtıktan sonra ~ / .profile dosyasına $ XAUTH dosyası oluşturacak bir komut yazabilirsiniz, daha sonra kap otomatik olarak bu $ XAUTH dosyasını kullanır.

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

Daha sonra, sistem her başlatıldığında ve kullanıcı oturum açtığında kap otomatik olarak Xauthority dosyasını alacaktır.


4

Diğer çözümler işe yaramalı, ama işte bir çözüm docker-compose.

Bu hatayı düzeltmek için docker'a $ DISPLAY ve .X11-unix iletmeniz ve docker'ı başlatan kullanıcıya xhost'a erişim izni vermeniz gerekir.

docker-compose.ymlDosya içinde :

version: '2'
services:
    node:
        build: .
        container_name: node
        environment:
            - DISPLAY
        volumes:
            - /tmp/.X11-unix:/tmp/.X11-unix

Terminalde veya komut dosyasında:

  • xhost +si:localuser:$USER
  • xhost +local:docker
  • export DISPLAY=$DISPLAY
  • docker-compose up


3

Docker kullanıcısının (burada: kök) X11 ekranına erişmesine izin verebilirsiniz:

XSOCK=/tmp/.X11-unix
xhost +SI:localuser:root 
docker run -t -i --rm -v $XSOCK:$XSOCK:ro -e DISPLAY=unix$(DISPLAY) image 
xhost -SI:localuser:root

2

OSX (10.13.6, yüksek sierra)

@Nick benzer , ancak çözümü benim için işe yaramadı.

Önce brew install socatsocat'ı yaparak XQuartz'ı kurun ( https://www.xquartz.org/ )

Ardından , yorumlar bölümünde bu adımları ( http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/ ) takip edin :

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

Ayrıca debian docker konteynerinden de CLion'u başlatabiliyordum.


1

BRIDGE ağı ile liman işçisi. ekran yöneticisi lightdm ile Ubuntu 16.04 için:

cd /etc/lightdm/lightdm.conf.d
sudo nano user.conf

[Seat:*]
xserver-allow-tcp=true
xserver-command=X -listen tcp

daha fazla özel izin kullanabilirsiniz

xhost +

docker run --volume="$HOME/.Xauthority:/root/.Xauthority:rw" --env="DISPLAY=$HOST_IP_IN_BRIDGE_NETWORK:0" --net=bridge $container_name

1

Görüntüyü zaten oluşturmuş olmanız durumunda başka bir cevap:

  1. sudo olmadan docker'ı çağır ( Docker nasıl düzeltilir: İzin verilmedi sorunu var )

  2. ana bilgisayar ve kapsayıcı paylaşımı arasında aynı USER & home & passwd dosyasını paylaşın (ipuçları: kullanıcı adı yerine kullanıcı kimliğini kullanın)

  3. sürücüye bağımlı kütüphanelerin iyi çalışması için dev klasörü

  4. artı X11 ileri.

    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

sorabilirsiniz, bu kadar çok şey aynı ise liman işçisi kullanmak için ne anlamı var? düşünebileceğim bir sebep, paket bağımlılığı cehenneminin üstesinden gelmektir ( https://en.wikipedia.org/wiki/Dependency_hell ).

Yani bu tür kullanımların geliştirici için daha uygun olduğunu düşünüyorum.


Benim için işe yarayacak tek kişi bu. Benim amacım için, bunu en aza indirebildim: docker run --network = host --volume = echo ~: / home / $ {USER} id -u ${USER}--user = --env = "DISPLAY" --volume = "/ etc / passwd: / etc / passwd: ro "-it REPO: TAG / bin / bash
user1145922

1

Ben kullanarak bir USB kameradan bir video akışını çalıştırmak için yönetilen opencviçinde dockeraşağıdaki adımları izleyerek:

  1. Docker'ın X sunucusuna erişmesine izin verin

    xhost +local:docker
    
  2. X11 Unix soketini ve X kimlik doğrulama dosyasını oluşturun

    XSOCK=/tmp/.X11-unix
    XAUTH=/tmp/.docker.xauth
    
  3. Uygun izinler ekleyin

    xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
    
  4. Qt oluşturma hızını "doğal" olarak ayarlayın, böylece X11 oluşturma motorunu atlamaz

    export QT_GRAPHICSSYSTEM=native
    
  5. Qt'ye MIT-SHM (paylaşılan bellek) kullanmamasını söyleyin - bu şekilde güvenlik açısından da daha güvenli olmalıdır

    export QT_X11_NO_MITSHM=1
    
  6. Docker run komutunu güncelleme

    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
    

Not: Projeyi bitirdiğinizde, erişim denetimlerini varsayılan değerlerine döndürün - xhost -local:docker

Ek bilgi: Docker ile GUI'leri kullanma

Kredi: Tensorflow, OpenCV ve Docker kullanarak gerçek zamanlı ve video işleme nesnesi algılama


"X11 Unix soketi ve X kimlik doğrulama dosyası oluşturun" herhangi bir dosya oluşturmaz, sadece değişkenleri tanımlar?
MrR
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.