准备工作

准备docker

这里给出各个系统安装docker的详细步骤,最后我们不要忘了设置docker加速

Docker 安装www.runoob.com/docker/ubuntu-docker-install.html

Docker 镜像加速www.runoob.com/docker/docker-mirror-acceleration.html正在上传…重新上传取消

准备python项目

docker python包 镜像 python打包docker镜像_Dockerfile

python项目结构

这里简单介绍下各个目录、文件作用

  • docker_demo 项目顶级目录
  • Dockerfile 后面根据Dockerfile创建docker镜像,后续将详细讲解该文件
  • logs 日志目录,主要用来演示如何将容器中的数据同步到宿主机中去
  • README 介绍整个项目的背景和使用方法
  • requirements.txt 该文件描述了python项目的依赖环境
  • src 该目录下放置函数入口文件
  • main.py 该文件简单地验证docker是否成功安装好环境依赖、容器是否能和宿主机进行数据同步

编写Dockerfile

将Dcokerfile文件置于项目根目录下,文件内容如下

FROM python:3.7

WORKDIR ./docker_demo
 
ADD . .

RUN pip install -r requirements.txt

CMD ["python", "./src/main.py"]
  • FROM python:3.7

FROM <基础镜像>。所谓定制镜像,那一定是以一个镜像为基础。FROM 指令用来指定以哪个镜像作为基础镜像生成新的镜像。这里我们将官方Python的3.7版本镜像作为基础镜像。

  • WORKDIR ./docker_demo

WORKDIR <工作目录路径> 。 使用 WORKDIR 指令可以来指定镜像中的工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录。

  • ADD . .

ADD <源路径> <目标路径>。使用ADD指令可以将构建上下文目录中的源路径目录复制镜像内的 <目标路径> 位置。第一个参数“.”代表Dockerfile所在的目录,即python项目dockerdemo下所有的目录(不包括docker_demo自身)。第二个参数“.”代表镜像的工作目录docker_demo。所以该行命令会将python项目docker_demo目录下的所有文件复制到镜像的docker_demo目录下。这样docker镜像中就拥有了一份docker_demo python项目。

  • RUN pip install -r requirements.txt

RUN 指令是用来执行命令行命令的。这里直接安装requirements.txt 中指定的任何所需软件包。

  • CMD["python","./src/main.py"]

CMD 指令是容器启动命令,这里是在容器启动时通过python运行 main.py。值得注意的是./目录指的是当前工作目录即docker_demo

requirements.txt

pandas==1.1.3

main.py

# 导入numpy验证docker是否根据requirements文件安装好了依赖
import numpy as np
if __name__ == '__main__':
    # 在logs目录下创建个名为docker.log的空文件,验证容器和宿主机是否能进行数据同步
    os.mknod('../logs/docker.log')
    print("hello docker")

生成Docker镜像

在dockerfile所在的目录下运行。

sudo docker build -t demo:v1 .

我们利用build指令生成镜像,-t 参数指定了最终镜像的名字为demo:v1。如果注意,会看到 docker build 命令最后有一个 . 。 . 表示当前目录,这里是指将Dockerfile所在的当前目录作为构建上下文目录。注意:不清楚构建上下文目录含义的同学可以返回编写Dockerfile小节,查看ADD . .指令中对构建上下文目录的描述。

运行Docker容器

sudo docker run demo:v1

我们用docker run运行容器 ,终端显示 hello docker 表示容器运行成功

但是有一点,我们的程序应该会在logs目录下创建一个docker.log文件,我们打开python项目docker_demo下的logs目录并没有发现docker.log文件。也就是说容器运行时产生的数据并没有同步到宿主机。这并不我们的生成镜像、运行容器的步骤出错了,这是docker设计者不想让容器去改变宿主机而做的设计。那我们想要获取或者说持久化容器生产的数据该如何做呢?

加载数据卷

sudo docker run -v /docker_demo/logs:/logs demo:v1

运行容器的时候加上-v参数 /docker_demo/logs:/logs。

这里命令的含义是将 宿主机的/docker_demo/logs挂载到容器的/logs上。这样容器对/logs目录的操作就会同步到宿主机的/docker_demo/logs目录。

通过-v能够同步容器和宿主机目录的读写,运行容器之后,我们发现docker_demo下的logs目录能多出一个docker.log文件。