本文首发于微信公众号:Hunter后端
原文链接:Docker笔记三之运行Django系统
这一篇笔记介绍一下如何使用 Docker 运行 Django 系统。
流程大概是这样,拉取一个 python 镜像,然后将我们的 Django 系统放到该镜像中构建一个新的镜像,运行新镜像产生的容器就有我们的 Django 服务了。
以下是本篇笔记目录:
- 镜像和系统准备
- Dockerfile 准备
- 构建镜像
- 运行容器
- 其他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 的内容是:
- FROM 命令:在 python:3.6 的基础镜像上操作
- RUN 命令:在镜像内创建 /hunter 文件夹
- WORKDIR 命令:指定镜像内工作目录为 /hunter
- ADD 命令:将宿主机的 requirements.txt 文件复制到镜像内 /hunter 目录下
- RUN 命令:在镜像内进入 /hunter 文件夹下
- RUN 命令:在镜像内根据 /hunter 文件夹下的 requirements.txt 文件安装 python 依赖
- ADD 命令:将宿主机的 Django 系统文件整个复制到镜像内的 /hunter 文件夹下
- 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
如果想获取更多后端相关文章,可扫码关注阅读:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。