前一次我们通过 docker 搭建了 selenium 的分布式测试环境。
在学习过程中,觉得如果把调试环境也放在 docker,这样不管以后在工作中统一大家的调试的测试环境肯定会有帮助的。
刚开始我觉得只要我把我配置好的环境做成一个 images 然后发给需要的人,让他们导入到 docker 中就可以了。
但是这个方法看起来很笨重,也不利于镜像的管理,如果镜像里修改了某些内容,难道还让我把新的镜像在发放一次?
答案是这个方法可行,但是还是笨重。
好在 docker 有自己的管理方式,就是 dockerfile。
工作原理很简单,dockerfile 中先指定一个基础镜像,然后把 shell 命令写到脚本中,然后脚本根据内容,在基础镜像的上开始运行脚本,最后就生成了新的镜像。
这种方式的好处就我现在能感受到的优点有:
1.方便传送,一个 dockerfile 基本上不会大于 1M,但是一个 docker image 有的却会是几百 M 以上的。
2.方便维护,当我们的 images 中需要删除,或者增加什么工具或者控件的时候,我们修改 dockerfile,然后发布出去,大家重新构建 images 就可以了。不需要去通知每个人去做操作,或者去每个人的 images 中去做相同的操作。

那么我们开始学习 dockerfile。

目标:在镜像 selenium/standalone-chrome-debug 中添加 python 和中文字体。

1.问题

首先我们看下图

上图是我启动容器 debug(使用的镜像 selenium/standalone_chrome_debug),首先我们发现没有安装 python,其次打开的网页中中文显示为乱码。我们就遇上了两个问题
问题 1:安装 python
问题 2:增加字库

增加字库,解决方案

下图是@ycwdaaaa 在文章https://testerhome.com/topics/8450 中给出一个解决方案。他建议在 dockerfile 中加入以下命令

前面我说了 dockerfile 中其实很大一部分就是执行 shell 命令。
那么我们来验证下,在容器 debug 的 bash 中输入命令
apt-get update
apt-get -y install ttf-wqy-microhei ttf-wqy-zenhei
重新打开浏览器,发现中文乱码已经解决,不但问题解决了,还证明只要会 shell 命令,dockerfile 的配置还是很简单的。

那我们开始编写 dockfile 然后构建我们需要的镜像。

FROM selenium/standalone-chrome-debug:3.4.0


USER root

RUN apt-get update \
    && apt-get -y install ttf-wqy-microhei ttf-wqy-zenhei \
    && apt-get clean

我们来分析下这段 dockfile 的内容
1.FROM selenium/standalone-chrome-debug:3.4.0
从一个基础镜像开始建立我们的新镜像 这里把 selenium/standalone-chrome-debug:3.4.0 作为基础镜像

2.USER root
没有取查,估计意思是给 root 权限吧。

3.RUN apt-get update \
&& apt-get -y install ttf-wqy-microhei ttf-wqy-zenhei \
&& apt-get clean
RUN 是 dockerfile 中的一个命令就是运行
然后先运行命令
apt-get update
看看 apt-get 的是否有更新
在运行命令
apt-get -y install ttf-wqy-microhei ttf-wqy-zenhei
用 apt-get 命令安装字库
最后运行命令
apt-get clean

那么来运行 dockerfile 来构建,输入命令
docker build -t debug/chinese .
这里我们要注意,好像运行 docker build 的时候是自动寻找当前目录下的 dockerfile,所以,我们先要进入到需要运行 dockerfile 的目录下才运行改命令。
如果 build 顺利,我们应该在 images 命令中找到新构建的镜像 debug/chinese

然后我们启动该镜像

然后用 vnc 链接到容器内部。

打开 chrome 浏览区,输入百度的首页,我们就看到新构建的镜像启动出来的容器中的浏览器是没有中文乱码的困惑的。

Ps:注意,构建的时候一定要注意网络状态,我家网络太差了,构建的时候经常失败,构建了 4 个小时,才成功的。失败的时候,也会产生 image,但是是没有 repository 名和 tag 名的,还会启动一个容器。我们需要先去杀掉容器,docker rm 命令,在删除构建失败的镜像 docker rmi 命令。

添加 python 系统,解决方案

通过字库的解决方案,我们了解到了 dockerfile 如何使用的。
让我现在写 shell 去安装不可能,作为一个有善于思考的伸手党。
我在 github 上找到了 docker-python 的 dockerfile
https://github.com/docker-library/python/blob/db2d58d73043c85ceecc8e675372b4dc6a77d136/2.7/Dockerfile
我觉得只要把这个 dockerfile 中
FROM buildpack-deps:jessie 修改为 FROM selenium/standalone-chrome-debug:3.4.0
然后构建就应该成功。我现在就在构建中,无奈家中网络太差,一直构建到一半就失败。不过只要网络好,应该不会有问题的。

当然我们也可以做的细致点。把官方的 dockerfile 分解一下。
其实官方的 dockerfile 完成了 3 个内容。
1.安装 python
2.安装 PIP
3.安装 virtualenv

还有一些安装依赖。
所以,我打算先做一个 dockerfile,不安装 pip,virtualenv,只安装 python。然后构建成功的镜像在用新的 dockerfile(chrome_debug + python)去构建一个 PIP 的的镜像。

FROM selenium/standalone-chrome-debug:3.4.0

# ensure local python is preferred over distribution python
ENV PATH /usr/local/bin:$PATH

ENV LANG en_US.UTF-8

# runtime dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
        tcl \
        tk \
    && rm -rf /var/lib/apt/lists/*


RUN apt-get update \
    && apt-get -y install ttf-wqy-microhei ttf-wqy-zenhei \
    && apt-get clean

RUN apt-get update && apt-get install -y build-essential

ENV GPG_KEY C01E1CAD5EA2C4F0B8E3571504C367C218ADD4FF
ENV PYTHON_VERSION 2.7.13

RUN set -ex \
    && buildDeps=' \
        tcl-dev \
        tk-dev \
    ' \
    && apt-get update && apt-get install -y $buildDeps --no-install-recommends && rm -rf /var/lib/apt/lists/* \
    \
    && wget -O python.tar.xz "https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tar.xz" \
    && wget -O python.tar.xz.asc "https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tar.xz.asc" \
    && export GNUPGHOME="$(mktemp -d)" \
    && gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$GPG_KEY" \
    && gpg --batch --verify python.tar.xz.asc python.tar.xz \
    && rm -r "$GNUPGHOME" python.tar.xz.asc \
    && mkdir -p /usr/src/python \
    && tar -xJC /usr/src/python --strip-components=1 -f python.tar.xz \
    && rm python.tar.xz \
    \
    && cd /usr/src/python \
    && ./configure \
        --enable-shared \
        --enable-unicode=ucs4 \
    && make -j "$(nproc)" \
    && make install \
    && ldconfig \
    \
    && apt-get purge -y --auto-remove $buildDeps \
    \
    && find /usr/local -depth \
        \( \
            \( -type d -a -name test -o -name tests \) \
            -o \
            \( -type f -a -name '*.pyc' -o -name '*.pyo' \) \
        \) -exec rm -rf '{}' + \
    && rm -rf /usr/src/python

这个 dockerfile 其实就是把 python 的 dockerfile 拿过来然后把镜像源该成了
FROM selenium/standalone-chrome-debug:3.4.0

当中要注意两点
1.RUN apt-get update \
&& apt-get -y install ttf-wqy-microhei ttf-wqy-zenhei \
&& apt-get clean
这段就是我们前面说的添加中文字体

2.RUN apt-get update && apt-get install -y build-essential
这句花了我一天的时间调查,如果没有这句,就会报错,看下图。

造成这个错误的原因就是 selenium 的镜像里没有装好 gcc,但是 python 的镜像里是装好 gcc 的。
安装 python 本身没有问题,但是安装依赖缺失了。所以要在这里补这么一句。

然后运行 dockerfile,等新的镜像做成,然后启动容器。

我们看到了带有 python 的可以显示中文的一个 调试环境。

总结

我们可以不会写 shell,但是要会看的懂 shell,简单的操作命令百度一下什么都有了。
当 dockerfile 构建报错的时候,先去看 logs,然后把报错的那句命令 拆分开(如果是多个命令在一起的比如很多时候 apt-get 的命令是用&&连接的。)去 docker 容器内调试看看。
尽量去找官方已经做好的 dockerfile,然后微调一下。


↙↙↙阅读原文可查看相关链接,并与作者交流