前言如果你是一个python自动化测试人员,某天你在公司终于完成了一个项目的接口自动化脚本工作,在你自己常用的本机或者服务器上调试完成了脚本,稳稳地没问题。 可是晚上下班回家,你自己找了个linux的服务器,想在家里也练练手,于是重新安装python3.6版本,网上找个教程巴拉巴拉的一大堆指令安装。 第二天你回到公司,领导说你这个脚本能不能放到另外一套环境的服务器上执行(与你本机环境是不通的),于是你又重复安装一遍python3.6环境和执行脚本的一些依赖包。 运气好还能联网pip在线安装,运气不好,都不能连接外网,只能本地安装。于是乎你开始怀疑人生,为什么我要重复安装这么多次环境啊。。。。 要是100个不同服务器,我是不是得安装100次啊,于是乎你会想:我是不是可以做一个虚拟的python3.6环境,事先安装好我需要的依赖包。 把做好的虚拟环境传到某个仓库(类似github),哪个机器需要用到,就一键导入过去就ok了,于是docker制作自己的镜像文件势在必行了,这就是今天要说的Dockerfile制作一个属于自己的镜像文件。 Dockerfile简介Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。 简单来说,Dockerfile就是把我们安装环境的每个步骤和指令,放到一个文件,最后一键执行,最后做成一个你想要的环境。 Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。 Docker构建三步曲: 编写dockerfile文件 docker build 构建image镜像文件 docker run 运行容器
Dockerfile相关指令Dockerfile 是一个包含创建镜像所有命令的文本文件,通过docker build命令可以根据 Dockerfile 的内容构建镜像, 在介绍如何构建之前先介绍下 Dockerfile 的基本语法结构。 Dockerfile 有以下指令选项: FROM 基础镜像,当前新镜像是基于哪个镜像的 MAINTAINER 镜像维护者的姓名和邮箱地址 RUN 容器构建时需要运行的命令 CMD 指定一个容器启动时要运行的命令。 dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换。 EXPOSE 当前容器对外暴露的端口号 ENV 用来在构建镜像过程中设置环境变量 ADD 将宿主机目录下的文件拷贝到镜像里面并且ADD命令会自动处理URL和解压tar压缩包 COPY COPY:类似ADD,拷贝文件和目录到镜像中,但是它只是拷贝,不会自动处理URL和解压tar压缩包。 ENTRYPOINT 指定一个容器启动时要运行的命令。 ENTRYPOIT的目的和CMD一样,都是在指定容器启动程序及参数。 VOLUME 容器数据卷,用于数据保存和持久化工作 USER 指定运行容器时的用户名或UID,后续的 RUN 也会使用指定用户 WORKDIR 指定在容器创建后,终端默认登录进来工作目录,一个落脚点 ONBUILD 当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后,父镜像的onbuild被触发。
Dockerfile编写在当前目录新建一个文件夹docker-run, cd进入到文件夹,touch新建一个Dockerfile,然后vi打开文件,开始编辑 [root@yoyo ~]# mkdir docker-run [root@yoyo ~]# cd docker-run/ [root@yoyo docker-run]# touch Dockerfile [root@yoyo docker-run]# vi Dockerfile 编辑内容如下: # 基于python3.6.8镜像 FROM python:3.6.8
MAINTAINER yoyo <283340479@qq.com>
# 更新pip RUN pip install --upgrade pip
# 工作目录 WORKDIR /code ADD . /code
# pip安装依赖包 RUN pip install -r requirements.txt
# 传递参数 ENTRYPOINT ["pytest"]
# 默认显示help帮助信息 CMD ["--help"] requirements.txtrequirements.txt是python的相关依赖包, 可以通过freeze命令生成 pip3 freeze >requirements.txt
[root@yoyo docker-run]# cat requirements.txt APScheduler==3.5.3 asn1crypto==0.24.0 atomicwrites==1.3.0 attrs==18.2.0 backports.csv==1.0.7 bcrypt==3.1.7 beautifulsoup4==4.7.1 cached-property==1.5.1 certifi==2018.11.29 cffi==1.12.3 chardet==3.0.4 cryptography==2.7 DBUtils==1.3 defusedxml==0.5.0 diff-match-patch==20181111 Django==2.1.4 django-bootstrap3==11.0.0 django-crispy-forms==1.7.2 django-formtools==2.1 django-import-export==1.2.0 django-ranged-response==0.2.0 django-reversion==3.0.3 django-simple-captcha==0.5.10 django-stdimage==4.0.1 docker==3.7.3 docker-compose==1.24.1 docker-pycreds==0.4.0 dockerpty==0.4.1 docopt==0.6.2 et-xmlfile==1.0.1 future==0.17.1 httplib2==0.12.1 idna==2.7 jdcal==1.4 jsonschema==2.6.0 more-itertools==6.0.0 mysqlclient==1.4.2.post1 odfpy==1.4.0 openpyxl==2.6.1 paramiko==2.6.0 Pillow==5.4.1 pluggy==0.6.0 progressbar2==3.39.3 py==1.7.0 pycparser==2.19 pymssql==2.1.4 PyMySQL==0.9.3 PyNaCl==1.3.0 pytest==3.6.3 python-utils==2.3.0 pytz==2018.7 PyYAML==3.13 requests==2.20.1 six==1.12.0 soupsieve==1.7.3 tablib==0.13.0 texttable==0.9.1 tzlocal==1.5.1 urllib3==1.24.1 websocket-client==0.56.0 xlrd==1.2.0 xlwt==1.3.0 build构建镜像文件docker build 命令用于使用 Dockerfile 创建镜像。OPTIONS说明: —pull :尝试去更新镜像的新版本; —quiet, -q :安静模式,成功后只输出镜像 ID; —tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。
-t参数设置镜像名称yoyo_pytes和tag标签名称v1,注意最后面有个点. docker build -t yoyo_pytest:v1 .
[root@yoyo docker-run]# docker build -t yoyo_pytest:v1 . Sending build context to Docker daemon 11.78kB Step 1/8 : FROM python:3.6 ---> cfcdf565ff94 Step 2/8 : MAINTAINER yoyo <283340479@qq.com> ---> Using cache ---> f523b919fcf9 Step 3/8 : RUN pip install --upgrade pip ---> Using cache ---> 3399b50dab4e Step 4/8 : WORKDIR /code ---> Using cache ---> 7223a20e17fd Step 5/8 : ADD . /code ---> 650b554ccd6c Step 6/8 : RUN pip install -r requirements.txt ---> Running in 0e49d444f7d8 运行过程中可以看到按步骤运行,如:Step 1/8 运行完成后,可以通过docker images查看生成的镜像 [root@yoyo docker-run]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE yoyo_pytest v1 6b4267ce7ac4 21 seconds ago 1.02GB [root@yoyo docker-run]# run运行容器在当前目录新建一个test_h.py文件,写入pytest测试脚本 import pytest
# ** 作者:上海-悠悠 QQ交流群:717225969** def test_one(): print("正在执行----test_one") x = "this" assert 'h' in x
def test_two(): print("正在执行----test_two") x = "hello" assert x
def test_three(): print("正在执行----test_three") a = "hello" b = "hello world" assert a in b
if __name__ == "__main__": pytest.main(["-s", "test_h.py"]) 使用docker run运行容器 -it -t让docker分配一个伪终端并绑定到容器的标准输入上, -i则让容器的标准输入保持打开. —rm 容器退出时,自动清除容器。 —rm选项不能与-d同时使用 -v 将容器的工作目录/code挂载到宿主机的$PWD,也就是当前目录 yoyo_pytest:v1 容器名称和tag名称 test_h.py 后面跟着需要执行的脚本名称
[root@yoyo docker-run]# docker run -it --rm -v "$PWD":/code yoyo_pytest:v1 test_h.py -s ================================================================== test session starts ================================================================== platform linux -- Python 3.6.9, pytest-3.6.3, py-1.7.0, pluggy-0.6.0 rootdir: /code, inifile: collected 3 items
test_h.py 正在执行----test_one .正在执行----test_two .正在执行----test_three .
=============================================================== 3 passed in 0.01 seconds ================================================================ [root@yoyo docker-run]#
|