头图

本文首发于微信公众号:Hunter后端

原文链接:Docker笔记三之运行Django系统

这一篇笔记介绍一下如何使用 Docker 运行 Django 系统。

流程大概是这样,拉取一个 python 镜像,然后将我们的 Django 系统放到该镜像中构建一个新的镜像,运行新镜像产生的容器就有我们的 Django 服务了。

以下是本篇笔记目录:

  1. 镜像和系统准备
  2. Dockerfile 准备
  3. 构建镜像
  4. 运行容器
  5. 其他Dockerfile命令

1、镜像和系统准备

镜像拉取

首先我们需要准备一个 Python 3.6 的镜像,用于后面构建我们的 Django 镜像。

通过下面的命令拉取:

docker pull python:3.6

然后通过 docker images 可以看到在 REPOSITORY 下名一个 python, TAG 为 3.6 镜像

Django 系统准备

根据隔壁 Django 笔记,我们可以创建一个新系统,也可以用自己的项目系统,这里我们命名为 hunter,放在 ~/ 目录下,这个目录地址可以自定义

python 依赖准备

然后准备一个 requirements.txt,这包含了我们运行系统所需要的全部依赖,可以在我们创建的 Django 系统下通过 pip freeze 命令获得:

pip3 freeze > requirements.txt

requirements.txt 这个文件我们也放在 ~/ 目录下

2、Dockerfile 准备

然后我们需要新建一个 Dockerfile 文件,这个文件的作用是依据我们写好的命令,在一个基础镜像上将我们需要运行的 Django 系统或者其他系统传到镜像里成为一个新的镜像

我们创建的 Dockerfile 也放在 ~/ 目录下

FROM python:3.6

RUN mkdir /hunter -p

WORKDIR /hunter

ADD ./requirements.txt /hunter

RUN cd /hunter
RUN pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

ADD ./hunter /hunter

CMD ["python3", "manage.py", "runserver", "0:9898"]
  • FROM 构建新的镜像的基础镜像,即使用哪个指定的镜像作为基础来构建新的镜像
  • ADD 复制指令,类似于 COPY 指令,在这里,使用 COPY 指令也可以,不同点在于对压缩文件的处理
  • RUN 执行指令,在构建新镜像的时候运行
  • CMD 也是执行指令,不过是在容器运行的时候执行,相当于是容器启动时的默认指令
  • WORKDIR 指定工作的目录,在容器运行起来后,使用命令进入容器,默认进入的也是 WORKDIR 的目录

所以我们上面的 Dockerfile 的内容是:

  1. FROM 命令:在 python:3.6 的基础镜像上操作
  2. RUN 命令:在镜像内创建 /hunter 文件夹
  3. WORKDIR 命令:指定镜像内工作目录为 /hunter
  4. ADD 命令:将宿主机的 requirements.txt 文件复制到镜像内 /hunter 目录下
  5. RUN 命令:在镜像内进入 /hunter 文件夹下
  6. RUN 命令:在镜像内根据 /hunter 文件夹下的 requirements.txt 文件安装 python 依赖
  7. ADD 命令:将宿主机的 Django 系统文件整个复制到镜像内的 /hunter 文件夹下
  8. CMD 命令:指定容器启动时运行的命令

以上命令在我们构建镜像的时候会依次执行。

注意: CMD 指定的程序会被 docker run 的时候后面添加的程序指令覆盖

与 CMD 还有个作用类似的命令,ENTRYPOINT,这个用法后面再介绍

就此,我们构建新镜像的步骤和命令就此指定了。

3、构建镜像

接下来的操作就是根据 Dockerfile 构建一个新镜像

进入 ~/ 文件夹下,有以下几个文件及文件夹:

hunter/
requirements.txt
Dockerfile

基本的命令如下:

docker build . -t tag -f Dockerfile

-t 参数表示构建新镜像时手动打的一个 tag

-f 表示指定的 Dockerfile 文件,如果不使用 -f 参数,会默认寻找当前文件夹的 Dockerfile

接下来我们打一个 tag 为 Django:1.0.0 的镜像,使用前面我们创建的 Dockerfile

docker build . -t django:1.0.0 -f Dockerfile

在这里 -f 参数可以不添加,因为会默认使用当前文件夹的 Dockerfile 文件

可以看到下面这种类似的输出内容:

Step 7/8 : ADD ./hunter /hunter
 ---> 84a62ad79b51
Step 8/8 : CMD ["python3", "manage.py", "runserver", "0:9898"]
 ---> Running in 33bcc53af8cf
Removing intermediate container 33bcc53af8cf
 ---> 926fce7b8cea
Successfully built 926fce7b8cea
Successfully tagged django:1.0.0

然后使用 docker images 命令可以看到有一个 django:1.0.0 的镜像了。

4、运行容器

接下来我们可以根据 image id 或者 django:1.0.0 这个 tag 来运行容器:

docker run -p 9898:9898 django:1.0.0

然后当前界面会显示 Watching for file changes with StatReloader 这种信息

然后访问我们的系统 localhost:9898 类似这种,在当前界面就会输出相应的访问信息

而如果我们想要停止运行这个容器,可以在新开一个shell,通过 docker ps 找到正在运行的容器,然后 docker stop xxxx停止或者直接在当前界面 ctrl + c

在后台运行这个容器可以如下操作:

docker run -itd -p 9898:9898 django:1.0.0

在这里我们使用 -p 参数将容器的 9898 端口映射到宿主机的 9898 端口

注意: 为了以示区分,假设端口映射为 -p 5678:9898,前面的 5678 是宿主机的端口,后面的 9898 是容器内的端口

在容器运行起来之后,如果想进入该容器,可以 通过 docker ps 找到这个运行的容器,然后 使用下面的命令进入容器内查看

5、其他Dockerfile命令

除了在前面介绍的 Dockerfile 命令,还有挂载的命令 VOLUME,端口声明的命令 EXPOSE,环境变量设置的命令 ENV,还有与 CMD 相似的指令执行的命令 ENTRYPOINT 等

EXPOSE

可用于声明这个镜像使用的端口,在运行的时候可以使用 -p 参数映射这个端口,但似乎并无太多实际意义,可以用于在 Dockerfile 中声明,后期便于查看

VOLUME

挂载的命令,我们可以在后面的运行 MySQL 镜像的时候介绍

ENV

命令为环境变量,可以在构建镜像的时候就指定变量,也可以在 运行容器的时候指定命令,可以直接在 Dockerfile 中如此声明:

ENV key value

ENTRYPOINT

与 CMD 类似的作用,但 ENTRYPOINT 不会被容器启动时的指定的指令覆盖,而 CMD 命令会被覆盖

比如:

docker run -itd image_id bash

这里就指定了新的 CMD 命令为 bash,那么原来的 CMD 命令就被覆盖,不会执行了

如果想要覆盖 Dockerfile 中的 ENTRYPOINT 命令,仅在容器 run 的时候,使用 --entrypoint 的参数,则会覆盖 ENTRYPOINT 指定的程序

在 Dockerfile 中,如果存在多个 ENTRYPOINT 命令,仅最后一个生效,比如:

# Dockerfile

ENTRYPOINT ["python3", "manage.py", "runserver", "0:7979"]

ENTRYPOINT ["python3", "manage.py", "runserver", "0:9898"]

则系统会运行 最后一条,使用 9898 的端口

ENTRYPOINT 和 CMD 搭配使用

因为 entrypoint 不会被覆盖,所以可以放入不会变的命令

而 CMD 会被后面的参数覆盖,所以可以放入会被更改的数据,比如端口,或者其他会变的配置文件位置

以 Django 系统为例,我们可以将 python3 manage.py 这两个命令给 entrypoint,将端口的设置给 CMD,因为端口我们是可以更改的。

示例如下:

ENTRYPOINT ["python3", "manage.py", "runserver"]
CMD ["0:9898"]

然后我们重新构建镜像,获得新的 image_id,然后运行容器,加上 CMD 命令更换端口为 9999:

docker run -itd -p 9898:9999 image_id 0:9999

通过上面的命令将系统运行起来后,还是可以访问宿主机的 localhost:9898,但是容器内部使用的端口已经变成了 9999

我们可以进入容器内部,查看运行的进程,可以看到在容器内已经是 使用的 9999 端口在运行

docker exec -it container_id bash

ps aux

如果想获取更多后端相关文章,可扫码关注阅读:
image.png


Hunter
27 声望12 粉丝