lor*_*age 50 user-interface docker
我正在运行一个Docker容器,主要是作为该R语言的独立开发环境.(R这里的用法与帖子的其余部分正交,即你可以假设任何可以在repl-session中运行的通用程序.)很多时候这将涉及做绘图,制作图形等内容; 我需要看看这些.因此,我更愿意选择显示我在容器中创建的图形.到目前为止,我是这样做的.首先我创建一个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"]
Run Code Online (Sandbox Code Playgroud)
我构建映像,然后使用以下命令启动容器:
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
Run Code Online (Sandbox Code Playgroud)
然后可以ssh到我的容器中:
ssh -X docker@localhost -p 5000.
Run Code Online (Sandbox Code Playgroud)
这会给我我想要的东西.但我想知道是否有另一种更加资源友好的方式从容器中获取图形/ GUI输出?(我希望,如果可能的话,解决方案不会涉及vnc.)
lor*_*age 80
有一种很好的,简单的方法可以从Docker容器中获取图形输出,而无需sshd在容器内部运行守护程序.Docker可以在运行单个进程时提供裸机性能,在这种情况下应该是这样R.运行sshd守护进程虽然可能是边缘的,但会引入额外的开销.通过将sshd守护程序作为管理程序守护程序的子进程运行,这不会更好.当人们充分利用绑定装置时,两者都可以省去.在构建了应该运行容器的映像之后,我们启动一个交互式容器并将/tmp/.X11-unix文件夹绑定
到其中.我将陈述完整的命令并详细解释它的作用:
docker run -i -t --rm \
-i建立一个互动会议; -t分配伪tty; --rm使这个容器短暂-e DISPLAY = $ DISPLAY \
:0)-u码头
-u指定进程应由用户(此处docker)而不是root 用户运行.这一步很重要(vi)!-v /tmp/.X11-unix:/tmp/.X11-unix:ro \
-vbind将X11驻留在/tmp/.X11-unix本地计算机上的套接字挂载到/tmp/.X11-unix容器中,:ro并使套接字只读.--name ="rdev"ubuntu-r R
--name=""指定容器的名称(这里rdev); 要从(此处ubuntu-r)运行容器的图像; 要在容器中运行的进程(此处R).(只有在未设置默认值CMD或ENTRYPOINT图像时,才需要指定进程的最后一步.)发出此命令后,您应该查看漂亮的R
开始输出.如果您试图demo(graphics)查看图形输出是否已经有效,您会注意到它不是.这是因为Xsecurity扩展阻止您访问套接字.您现在可以xhost +在本地计算机上键入并demo(graphics)再次尝试容器.你现在应该有图形输出.但是,强烈建议不要使用此方法,因为您允许访问xsocket到您当前连接的任何远程主机.只要您只与单用户系统进行交互,这可能是合理的,但只要涉及多个用户,这将是绝对不安全的!因此,您应该使用危险性较小的方法.一个好方法是使用解释的服务器
xhost +si:localuser:username
Run Code Online (Sandbox Code Playgroud)
可用于指定单个本地用户(请参阅参考资料man xhost).这意味着
username应该是在X11本地计算机上运行服务器并运行docker容器的用户的名称.这也是为什么在运行容器时指定用户很重要的原因.最后但并非最不重要的是,总是使用更复杂的解决方案xauth和.Xauthority文件来授予对X11套接字的访问权限(请参阅参考资料man xauth).然而,这也将涉及更多的知识如何X工作.
这可以产生的积极影响可以从需要运行的流程数量中看出,以实现所需的目标.
(1)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
Run Code Online (Sandbox Code Playgroud)
登录ssh并运行时R:
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
Run Code Online (Sandbox Code Playgroud)
(2)使用bind mount方法:
UID PID PPID C STIME TTY TIME CMD
chb 4356 718 0 18:12 pts/4 00:00:00 /usr/local/lib/R/bin/exec/R --no-save --no-restore
Run Code Online (Sandbox Code Playgroud)