在Docker for Windows中运行GUI程序
Docker运行GUI原理
Docker目前大多应用在服务器领域,那么在Docker中可以运行GUI程序吗?怀着好奇心google了一番,还真有人写了一篇文章 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"
上述参数的含义就是将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
相较原文有如下变动:
- ubuntu的版本也升级到了18.04
- apt源替换成了中科大的镜像地址方便快速构建
Docker build
$ docker build -t firefox .
和原文一致,构建容器。
Docker run
$ docker run -ti --rm -e DISPLAY=host.docker.internal:0.0 firefox
相较原文有如下变动:
- 删除了
set-variable -name DISPLAY -value YOUR-IP:0.0命令 - 设置容器的
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效果如下:

注意:必须安装中文字体,仅仅设置语言环境还是会导致乱码的。
其他方式
网上还有几种方式,我只看了文章的理论,感觉可行,大家有空可以去亲自尝试一番:
Xvfb + VNC- https://medium.com/dot-debug/running-chrome-in-a-docker-container-a55e7f4da4a8Xming- https://blogs.msdn.microsoft.com/jamiedalton/2018/05/17/windows-10-docker-gui/SSH with X11 forwarding- https://blog.docker.com/2013/07/docker-desktop-your-desktop-over-ssh-running-inside-of-a-docker-container/X11docker- 一个专门为Docker增加X11图形渲染支持的项目 https://github.com/mviereck/x11docker
在Docker for Windows中运行GUI程序的更多相关文章
- 在OSX和Windows版本Docker上运行GUI程序
看到很多人在Docker问题区讨论:如何在OS X和Windows的Docker上运行GUI程序, 随手记录几个参考资料: https://github.com/docker/docker/issue ...
- 在 Docker 容器中运行应用程序
案例说明 运行 3 个容器,实现对网站的监控. 三个容器的说明: 容器 web: 创建自 nginx 映像,使用 80 端口,运行于后台,实现 web 服务. 容器 mailer: 该容器中运行一个 ...
- 如何在windows中编写R程序包(转载)
网上有不少R包的编译过程介绍,挑选了一篇比较详细的,做了稍许修改后转载至此,与大家分享 如何在windows中编写R程序包 created by helixcn modified by binaryf ...
- 如何实现在Windows上运行Linux程序,附示例代码
微软在去年发布了Bash On Windows, 这项技术允许在Windows上运行Linux程序, 我相信已经有很多文章解释过Bash On Windows的原理, 而今天的这篇文章将会讲解如何自己 ...
- 【爬坑】在 IDEA 中运行 Hadoop 程序 报 winutils.exe 不存在错误解决方案
0. 问题说明 环境为 Windows 10 在 IDEA 中运行 Hadoop 程序报 winutils.exe 不存在 错误 1. 解决方案 [1.1 解压] 解压 hadoop-2.7.3 ...
- 在Windows中运行Linux bash命令的几种方法
如果你正在课程中正在学习 shell 脚本,那么需要使用 Linux 命令来练习命令和脚本. 你的学校实验室可能安装了 Linux,但是你自己没有安装了 Linux 的笔记本电脑,而是像其他人一样的 ...
- # 如何在Windows下运行Linux程序
如何在Windows下运行Linux程序 一.搭建 Linux 环境 1.1 安装 VMware Workstation https://www.aliyundrive.com/s/TvuMyFdTs ...
- 在dos中运行java程序,若出现Exception in thread “main" java.lang.NoClassDefFoundError
在dos中运行java程序,若出现Exception in thread “main" java.lang.NoClassDefFoundError,可以检查一下几项: 环境变量配置: 注意 ...
- 解决由于一个软件限制策略的阻止,windows无法运行此程序cmd.reg
解决由于一个软件限制策略的阻止,windows无法运行此程序cmd.reg Windows Registry Editor Version 5.00 [-HKEY_LOCAL_MACHINE\SOFT ...
随机推荐
- 数据库中 ’’ 和 NULL的区别
null不是对象,''是对象 从'',你就可以知道这是一个字符串类型的数据,是一个长度为零的字符串. 从NULL,你只能知道这里没有赋过值,是空的,他不属于任何数据类型. 我们在数据库实际使用中,一般 ...
- springboot-多模块构建
1. 场景描述 先介绍下背景,项目为什么需要用多模块?springmvc难道还不够? (1)设计模式真言:"高内聚.低耦合",springmvc项目,一般会把项目分成多个包:con ...
- python基础知识四 小数据池,深浅拷贝,集合+菜中菜
四.小数据池,深浅拷贝,集合+菜中菜 1小数据池 --缓存机制(驻留机制) '==' 判断两边内容是否相等 'is' 基于内存地址进行判断是否相同 a = 10 b = 10 print(a ...
- VirtualBox下安装Linux系统
Linux 开源的类Unix操作系统,拥有图形界面文字界面,旗下发行版不胜其数(Ubuntu.Deepin.CentOS...)在互联网公司中Linux服务器大多是用的CentOS系统,其他Linux ...
- 创建PaletteSet的一个问题
下面是一个常规创建PaletteSet面板的代码: public static PaletteSet m_ps = null; [CommandMethod("MyPalette" ...
- hdu6396 Swordsman(贪心)
Swordsman 题目传送门 解题思路 先将每种属性排序,因为打倒怪兽会使属性增强,所以肯定是能打就打,用cnt[i]记录怪兽i已经被超过的属性数量,如果被超过的属性数为k了,则打倒此怪兽,将获得的 ...
- 科密指纹考勤机B329采集
昨天项目用到了科密指纹考勤机B329. 暂记录下碰到的问题,及其解决办法,以备查询. 1.下载科密的二次开发包SDK“10079” .地址:( http://pan.baidu.com/s/1i39m ...
- python检测是否是质数
python检测是否是质数 编写python脚本,使得实现以下功能: 输入一个整数,通过脚本判断出输入的这个数是否是质数,然后输出是否是质数. 脚本如下图所示: Num = input("P ...
- Django的性能优化
Django的性能优化 一,利用标准数据库优化技术 传统数据库优化技术博大精深,不同的数据库有不同的优化技巧,但重心还是有规则的.在这里算是题外话,挑两点通用的说说: 索引,给关键的字段添加索引, ...
- Bellman-Ford 算法
根据之前最短路径算法里提到的,我们只要放松所有边直到其全部失效就可以得到最短路径 注意:图中不能有负圈.否则当负圈中某个点经过这个负圈的所有边的松弛操作后,这个点的的d[i]就会减小,此时会发现它可以 ...