用Docke和VNC制作Ubuntu的远程桌面

个人终端总是有很多的限制,一是没有办法随时随地携带,二是各种应用安装删除,时间一长,系统很乱,三是在外时连接家庭局域网困难。所以在家中安装一台服务器并运行桌面系统还是有需要的。实现方案比较流行的是远程控制软件,经过比较,多数体验不是很好,主要是连接效果不理想或者是要安装各种终端软件,并依赖软件开发商,各种注册或购买。

参考了不同的实现方法之后,决定自己用Docker搭建一个Web版的远程桌面,实现一个浏览器基本满足要求,网络上已经有比较好的成熟方案,但比较少,大家可以直接下载来使用,效果是不错的,这里我还是自己动手搭建,记录一下过程并分享几点经验。

一、安装基于Ubuntu官方镜像的docker容器

1、下载官方镜像 docker pull ubuntu

这里直接下载20.04版本比较好,以前版本也没有问题,20.04版自带的python是3.8.5,以后安装noVNC时可以不用再安装一堆python的依赖。

这个系统仅有73MB,只非常简单的一个核心,所有的基础应用都要从头安装。

2、启动容器并更新国内源

由于后面安装的桌面系统庞大,首先是要将ubuntu换成国内源,否则无法进行后面的操作。

2.1 SSH连接服务器,直接 docker run -p 6080:6080 ubuntu:latest 启动ubuntu容器。

2.2 进入容器并更新源

apt-get update  #更新ubuntu的官方列表

apt-get install nano ca-certificates  #安装编辑器和源证书

nano /etc/apt/souces.list #打开源的配置文件并把以下中科大的源复制到文件中

deb https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse

deb https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse

deb https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse

deb https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse

二、在容器中安装轻量级的桌面系统

1、安装桌面

典型桌面发行版的ubuntu界面比较漂亮,但十分臃肿庞大,用于远程桌面资源占用太大,选用轻量的系统比较适合,这里安装台湾人开发的LXDE系统,简洁大方。

apt-get update  #不要忘记这一步,这样就可以将源切换到国内了

apt-get install lxde-core galculator gpicview mousepad xarchiver lxterminal git

# lxde桌面完整版组件比较多,仅安装核心模块和几个常用工具。

2、安装用于远程显示的组件

远程连接显示有多种选择,主要是VNC方案,VNC也有多种选择,比较方便简单的是安装tightvncserver,一条安装命令后就可以直接进行连接,不足是连接后在桌面调节显示不方便。网络上有很多的教程,简单实用。

从保证显示效果和运行效率,以及高可用性考虑,这里选用x11vnc方案,搭建起来比较麻烦一些。

apt-get install xorg xvfb x11vnc

xorg和xvfb可以只装一个,都是x server。而x11vnc则是vnc的 server。

3、安装语言支持

apt-get install language-pack-zh-hans
apt-get install ttf-wqy-zenhei

这个语言包一定要装,否则很可能桌面起来后全部乱码。

三、调试系统的虚拟显示

1、调试Xvfb

进入容器,以root用户运行 Xvfb :1

检查系统的返回信息,不能有报错,顺利进入终端占用状态是正常的,这一步大概率会出错,可以百度解决。

2、调试x11vnc

另外开启SSH重新进入容器,以root用户运行 x11vnc -display :1

同样检查系统的返回信息,不能有报错,顺利进入终端占用状态是正常的,这一步也大概率会出错,可以百度解决。

3、调试openbox

开启SSH重新进入容器,以root用户运行 openbox

openbox是lxde桌面安装时装好的桌面管理器,同样不能有运行错误。

四、安装进程管理程序

1、安装进行守护程序

由于Docker自身设计的运行机制要求,仅允许运行一个用户进程,所以以上安装的那么多应用没有特殊的措施是不能同时运行的,也就没有办法显示桌面。上文提到tightvncserver运行时能够把其他程序也带起来,所以可以完成桌面的显示,这也是用vncserver部署方便的原因,但x11vnc没有这种能力,所以要安装进程守护程序,把其它的程序作为它的子进程来管理。

1.1 apt-get install supervisor

1.2 echo_supervisord_conf > /etc/supervisor/supervisord.conf

创建默认配置文件  并将配置文件修改好,其中在program模块要将xvfb openbox lxpanel pcmanfm x11vnc noVNC按优先顺序配置好。

这里也有大量的工作,要深入学习各种教程。

1.3 supervisord -c /etc/supervisor/supervisord.conf 启动supervisor 服务进行排错

2、安装错误进程回收处理程序

由于在实际运行中,有的进程会因各种原因崩溃死亡,容器部署在服务器长期运行,这种错误不处理积累下来可能会对系统造成一定的影响,也可能会影响容器的运行效率,所以部署一个进程处理程序有利于系统的长久稳定。

apt-get install tini #这个程序要求以PID1运行,所以要用脚本在容器启动时首先运行,具体可以教参官网。

以上两种程序的基本原理是,用supervisor保证所有进程正常运行,失败或崩溃后及时拉起来,保证各种服务正常,用tini处理进程错误,保证系统干净,不影响效率。

五、安装远程Web工具

前面安装完成后,启动系统就可以用vnc viewer软件进行连接了,要求是你的终端上安装了这个软件。还有一种选择是安装noVNC,一种广泛应用的web vnc连接方式,好处是只要用浏览器就可以VNC连接,不用另外安装什么东西。

1、git clone https://github.com/novnc/noVNC.git #下载noVNC代码

2、安装noVNC并检查安装错误

cd noVNC/utils

bash launch.sh –vnc localhost:5900

这里系统会自动下载各种依赖程序进行安装,包括其中重要的组件websockify,如果基础镜像是ubuntu18.04就要自己先升级python3并安装pip,再安装setup-tools,再手动安装websockify,过程复杂,很容易出错,但肯定也能正常运行,具体看官网说明。

六、验证整个系统是否安装正确,能否正常运行

1、先docker stop 停止容器,再dcoker start启动容器,并用 ps -a 检查系统用户进程情况,使容器有一个干净的环境。

2、启动tini,检查程序运行,只要能运行就可以,如果系统警告不是PID1运行不用管。

3、用supervisor启动桌面系统

supervisord -c /etc/supervisor/supervisord.conf

用ps -a检查系统进程情况,如果program模块中配置的进程全部正常运行则表示安装成功,否则根据信息进行排错处理。

由于配置文件中只要有一个进程错误,就可能导致所有进程起不来,所以排查错误的时候可以先只留一个程序,其它注释掉,正常运行再加入下一个,直到全部正常运行。

4、在浏览器中运行 IP:6080 系统进入桌面

七、在容器中安装基础应用

1、安装火狐浏览器,这个浏览器是ubuntu的默认配置,兼容性良好。

apt-get install firefox

这里安装的是国际版,安装后在选项的语言中选添加语言,选chinese(china),应用并重新启动后就是中文界面了。不要另外安装中文字体,否则字体可能更难看。

2、安装输入法、WPS等软件,根据需要安装相关应用并完成配置。

八、生成基础镜像

用docker commit命令将以上配置好的容器保存为基础镜像。

基础镜像生成后,原有的容器就没有用了,暂时停止容器运行,后面工作如果没有问题可以删除此容器。

九、用配置好的基础镜像制作以脚本启动的webvnc的docker镜像

1、编写容器启动脚本

在主机的用户目录下建立start.sh启动脚本,主要可以包括以下内容:

if [ -n “$PASSWORD” ]; then
echo -n “$PASSWORD” > /.passwd1
x11vnc -storepasswd $(cat /.passwd1) /.passwd2
sed -i ‘s/^command=x11vnc.*/& -rfbauth \/.passwd2/’ /etc/supervisor/supervisord.conf
export PASSWORD=

exec /bin/tini — supervisord -n -c /etc/supervisor/supervisord.conf

2、编写Dockerfile

ROM ubuntu:tag
COPY start.sh /
RUN chmod +x start.sh
ENTRYPOINT [“/start.sh”]

ubuntu:tag就是在上一步生成的基础镜像

3、生成web vnc的成品镜像

dcoker build -t vncubuntu:newtag .

十、运行web vnc容器

docker run -p 6080:6080 -e PASSWORD=passwd vncubuntu:newtag

系统正常启动过程如下:

02:07:12,361 INFO supervisord started with pid 11

02:07:13,371 INFO spawned: ‘xvfb’ with pid 15

02:07:13,373 INFO spawned: ‘openbox’ with pid 16

02:07:13,375 INFO spawned: ‘lxpanel’ with pid 17

02:07:13,377 INFO spawned: ‘pcmanfm’ with pid 18

02:07:13,390 INFO spawned: ‘x11vnc’ with pid 19

02:07:13,394 INFO spawned: ‘novnc’ with pid 20

在浏览器中输入 IP:6080  ,系统显示登录界面,输入启动容器时设置的密码,进入系统。

其它

到现在仅局域网内可以运行,要想在外网访问局域网,需要配置主机可以外网访问并映射好端口,特别注意,上述安装没有配置SSL,仅能http访问并不安全,可以在主机中安装反向代理并配置好SSL,这样就可以https访问了。

几个问题:

1、xvfb或x11vnc命令出现 access control disabled,clients can connect from any host以及 unable to open display

这个问题是启动VNC服务时,系统需要定向到指定的内部显示环境,因此要进行相关设置。

终端执行 export DISPLAY= :1

xhost +

此时,系统提示“access control disabled, clients can connect from any host”才正确。然后再重新执行服务器命令。

2、supervisor命令启动时是服务端和客户端一起启动,如果配置文件有问题,有可能导致服务端运行不正常,显示unix:///var/run/supervisor.sock refused connection等问题,表示客户端无法正常连接。

解决问题的关键是该命令的conf配置文件要正常,只要配置改好了,服务端就能启动,客户端能不能正常连接不是大问题,因为客户端只是用于辅助运行和获取信息,这里没有太大用处,也就是这个问题可以不处理。

用ps 命令查看supervisor守护运行的进程是否起来,全部起来了表示成功,否则继续调试。

3、中文输入法的问题

系统安装好后,系统已经附带安装好了ibus输入法,但是原始配置没有中文,而且安装中文输入后在浏览器和wps中无法输入中文,网上有很多教程,主要是推荐安装fcitx,其实没有必要,ibus是linux默认的输入法,非常好用,只是中文环境下要做一定的配置。

3.1 补充安装中文拼音和五笔输入

apt-get install ibus-table-wubi ibus-pinyin

3.2 配置中文输入

编辑.bashrc文件,nano /home/**/.bashrc 加入以下语句:

export GTK_IM_MODULE=ibus
export QT_IM_MODULE=ibus
export XMODIFIERS=@im=ibus

这样在浏览器和文本编辑器中就能输入中文了,但在wps中还是不行,终端中打开wps的四个配置文件,/usr/bin/wps,/usr/bin/et,/usr/bin/wpp,/usr/bin/wpspdf,加入以下语句就可以了。

export XMODIFIERS=”@im=ibus”
export QT_IM_MODULE=”ibus”