Docker运行GUI原理

Docker目前大多应用在服务器领域,那么在Docker中可以运行GUI程序吗?怀着好奇心google了一番,还真有人写了一篇文章 running-gui-applications-inside-docker-containers,文章从原理剖析到实际操作内容非常详尽。

引用自running-gui-applications-inside-docker-containers

从上图中我们可以清楚的了解到,要在docker中运行GUI程序,关键是让Docker知道X Server(大多数Linux桌面环境的基础)。文章的核心就在以下参数:

  • share the Host’s DISPLAY environment variable to the Container
  • --env="DISPLAY"
  • run container with host network driver with
  • --net=host

$ docker run --net=host --env="DISPLAY"

引用自running-gui-applications-inside-docker-containers

上述参数的含义就是将Linux宿主机的X Server共享给Docker容器,还有一种方式就是映射宿主机X Server.sock文件到容器中去。

那么问题来了,在Windows或Mac这些没有X11的Host机器上怎么办呢?由于本人一直使用的Docker for Windows(没钱:)),所以Mac环境暂不关心。

Docker for Windows运行GUI程序

照例google到了一篇文章Run GUI app in linux docker container on windows host,内容同样非常详尽,本文大体也是按照这篇文章的指引。

安装VcXsrv

VcXsrv Windows X Server是Windows上的X11程序,另外还可选择Xming,但Xming最后一次更新是在2016年,代码相对较老,所以还是选择VcXsrv吧。

VcXsrv程序下载安装步骤可以参考Run GUI app in linux docker container on windows host

构建测试容器

Run GUI app in linux docker container on windows host一样也是选择启动一个firefox来做实验,不同的是我对Dockerfile和docker run命令做了一些变更。

Create Dockerfile

FROM ubuntu:18.04
# 修改源地址
RUN mv /etc/apt/sources.list /etc/apt/sources_backup.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic universe " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates universe " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic multiverse " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates multiverse " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-security universe " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-security multiverse " >> /etc/apt/sources.list && \
echo "deb http://archive.canonical.com/ubuntu bionic partner " >> /etc/apt/sources.list && \
# 安装firefox
apt-get update && apt-get install -y firefox
CMD /usr/bin/firefox

相较原文有如下变动:

  1. ubuntu的版本也升级到了18.04
  2. apt源替换成了中科大的镜像地址方便快速构建

Docker build

$ docker build -t firefox .

和原文一致,构建容器。

Docker run

$ docker run -ti --rm -e DISPLAY=host.docker.internal:0.0 firefox

相较原文有如下变动:

  1. 删除了set-variable -name DISPLAY -value YOUR-IP:0.0命令
  2. 设置容器的DISPLAY参数为host.docker.internal而不是宿主机的具体ip

原文的set-variable作用是将宿主机的ip作为临时环境变量,在docker run的时候直接引用该环境变量赋值给容器的DISPLAY,可有可无,并且set-variable只能在PowerShell环境生效,因此直接删除。

再来看-e DISPLAY=host.docker.internal:0.0,从18.03版本开始,Docker推荐容器使用host.docker.internal来访问宿主机上的服务,容器的DNS会自动解析到宿主机的内部IP上,参考Docker for Windows的官方文档:I WANT TO CONNECT FROM A CONTAINER TO A SERVICE ON THE HOST

测试效果验证

winpty 是因为我用的Git for Windows Bash

访问下百度:



怎么有乱码,别急,这个是因为Docker build时未指定ubuntu的locales,ubuntu的镜像默认不支持中文导致的,参考官方文档:ubuntu locales 修改我们的Dockerfile:

FROM ubuntu:18.04
# 修改源地址
RUN mv /etc/apt/sources.list /etc/apt/sources_backup.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic universe " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates universe " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic multiverse " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-updates multiverse " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-security universe " >> /etc/apt/sources.list && \
echo "deb http://mirrors.ustc.edu.cn/ubuntu/ bionic-security multiverse " >> /etc/apt/sources.list && \
echo "deb http://archive.canonical.com/ubuntu bionic partner " >> /etc/apt/sources.list && \
# 更新并安装国际化语言包以及中文字体
apt-get update && \
apt-get install -y locales && \
locale-gen zh_CN && \
locale-gen zh_CN.utf8 && \
apt-get install -y ttf-wqy-microhei ttf-wqy-zenhei xfonts-wqy
# 设置系统语言环境为中文UTF-8
ENV LANG zh_CN.UTF-8
ENV LANGUAGE zh_CN.UTF-8
ENV LC_ALL zh_CN.UTF-8
# 安装firefox
RUN apt-get install -y firefox
CMD /usr/bin/firefox

重新run效果如下:

注意:必须安装中文字体,仅仅设置语言环境还是会导致乱码的。

其他方式

网上还有几种方式,我只看了文章的理论,感觉可行,大家有空可以去亲自尝试一番:

在Docker for Windows中运行GUI程序的更多相关文章

  1. 在OSX和Windows版本Docker上运行GUI程序

    看到很多人在Docker问题区讨论:如何在OS X和Windows的Docker上运行GUI程序, 随手记录几个参考资料: https://github.com/docker/docker/issue ...

  2. 在 Docker 容器中运行应用程序

    案例说明 运行 3 个容器,实现对网站的监控. 三个容器的说明: 容器 web: 创建自 nginx 映像,使用 80 端口,运行于后台,实现 web 服务. 容器 mailer: 该容器中运行一个 ...

  3. 如何在windows中编写R程序包(转载)

    网上有不少R包的编译过程介绍,挑选了一篇比较详细的,做了稍许修改后转载至此,与大家分享 如何在windows中编写R程序包 created by helixcn modified by binaryf ...

  4. 如何实现在Windows上运行Linux程序,附示例代码

    微软在去年发布了Bash On Windows, 这项技术允许在Windows上运行Linux程序, 我相信已经有很多文章解释过Bash On Windows的原理, 而今天的这篇文章将会讲解如何自己 ...

  5. 【爬坑】在 IDEA 中运行 Hadoop 程序 报 winutils.exe 不存在错误解决方案

    0. 问题说明 环境为 Windows 10 在 IDEA 中运行 Hadoop 程序报   winutils.exe 不存在  错误 1. 解决方案 [1.1 解压] 解压 hadoop-2.7.3 ...

  6. 在Windows中运行Linux bash命令的几种方法

    如果你正在课程中正在学习 shell 脚本,那么需要使用 Linux 命令来练习命令和脚本. 你的学校实验室可能安装了 Linux,但是你自己没有安装了 Linux 的笔记本电脑,而是像其他人一样的 ...

  7. # 如何在Windows下运行Linux程序

    如何在Windows下运行Linux程序 一.搭建 Linux 环境 1.1 安装 VMware Workstation https://www.aliyundrive.com/s/TvuMyFdTs ...

  8. 在dos中运行java程序,若出现Exception in thread “main" java.lang.NoClassDefFoundError

    在dos中运行java程序,若出现Exception in thread “main" java.lang.NoClassDefFoundError,可以检查一下几项: 环境变量配置: 注意 ...

  9. 解决由于一个软件限制策略的阻止,windows无法运行此程序cmd.reg

    解决由于一个软件限制策略的阻止,windows无法运行此程序cmd.reg Windows Registry Editor Version 5.00 [-HKEY_LOCAL_MACHINE\SOFT ...

随机推荐

  1. 渐进式web应用开发---promise式数据库(五)

    在前面的一篇文章中,我们已经实现了使用indexedDB实现ajax本地数据存储的功能,详情,请看这篇文章.现在我们需要把上面的一篇文章中的代码使用promise结构来重构下.我们为什么需要使用pro ...

  2. c语言进阶8-数据结构

    一.  数据结构的起源: 1.        为什么要学习数据结构 阿基米德说过:“给我一个支点,我就能翘起地球”.那么给我一个程序,我就能用好程序,给我一个结构,我就能把内容填充完成.打个比方,一个 ...

  3. 将个人网站主页设置为Tomcat默认打开页面

    步骤: 1.打开server.xml,在</Host>的上一行添加内容格式如下 <Context path="" reloadable="true&qu ...

  4. Java EE.JSP.动作组件

    常见的JSP动作组件有以下几种: 1)<jsp:include>:在页面被请求的时候引入一个文件 2)<jsp:param>:在动作组件中引入参数信息 3)<jsp:fo ...

  5. 深挖Openstack Nova - Scheduler调度策略

    深挖Openstack Nova - Scheduler调度策略   一.  Scheduler的作用就是在创建实例(instance)时,为实例选择出合适的主机(host).这个过程分两步:过滤(F ...

  6. 备战金九银十,Java研发面试题(Spring、MySQL、JVM、Mybatis、Redis、Tomcat)[带答案],刷起来!

    八月在即,马上就是"金九银十",又是跳槽招聘季.咱们这行公认涨薪不如跳槽加的快.但不建议频繁跳槽,还是要学会融合团队,抓住每个机会提升技能. 苏先生在这里给大家整理了一套各大互联网 ...

  7. Java初中级程序员面试题宝典

    Java基础部分 &与&&区别? &和&&都是逻辑运算符,都是判断两边同时真则为真,否则为假:但是&&当第一个条件不成之后,后面的条件都 ...

  8. AbstractCollection

    概述 这个类提供了实现Collection接口的骨架,来最小化实现此接口所做的工作. 要实现一个不可修改的 collection,编程人员只需扩展此类,并提供 iterator 和 size 方法的实 ...

  9. Ubuntu 下jdk的安装

    因为我ubuntu下需要运行一个java程序,其实是想做一下tc,因为浏览器要运行java插件,那个客户端一直下载不了,我记得我装过的,这个问题后面说.然后我就打算重新安装,通过查找资料,终于解决了手 ...

  10. spring boot 学习笔记(二)之打包

    一.叙述 spring boot 在 pom 中可以配置成  packaging 为 jar ,这样打包出来的就是一个 jar 包,可以通过 Java 命令直接运行, Java 命令为: java - ...