参考来源
:https://www.runoob.com/docker/docker-dockerfile.html
概念
Dockerfile基于一系列的脚本或命令重新构建一个新的镜像。当然最基本的这些脚本或命令的最基础的底层基础镜像(一般是具有操作系统级别封装好的基础镜像:如centos,再nginx镜像中我们进入之后查看内部的结构可以看到它对于的目录都有相关的操作系统级别的目录结构,所以可以说明所有的镜像的基础镜像一般都是具有操作系统级别的基础镜像)。
场景
1:对开发人员提供一致性的开发环境。
2:运维人员部署实现无缝移植。
3:测试人员基于已构建的镜像做相关的扩展或构建新的镜像。
常用命令
命令 | 作用 |
---|---|
FROM IMAGE_NAME:TAG | 基于哪个基础的镜像启动构建流程(前提需镜像需先存在,不然会去pull) |
MAINTAINER USER_NAME | 声明镜像创建者(无关紧要,做一些备注或版权说明) |
ENV ke vlaue | 设置当前镜像的环境的变量,(可以写多个设置) |
RUN COMMAND | 命令的相关的执行,是Dockerfile核心部分 (可以写多条) |
ADD source_dir/file dst_dir/dir | 把宿主机的文件复制到容器内,(如果复制的文件是一个压缩的文件,将会在复制后自动的解压) |
COPY source_dir/file dst_dir/dir | 把宿主机的文件复制到容器内,(但如果复制的文件是一个压缩的文件,不会自动的解压) |
WORKDIR parh_dir | 设置工作目录,此工作目录后续的所有的命令的执行都是再目录下进行 |
CMD | 运行程序或命令 |
CMD的补充说明:
CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
CMD 在docker run 时运行。
RUN 是在 docker build。
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
实践Flask部署安装
-
1)编写flask项目相关的文件:
image.png - 2)编写相关gunicorn.conf.py
import gevent.monkey
import multiprocessing
gevent.monkey.patch_all()
# 定义同时开启的处理请求的进程数量,根据网站流量适当调整
workers = 2
# 指定每个工作者的线程数
threads = 4
# 监听内网端口80
bind = '0.0.0.0:80'
# 工作模式协程采用gevent库,支持异步处理请求,提高吞吐量
worker_class = 'gevent'
# 设置最大并发量
worker_connections = 2000
# 设置进程文件目录
pidfile = 'gunicorn.pid'
# 设置访问日志和错误信息日志路径
accesslog = 'gunicorn_acess.log'
errorlog = 'gunicorn_error.log'
# 设置日志记录水平
loglevel = 'info'
# 代码发生变化是否自动重启
reload=True
- 3)编写相关requirements.txt
cffi==1.14.3
click==7.1.2
Flask==1.1.2
gevent==20.9.0
greenlet==0.4.17
gunicorn==20.0.4
itsdangerous==1.1.0
Jinja2==2.11.2
MarkupSafe==1.1.1
peewee==3.13.3
psycopg2==2.8.6
pycparser==2.20
redis==2.10.6
Werkzeug==1.0.1
zope.event==4.5.0
zope.interface==5.1.2
- 4)编写Dockerfile文件
方式1:
FROM python:3.6
WORKDIR /data/Project/web_statistics
COPY requirements.txt ./
RUN pip install --no-cache-dir --default-timeout=100 -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
COPY . .
CMD ["gunicorn", "main:app", "-c", "./gunicorn.conf.py"]
或者
CMD ["gunicorn", "-k", "gevent", "-b", "0.0.0.0:5000", "main:app"]
方式2(不推荐run多层的话会进行多层的构建,导致镜像文件过大):
FROM python:3
MAINTAINER "username<usereamil>"
ENV PIPURL "https://pypi.tuna.tsinghua.edu.cn/simple"
WORKDIR /data/Project/web_statistics
COPY app.py app.py
RUN pip --no-cache-dir install -i ${PIPURL} --upgrade pip
RUN pip --no-cache-dir install -i ${PIPURL} gunicorn==19.9.0
RUN pip --no-cache-dir install -i ${PIPURL} flask==1.0.2
RUN pip --no-cache-dir install -i ${PIPURL} gevent==1.4.0
CMD gunicorn -c gun.conf app:app
补充:
指定用户运行的模式
gunicorn --workers 3 --bind 0.0.0.0:5000 --user nginx --worker-class gevent main:app
关于工作目录的补充说明:
WORKDIR :以后各层的当前目录就被改为指定的目录,如果目录不存在,WORKDIR会建立目录
-
5)上传项目到对于的目录下用于构建
image.png -
6)进如到对于的web_statistics目录下,然后执行镜像构建
PS : 注意后面有一个点 是表示查询当前Dockerfile文件,因为是在当前目录下,所以直接的 使用 ‘.’
[root@localhost web_statistics]# docker build -t='flask_web_stj' .
- 7)构建完成后,进行相关的镜像容器启动的测试
查看构建的镜像:
docker image ls -a | grep flask
docker images | grep flask_demo
临时启动测试,可以用于查看内部的启动,方便预览服务启动是否报错
关键点: -it --rm
[root@localhost web_statistics]# docker run -it --rm -p 1235:80 flask_web_stj
[2020-11-04 08:58:43 +0000] [1] [INFO] Starting gunicorn 20.0.4
[2020-11-04 08:58:43 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2020-11-04 08:58:43 +0000] [1] [INFO] Using worker: gevent
[2020-11-04 08:58:43 +0000] [8] [INFO] Booting worker with pid: 8
[2020-11-04 08:58:44 +0000] [9] [INFO] Booting worker with pid: 9
[2020-11-04 08:58:44 +0000] [11] [INFO] Booting worker with pid: 11
[2020-11-04 08:58:44 +0000] [12] [INFO] Booting worker with pid: 12
[2020-11-04 08:58:44 +0000] [13] [INFO] Booting worker with pid: 13
补充非临时启动的情况下 ctrl+c强制结束再次启动
docker container start flask_web_stj
-
8)测试访问对于的接口
可以正常访问,只是内部的链接数据库的IP异常导出链接数据库出错
image.png
[2020-11-04 09:00:59,959] ERROR in app: Exception on /env [HEAD]
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/peewee.py", line 3035, in connect
self._state.set_connection(self._connect())
File "/usr/local/lib/python3.6/site-packages/playhouse/pool.py", line 156, in _connect
conn = super(PooledDatabase, self)._connect()
File "/usr/local/lib/python3.6/site-packages/playhouse/postgres_ext.py", line 467, in _connect
conn = super(PostgresqlExtDatabase, self)._connect()
其他补充查看容器进程情况:
docker ps -a | grep flask_app
docker container ls -a | grep flask_app
docker container start flask_app
- 9)正式线上的运行服务的话需要-d
[root@localhost web_statistics]# docker run -id -p 1235:80 --name flask01 flask_web_stj
4cfef408a9471842d9521ca1241f0332e030461879a73678914c563a7599bdf5
[root@localhost web_statistics]# docker run -id -p 1236:80 --name flask02 flask_web_stj
9b8ca21c49e2da0181e003b68bc9de606870d21b559b8583eb3ffe415e297276
[root@localhost web_statistics]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9b8ca21c49e2 flask_web_stj "gunicorn main:app -…" 12 seconds ago Up 11 seconds 0.0.0.0:1236->80/tcp flask02
4cfef408a947 flask_web_stj "gunicorn main:app -…" 20 seconds ago Up 19 seconds 0.0.0.0:1235->80/tcp flask01
cb252d0bb06e newmynginx "/docker-entrypoint.…" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp daorunginx
8bd4c69fec01 191c4017dcdd "docker-entrypoint.s…" 3 hours ago Up 3 hours 0.0.0.0:6379->6379/tcp myredis
[root@localhost web_statistics]#
上面启动了两个服务
0.0.0.0:1235->80/tcp flask01
0.0.0.0:1236->80/tcp flask02
测试两个访问都正常!
- 10)可以打包容器成镜像,然后就随处奔跑!
docker save -o flask_web_stj_image.tar flask_web_stj:1.0
docker load --input flask_web_stj_image.tar
后续补充:
进入到启动的容器里面的查看具体的结构
默认的docker exec -it flask01 /bin/bash 会进入到/data/Project/web_statistics 工作目录下
[root@localhost web_statistics]# docker exec -it flask01 /bin/bash
root@4cfef408a947:/data/Project/web_statistics# ls
Dockerfile __pycache__ gunicorn.conf.py main.py models requirements.txt
root@4cfef408a947:/data/Project/web_statistics#
root@4cfef408a947:/data/Project/web_statistics# ^C
root@4cfef408a947:/data/Project/web_statistics# cd ..
root@4cfef408a947:/data/Project# ll
bash: ll: command not found
root@4cfef408a947:/data/Project# cd ..
root@4cfef408a947:/data# cd ..
root@4cfef408a947:/# ls
bin boot data dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@4cfef408a947:/#
删除镜像的基本流程
1:先暂停容器的运行
2:查看当前相互关联的运行容器是否已经停止(docker ps -a)
3: 删除容器
4:再删除镜像
网友评论