我正在运行Docker容器,主要是作为R
语言的独立开发环境。 (这里R
的用法与帖子的其余部分正交,即你可以假设任何可以在repl
- 会话中运行的通用程序。)很多时候这将涉及做东西比如绘图,制作图形等;我需要看看
这些。因此,我更愿意选择显示我在容器中创建的图形。到目前为止,我是这样做的。首先,我创建一个Dockerfile
。省略最重要的步骤是:
# Set root passwd
RUN echo "root:test" | chpasswd
# Add user so that container does not run as root
RUN useradd -m docker
RUN echo "docker:test" | chpasswd
RUN usermod -s /bin/bash docker
RUN usermod -aG sudo docker
ENV HOME /home/docker
RUN mkdir /var/run/sshd
RUN mkdir -p /var/log/supervisor
# copy servisord.conf which lists the processes to be spawned once this
# container is started (currently only one: sshd)
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
EXPOSE 22
CMD ["/usr/bin/supervisord"]
我构建图像,然后使用:
启动容器docker run -d -p 127.0.0.1:5000:22 -h ubuntu-r -v /home/chb/files/Data:/home/docker/Data -P --name="rdev" ubuntu-r
然后可以ssh到我的容器中:
ssh -X docker@localhost -p 5000.
这会给我我想要的东西。但我想知道是否有另一种更加资源友好的方式从容器中获取图形/ GUI输出? (我希望,如果可能的话,解决方案不会涉及vnc
。)
答案 0 :(得分:78)
有一个很好的,简单的方法来获取图形输出
Docker容器,而不必在其中运行sshd
守护进程
容器。 Docker可以在运行单个时提供裸机性能
在这种情况下应该是R
的过程。运行sshd守护程序
将尽可能边际地引入额外的开销。这不是
通过将sshd守护程序作为子进程运行来改进
主管守护进程。当人们充分利用时,两者都可以省去
绑定坐骑。在构建容器所在的图像之后
要运行,我们启动一个交互式容器并绑定mount
/tmp/.X11-unix
文件夹。我将陈述完整的命令和
详细解释它的作用:
docker run -i -t --rm \
-i
设置了一个互动会话; -t
分配一个伪tty; --rm
使这个容器短暂-e DISPLAY = $ DISPLAY \
:0
)-u docker \
-u
指定进程应由用户(此处为docker
)运行,而不是由root运行。这一步很重要(v.i。)!-v /tmp/.X11-unix:/tmp/.X11-unix:ro \
-v
bind将驻留在本地计算机上X11
的{{1}}套接字安装到容器中的/tmp/.X11-unix
,/tmp/.X11-unix
使套接字只读。< / LI>
- name =“rdev”ubuntu-r R
:ro
指定容器的名称(此处为--name=""
);要从中运行容器的图像(此处为rdev
);要在容器中运行的进程(此处为ubuntu-r
)。 (只有在没有为图像设置默认R
或CMD
时,才需要指定流程的最后一步。)发出此命令后,你应该看看漂亮的ENTRYPOINT
开始输出。如果您尝试R
来查看图形
输出已经工作你会注意到它不是。那是因为
demo(graphics)
扩展名阻止您访问套接字。您
现在可以在您的本地计算机上键入Xsecurity
并尝试xhost +
你的容器了。你现在应该有图形输出。这种方法
但是,强烈建议您禁止访问xsocket
您当前连接的任何远程主机。只要你是这样的人
与单用户系统交互这可能在某种程度上是合理的,但是
一旦涉及多个用户,这将是绝对的
不安全!因此,您应该使用危险性较小的方法。一个好方法是
使用服务器解释
demo(graphics)
可用于指定单个本地用户(请参阅xhost +si:localuser:username
)。这意味着
man xhost
应该是运行username
服务器的用户的名称
您的本地计算机和运行docker容器的计算机。这也是
为什么在运行时指定用户很重要的原因
容器。最后但同样重要的是,总有更复杂的解决方案
使用X11
和xauth
文件授予对.Xauthority
套接字的访问权限
(见X11
)。然而,这也将涉及更多的知识
man xauth
如何运作。
可以在流程数量中看到这种积极影响 需要运行才能实现所需。
(1)在容器中运行X
和supervisor
:
sshd
通过UID PID PPID C STIME TTY TIME CMD
root 4564 718 1 18:16 ? 00:00:00 /usr/bin/python /usr/bin/supervisord
root 4576 4564 0 18:16 ? 00:00:00 /usr/sbin/sshd
登录并运行ssh
:
R
(2)使用bind mount方法:
UID PID PPID C STIME TTY TIME CMD
root 4564 718 0 18:16 ? 00:00:00 /usr/bin/python /usr/bin/supervisord
root 4576 4564 0 18:16 ? 00:00:00 /usr/sbin/sshd
root 4674 4576 0 18:17 ? 00:00:00 sshd: docker [priv]
chb 4725 4674 0 18:18 ? 00:00:00 sshd: docker@pts/0
chb 4728 4725 1 18:18 pts/0 00:00:00 -bash
答案 1 :(得分:4)
这显然是我迄今为止找到的最佳解决方案:
https://stackoverflow.com/a/25280523/1353930(所有归功于JürgenWeigert)
优点:
xhost +
)