Bagaimana Anda bisa menjalankan aplikasi GUI dalam wadah Docker ?
Apakah ada gambar yang mengatur vncserver
atau sesuatu sehingga Anda dapat - misalnya - menambahkan kotak pasir speedbump tambahan di sekitar katakanlah Firefox?
Bagaimana Anda bisa menjalankan aplikasi GUI dalam wadah Docker ?
Apakah ada gambar yang mengatur vncserver
atau sesuatu sehingga Anda dapat - misalnya - menambahkan kotak pasir speedbump tambahan di sekitar katakanlah Firefox?
Jawaban:
Anda cukup menginstal vncserver bersama dengan Firefox :)
Saya mendorong gambar, vnc / firefox, di sini: docker pull creack/firefox-vnc
Gambar telah dibuat dengan Dockerfile ini:
# 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'
Ini akan membuat wadah Docker yang menjalankan VNC dengan kata sandi 1234
:
Untuk Docker versi 18 atau lebih baru:
docker run -p 5900:5900 -e HOME=/ creack/firefox-vnc x11vnc -forever -usepw -create
Untuk Docker versi 1.3 atau lebih baru:
docker run -p 5900 -e HOME=/ creack/firefox-vnc x11vnc -forever -usepw -create
Untuk Docker sebelum versi 1.3:
docker run -p 5900 creack/firefox-vnc x11vnc -forever -usepw -create
docker inspect <container id>
atau hanya docker ps
, kemudian Anda terhubung ke ip host Anda dengan port yang baru saja Anda temukan.
Xauthority menjadi masalah dengan sistem yang lebih baru. Saya bisa membuang perlindungan dengan xhost + sebelum menjalankan wadah buruh pelabuhan saya, atau saya bisa mengirimkan file Xauthority yang dipersiapkan dengan baik. File Xauthority yang tipikal adalah spesifik hostname. Dengan buruh pelabuhan, setiap wadah dapat memiliki nama host yang berbeda (ditetapkan dengan buruh pelabuhan run-h), tetapi bahkan mengatur nama host wadah yang identik dengan sistem host tidak membantu dalam kasus saya. xeyes (saya suka contoh ini) hanya akan mengabaikan cookie ajaib dan tidak memberikan kredensial ke server. Karenanya kami mendapatkan pesan kesalahan 'Tidak ada protokol yang ditentukan Tidak dapat membuka tampilan'
File Xauthority dapat ditulis sedemikian rupa sehingga nama host tidak menjadi masalah. Kita perlu mengatur Keluarga Otentikasi ke 'FamilyWild'. Saya tidak yakin, jika xauth memiliki baris perintah yang tepat untuk ini, jadi di sini adalah contoh yang menggabungkan xauth dan sed untuk melakukan itu. Kita perlu mengubah 16 bit pertama dari output nlist. Nilai FamilyWild adalah 65535 atau 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
dapat disingkat menjadi-v $XSOCK -v $XAUTH
:0
dengan $DISPLAY
. Itu berarti xauth nlist $DISPLAY | ...
dan docker run -ti -e DISPLAY=$DISPLAY ...
. Biasanya X DISPLAY adalah :0
, tetapi tidak selalu (dan terutama tidak jika Anda terhubung melalui ssh -X).
/tmp/.docker.xauth
file dengan 600
izin. Ini menghasilkan xauth di dalam wadah buruh pelabuhan tidak bisa membaca file. Anda dapat memverifikasi dengan menjalankan xauth list
dalam wadah buruh pelabuhan. Saya telah menambahkan chmod 755 $XAUTH
setelah xauth nlist :0 | ...
perintah untuk menyelesaikan ini.
Saya baru saja menemukan entri blog ini dan ingin membagikannya di sini dengan Anda karena saya pikir itu adalah cara terbaik untuk melakukannya dan itu sangat mudah.
http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/
PROS:
+ tidak ada server x barang dalam wadah buruh pelabuhan
+ tidak ada vnc klien / server diperlukan
+ tidak ssh dengan penerusan x
+ wadah buruh pelabuhan yang jauh lebih kecil
CONS:
- menggunakan x pada host (tidak dimaksudkan untuk safe-sandboxing)
kalau-kalau link akan gagal suatu hari nanti saya telah meletakkan bagian terpenting di sini:
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
membangun gambar:
docker build -t firefox .
dan perintah run:
docker run -ti --rm \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
firefox
tentu saja Anda juga dapat melakukan ini dengan menjalankan perintah sh -c "echo script-here"
PETUNJUK: untuk audio lihatlah di: https://stackoverflow.com/a/28985715/2835523
apt-get -y install sudo
untuk membuat /etc/sudoers.d
folder.
$ xhost +
Dengan volume data buruh pelabuhan itu sangat mudah untuk mengekspos soket domain unix xorg di dalam wadah.
Misalnya, dengan Dockerfile seperti ini:
FROM debian
RUN apt-get update
RUN apt-get install -qqy x11-apps
ENV DISPLAY :0
CMD xeyes
Anda dapat melakukan hal berikut:
$ docker build -t xeyes - < Dockerfile
$ XSOCK=/tmp/.X11-unix/X0
$ docker run -v $XSOCK:$XSOCK xeyes
Ini tentu saja pada dasarnya sama dengan penerusan X. Ini memberi kontainer akses penuh ke xserver pada host, jadi itu hanya disarankan jika Anda mempercayai apa yang ada di dalamnya.
Catatan: Jika Anda khawatir tentang keamanan, solusi yang lebih baik adalah membatasi aplikasi dengan kontrol akses wajib atau berbasis peran . Docker mencapai isolasi yang cukup bagus, tetapi dirancang dengan tujuan berbeda. Gunakan AppArmor , SELinux , atau GrSecurity , yang dirancang untuk mengatasi masalah Anda.
xhost +
host.
xhost +local
diperlukan @Tully . Akan lebih baik untuk membuat ~/.Xauthority
file tersedia dalam wadah, sehingga dapat mengotentikasi sendiri.
Can't open display: :0
. Ada ide?
xhost +si:localuser:$USER
hanya mengotorisasi pengguna yang memulai wadah.
Anda juga dapat menggunakan subuser: https://github.com/timthelion/subuser
Ini memungkinkan Anda untuk mengemas banyak aplikasi gui di buruh pelabuhan. Firefox dan emacs telah diuji sejauh ini. Dengan firefox, webGL tidak berfungsi. Chromium tidak berfungsi sama sekali.
EDIT: Suara bekerja!
EDIT2: Pada saat saya pertama kali memposting ini, subuser telah mengalami kemajuan pesat. Saya sekarang memiliki situs web subuser.org , dan model keamanan baru untuk menghubungkan ke X11 melalui XPRA bridging .
Jürgen Weigert memiliki jawaban terbaik yang bekerja untuk saya di Ubuntu, namun pada OSX, docker berjalan di dalam VirtualBox dan jadi solusinya tidak bekerja tanpa kerja lebih banyak.
Saya sudah membuatnya bekerja dengan bahan tambahan ini:
Saya menghargai komentar pengguna untuk meningkatkan jawaban ini untuk OSX, saya tidak yakin apakah penerusan soket untuk X aman, tetapi tujuan penggunaan saya adalah untuk menjalankan wadah buruh pelabuhan secara lokal saja.
Selain itu, skripnya agak rapuh karena tidak mudah untuk mendapatkan alamat IP mesin karena itu ada di nirkabel lokal kami sehingga selalu ada beberapa IP acak.
Skrip BASH yang saya gunakan untuk meluncurkan wadah:
#!/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
Saya bisa mendapatkan xeyes dan matplotlib bekerja dengan pendekatan ini.
Ini sedikit lebih mudah pada Windows 7+ dengan MobaXterm:
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.
dan Error: cannot open display: VAIO:0.0
. Apakah Anda menemukan sesuatu seperti ini?
Berbagi tampilan host: 0, sebagaimana dinyatakan dalam beberapa jawaban lain, memiliki dua kelemahan:
xev
atau xinput
dimungkinkan, dan remote control aplikasi host dengan xdotool
.--ipc=host
).Di bawah ini contoh skrip untuk menjalankan gambar buruh pelabuhan di Xephyr yang membahas masalah ini.
--cap-drop ALL --security-opt no-new-privileges
. Juga pengguna kontainer tidak root.Script mengharapkan beberapa argumen, pertama manajer jendela host dijalankan di Xephyr, kedua gambar buruh pelabuhan, opsional ketiga perintah gambar yang akan dieksekusi. Untuk menjalankan lingkungan desktop di buruh pelabuhan, gunakan ":" alih-alih manajer jendela host.
Jendela Penutupan Xephyr mengakhiri aplikasi kontainer buruh pelabuhan. Mengakhiri aplikasi yang merapat menutup jendela Xephyr.
Contoh:
xephyrdocker "openbox --sm-disable" x11docker/lxde pcmanfm
xephyrdocker : x11docker/lxde
xephyrdocker xfwm4 --device /dev/snd jess/nes /games/zelda.rom
skrip 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
Skrip ini dikelola di wiki x11docker . Skrip yang lebih canggih adalah x11docker yang juga mendukung fitur seperti akselerasi GPU, webcam, dan berbagi printer, dan sebagainya.
Berikut adalah solusi ringan yang menghindari keharusan memasang X
server, vnc
server atau sshd
daemon apa pun pada wadah. Apa yang diperolehnya dalam kesederhanaan itu hilang dalam keamanan dan isolasi.
Diasumsikan bahwa Anda terhubung ke mesin host menggunakan ssh
dengan X11
penerusan.
Dalam sshd
konfigurasi host, tambahkan baris
X11UseLocalhost no
Sehingga port server X yang diteruskan pada host dibuka pada semua antarmuka (bukan hanya lo
) dan khususnya pada antarmuka virtual Docker docker0
,.
Kontainer, ketika dijalankan, membutuhkan akses ke .Xauthority
file sehingga dapat terhubung ke server. Untuk melakukan itu, kita mendefinisikan volume read-only yang menunjuk ke direktori home pada host (mungkin bukan ide yang bijak!) Dan juga mengatur XAUTHORITY
variabel sesuai.
docker run -v $HOME:/hosthome:ro -e XAUTHORITY=/hosthome/.Xauthority
Itu tidak cukup, kita juga harus melewati variabel DISPLAY dari host, tetapi mengganti nama host dengan ip:
-e DISPLAY=$(echo $DISPLAY | sed "s/^.*:/$(hostname -i):/")
Kita dapat mendefinisikan alias:
alias dockerX11run='docker run -v $HOME:/hosthome:ro -e XAUTHORITY=/hosthome/.Xauthority -e DISPLAY=$(echo $DISPLAY | sed "s/^.*:/$(hostname -i):/")'
Dan mengujinya seperti ini:
dockerX11run centos xeyes
.Xauthority
file itu sendiri: -v $HOME/.Xauthority:/root/.Xauthority -e XAUTHORITY=/root/.Xauthority
.
X11UseLocalhost
, Anda juga dapat menggunakan opsi tambahan --net=host
untuk docker run
perintah (ditemukan di sini ).
--net=host
adalah ide yang buruk karena sekarang jika Anda membuka port dalam wadah itu akan terbuka di tuan rumah juga ...
Sementara jawaban oleh Jürgen Weigert pada dasarnya mencakup solusi ini, pada awalnya tidak jelas bagi saya apa yang dijelaskan di sana. Jadi saya akan menambahkan pendapat saya, kalau-kalau ada orang lain yang perlu klarifikasi.
Off pertama, dokumentasi yang relevan adalah manualnya keamanan X .
Banyak sumber online menyarankan hanya memasang soket unix X11 dan ~/.Xauthority
file ke wadah. Solusi ini sering berhasil, tanpa benar-benar memahami mengapa, misalnya pengguna wadah berakhir dengan UID yang sama dengan pengguna, sehingga tidak perlu otorisasi kunci ajaib.
Pertama, file Xauthority memiliki mode 0600, sehingga pengguna kontainer tidak akan dapat membacanya kecuali ia memiliki UID yang sama.
Bahkan jika Anda menyalin file ke dalam wadah, dan mengubah kepemilikan, masih ada masalah lain. Jika Anda menjalankan xauth list
host dan container, dengan Xauthority
file yang sama , Anda akan melihat entri yang berbeda terdaftar. Ini karena xauth
memfilter entri tergantung pada tempat dijalankannya.
Klien X dalam wadah (yaitu aplikasi GUI) akan berperilaku sama dengan xauth
. Dengan kata lain, itu tidak melihat cookie ajaib untuk sesi X yang berjalan di desktop pengguna. Alih-alih, ia melihat entri untuk semua sesi "remote" X yang telah Anda buka sebelumnya (dijelaskan di bawah).
Jadi, apa yang perlu Anda lakukan adalah menambahkan entri baru dengan nama host wadah dan tombol hex yang sama dengan cookie host (yaitu sesi X yang berjalan di desktop Anda), misalnya:
containerhostname/unix:0 MIT-MAGIC-COOKIE-1 <shared hex key>
Tangkapannya adalah bahwa cookie harus ditambahkan dengan xauth add
di dalam wadah:
touch ~/.Xauthority
xauth add containerhostname/unix:0 . <shared hex key>
Kalau tidak, xauth
tandai dengan cara yang hanya terlihat di luar wadah.
Format untuk perintah ini adalah:
xauth add hostname/$DISPLAY protocol hexkey
Dimana .
mewakili MIT-MAGIC-COOKIE-1
protokol.
Catatan: Tidak perlu menyalin atau mengikat-mount .Xauthority
ke wadah. Cukup buat file kosong, seperti yang ditunjukkan, dan tambahkan cookie.
Jawaban Jürgen Weigert menyiasatinya dengan menggunakan FamilyWild
jenis koneksi untuk membuat file otoritas baru pada host dan menyalinnya ke dalam wadah. Perhatikan bahwa ini pertama-tama mengekstrak kunci hex untuk sesi X saat ~/.Xauthority
menggunakan xauth nlist
.
Jadi langkah-langkah penting adalah:
FamilyWild
tipe koneksi).Saya akui bahwa saya tidak begitu mengerti bagaimana cara FamilyWild
kerjanya, atau bagaimana xauth
atau klien X memfilter entri dari file Xauthority tergantung di mana mereka dijalankan. Informasi tambahan tentang ini disambut baik.
Jika Anda ingin mendistribusikan aplikasi Docker Anda, Anda akan memerlukan skrip mulai untuk menjalankan wadah yang mendapat kunci hex untuk sesi X pengguna, dan mengimpornya ke dalam wadah dengan salah satu dari dua cara yang dijelaskan sebelumnya.
Ini juga membantu untuk memahami mekanisme proses otorisasi:
$DISPLAY
./tmp/.X11-unix
direktori yang dipasang di wadah.Catatan: Soket Unix X11 masih harus dipasang di wadah, atau wadah tidak akan memiliki rute ke server X. Sebagian besar distribusi menonaktifkan akses TCP ke server X secara default untuk alasan keamanan.
Untuk informasi tambahan, dan untuk lebih memahami bagaimana hubungan X client / server bekerja, juga membantu untuk melihat contoh kasus penerusan SSH X:
$DISPLAY
dalam sesi SSH untuk menunjuk ke server X-nya sendiri.xauth
untuk membuat cookie baru untuk host jarak jauh, dan menambahkannya ke Xauthority
file untuk pengguna lokal dan jarak jauh.Ini tidak ringan tetapi merupakan solusi yang bagus yang memberikan fitur fitur docker dengan virtualisasi desktop penuh. Baik Xfce4 atau IceWM untuk Ubuntu dan CentOS berfungsi, dan noVNC
opsi ini memudahkan akses melalui browser.
https://github.com/ConSol/docker-headless-vnc-container
Ini berjalan noVNC
serta tigerVNC
vncserver. Kemudian ia memanggil startx
Window Manager yang diberikan. Selain itu, libnss_wrapper.so
digunakan untuk meniru manajemen kata sandi untuk pengguna.
xpra
di docker, yang merupakan root-less X. xpra
adalah IMO paling cocok dan lebih efisien daripada VNC.
--device /dev/...
ke buruh pelabuhan dan mengatur --cap
hak istimewa yang diperlukan . Itu mengalahkan tujuan penahanan, tetapi Anda dapat melewati perangkat. Dengan beberapa penyesuaian, saya bisa menjalankan GNOME / KDE di bawah VNC. Saya menjalankan beberapa X di buruh pelabuhan dengan kartu nvidia (tidak ada VNC atau Xpra), sehingga tentu saja bisa dilakukan.
Solusi yang diberikan di http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/ tampaknya merupakan cara mudah untuk memulai aplikasi GUI dari dalam wadah (saya mencoba firefox lebih dari ubuntu 14.04) tetapi saya menemukan bahwa perubahan tambahan kecil diperlukan untuk solusi yang diposting oleh penulis.
Secara khusus, untuk menjalankan wadah, penulis telah menyebutkan:
docker run -ti --rm \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
firefox
Tetapi saya menemukan bahwa (berdasarkan komentar tertentu di situs yang sama) ada dua opsi tambahan
-v $HOME/.Xauthority:$HOME/.Xauthority
dan
-net=host
perlu ditentukan saat menjalankan wadah agar firefox berfungsi dengan baik:
docker run -ti --rm \
-e DISPLAY=$DISPLAY \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v $HOME/.Xauthority:$HOME/.Xauthority \
-net=host \
firefox
Saya telah membuat gambar buruh pelabuhan dengan informasi di halaman itu dan temuan tambahan ini: https://hub.docker.com/r/amanral/ubuntu-firefox/
/tmp/.X11-unix
soket sama sekali. Ini hanya berfungsi dengan pemasangan .Xauthority
dan --net=host
.
/tmp/.X11-unix
sebagai volume tidak lagi berfungsi, karena buruh pelabuhan diam-diam menolak volume mount dari direktori lengket.
--network=host
dilakukan. Ini memberi kontainer Anda akses penuh ke tumpukan jaringan host, yang mungkin tidak diinginkan, tergantung pada apa yang Anda coba lakukan. Jika Anda hanya mengutak-atik menjalankan GUI kemas di desktop Anda, maka itu tidak masalah.
Ada solusi lain oleh lord.garbage untuk menjalankan aplikasi GUI dalam sebuah wadah tanpa menggunakan penerusan VNC, SSH dan X11. Disebutkan di sini juga.
Jika Anda ingin menjalankan aplikasi GUI tanpa kepala, baca di sini . Yang harus Anda lakukan adalah membuat monitor virtual dengan xvfb
atau perangkat lunak serupa lainnya. Ini sangat membantu jika Anda ingin menjalankan tes Selenium misalnya dengan browser.
Sesuatu yang tidak disebutkan di mana pun adalah bahwa beberapa perangkat lunak sebenarnya menggunakan kotak pasir dengan wadah Linux. Jadi misalnya Chrome tidak akan pernah berjalan normal jika Anda tidak menggunakan bendera yang sesuai --privileged
saat menjalankan wadah.
Saya terlambat ke pesta, tetapi untuk pengguna Mac yang tidak ingin menyusuri jalur XQuartz, berikut ini adalah contoh kerja yang membangun Gambar Fedora, dengan Lingkungan Desktop (xfce) menggunakan Xvfb
dan VNC
. Sederhana, dan berfungsi:
Di Mac, Anda bisa mengaksesnya menggunakan aplikasi Screen Sharing (default), yang terhubung ke 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
Periksa readme yang tertaut untuk perintah build dan run jika Anda mau / butuhkan.
Berdasarkan jawaban Jürgen Weigert , saya memiliki beberapa peningkatan:
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
Satu-satunya perbedaan adalah ia menciptakan direktori $ XAUTH_DIR yang digunakan untuk menempatkan file $ XAUTH dan me-mount direktori $ XAUTH_DIR alih-alih file $ XAUTH ke dalam wadah buruh pelabuhan.
Manfaat dari metode ini adalah Anda dapat menulis perintah di /etc/rc.local yaitu membuat folder kosong bernama $ XAUTH_DIR di / tmp dan mengubah modenya ke 777.
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
Ketika sistem dinyalakan kembali, sebelum pengguna masuk, buruh pelabuhan akan memasang direktori $ XAUTH_DIR secara otomatis jika kebijakan restart kontainer "selalu". Setelah pengguna login, Anda dapat menulis perintah di ~ / .profile yaitu untuk membuat file $ XAUTH, maka container akan secara otomatis menggunakan file $ XAUTH ini.
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
Setelah semua, wadah akan secara otomatis mendapatkan file Xauthority setiap kali sistem restart dan login pengguna.
Solusi lain harus berhasil, tetapi di sini ada solusi untuk docker-compose
.
Untuk memperbaiki kesalahan itu, Anda harus meneruskan $ DISPLAY dan .X11-unix ke buruh pelabuhan, serta memberikan pengguna yang mulai mengakses buruh pelabuhan ke xhost.
Dalam docker-compose.yml
file:
version: '2'
services:
node:
build: .
container_name: node
environment:
- DISPLAY
volumes:
- /tmp/.X11-unix:/tmp/.X11-unix
Dalam terminal atau skrip:
xhost +si:localuser:$USER
xhost +local:docker
export DISPLAY=$DISPLAY
docker-compose up
Untuk rendering OpenGL dengan driver Nvidia, gunakan gambar berikut:
https://github.com/thewtex/docker-opengl-nvidia
Untuk implementasi OpenGL lainnya, pastikan gambar memiliki implementasi yang sama dengan host.
Mirip dengan jawaban @Nick , tetapi solusinya tidak bekerja untuk saya.
Pertama instal socat dengan melakukan brew install socat
, dan instal XQuartz ( https://www.xquartz.org/ )
Kemudian ikuti langkah-langkah ini di sini ( http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/ ) di bagian komentar:
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
Saya juga dapat meluncurkan CLion dari wadah buruh pelabuhan debian saya juga.
Docker dengan jaringan BRIDGE. untuk Ubuntu 16.04 dengan display manager lightdm:
cd /etc/lightdm/lightdm.conf.d
sudo nano user.conf
[Seat:*]
xserver-allow-tcp=true
xserver-command=X -listen tcp
Anda dapat menggunakan lebih banyak izin pribadi
xhost +
docker run --volume="$HOME/.Xauthority:/root/.Xauthority:rw" --env="DISPLAY=$HOST_IP_IN_BRIDGE_NETWORK:0" --net=bridge $container_name
Namun jawaban lain jika Anda sudah membangun gambar:
aktifkan buruh pelabuhan tanpa sudo ( Cara memperbaiki buruh pelabuhan: Mendapat izin ditolak masalah )
bagikan PENGGUNA & home & passwd yang sama antara host dan berbagi kontainer (kiat: gunakan id pengguna, bukan nama pengguna)
folder dev untuk lib bergantung pada driver agar berfungsi dengan baik
ditambah X11 maju.
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
Anda mungkin bertanya, apa gunanya menggunakan buruh pelabuhan jika begitu banyak hal yang sama? baik, salah satu alasan yang dapat saya pikirkan adalah untuk mengatasi paket neraka neraka ( https://en.wikipedia.org/wiki/Dependency_hell ).
Jadi jenis penggunaan ini lebih cocok untuk pengembang saya pikir.
echo ~
: / home / $ {USER} id -u ${USER}
--user = --env = "DISPLAY" --volume = "/ etc / passwd: / etc / passwd: ro "-it REPO: TAG / bin / bash
Saya berhasil menjalankan streaming video dari kamera USB menggunakan opencv
di docker
dengan mengikuti langkah berikut:
Biarkan buruh pelabuhan mengakses server X
xhost +local:docker
Buat soket Unix X11 dan file otentikasi X.
XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth
Tambahkan izin yang tepat
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
Atur kecepatan rendering Qt ke "asli", sehingga tidak mem-bypass mesin rendering X11
export QT_GRAPHICSSYSTEM=native
Katakan Qt untuk tidak menggunakan MIT-SHM (memori bersama) - dengan cara itu seharusnya juga lebih aman dari segi keamanan
export QT_X11_NO_MITSHM=1
Perbarui perintah jalankan buruh pelabuhan
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
Catatan: Saat Anda menyelesaikan proyek, kembalikan kontrol akses pada nilai standarnya - xhost -local:docker
Lebih detail: Menggunakan GUI dengan Docker
Kredit: Deteksi objek pemrosesan video dan real-time menggunakan Tensorflow, OpenCV dan Docker