在目录下面新建三个文件:Dockerfile,项目文件,requirements.txt
Dockerfile文件内容格式如下:
# 基于镜像基础
#FROM python:3.6
FROM python:3.6-slim-stretch #有更小的体积
# 维护者信息
MAINTAINER name [email protected]
# 复制当前代码文件到容器中 /app
ADD . /app
# 设置app文件夹是工作目录 /app
WORKDIR /app
#解决Dockers中打印日志不及时的问题
ENV PYTHONUNBUFFERED=0
# 安装所需的包,默认为使用python官方镜像源,安装 比较慢
#RUN pip install -r requirements.txt
#可以修改为清华源
RUN pip install -r requirements.txt - i https://pypi.tuna.tsinghua.edu.cn/simple
# Run test.py when the container launches
CMD ["python", "/app/test/test.py"]
项目文件:直接把完整项目拷贝到docker目录下面
项目依赖:requirements.txt文件
1、进入需要生成文件的目录,执行 pip freeze > requirements.txt ,此方法会包含环境所有的依赖包。
2、pip install pipreqs
进入需要生成文件的目录执行: pipreqs ./ (或者直接 pipreqs D:\test(实际路径))
在此时可能会遇见
UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0x80 in position 776: illegal multibyte sequence
这个错误.
解决方法:指定编码格式 pipreqs ./ --encoding=utf8
# 1.进入docker文件夹
[root@localhost ~]# cd /www/wwwroot/docker
# 2.创建镜像(命令中最后的点不要忘记,这里表示当前目录,也可以写绝对路径)
# -t :指定要创建的目标镜像名
# . :Dockerfile文件所在目录,可以指定Dockerfile 的绝对路径
[root@localhost ~]# docker build -t imagename Dockerfilepath
[root@localhost ~]# docker build -t test .
[root@localhost ~]# docker build -t li /www/wwwroot/docker
# 查看所有镜像
[root@localhost ~]# docker images
# 前台运行一个镜像,生成新的container(运行一个交互式的container容器)
[root@localhost ~]# docker run -it -p 8080:9060 --name ef_nfcs ef_nfcs_img
# 后台运行一个镜像,生成新的container
[root@localhost ~]# docker run -d -p 8080:3000 --name c_name imagename
[root@localhost ~]# docker run -d -p 8080:3000 --name test li
# 宿主机的端口和容器端口的映射关系是:8080:3000(docker中部署的项目端口就是3000)
# 访问:http://宿主机ip:8080/index 即可。
# 映射宿主机的 8080 端口到docker容器的 3000 端口。
# 查看所有的容器(不加-a:查看当前正在运行的容器的详情)
[root@localhost ~]# docker ps -a
# 删除容器:
[root@localhost ~]# docker rm 容器ID
# 进入容器
[root@localhost ~]# docker exec -it 容器ID /bin/bash
[root@localhost ~]# docker exec -it a6e3963fd253 /bin/bash
[root@localhost ~]# docker attach 容器名或容器ID
#查看容器日志,通过docker logs命令可以查看容器的日志。
$ docker logs [OPTIONS] CONTAINER
Options:
--details 显示更多的信息
-f, --follow 跟踪实时日志
--since string 显示自某个timestamp之后的日志,或相对时间,如42m(即42分钟)
--tail string 从日志末尾显示多少行日志, 默认是all
-t, --timestamps 显示时间戳
--until string 显示自某个timestamp之前的日志,或相对时间,如42m(即42分钟)
#查看指定时间后的日志,只显示最后100行:
$ docker logs -f -t --since="2018-02-08" --tail=100 CONTAINER_ID
#查看最近30分钟的日志:
$ docker logs --since 30m CONTAINER_ID
#查看某时间之后的日志:
$ docker logs -t --since="2018-02-08T13:23:37" CONTAINER_ID
#查看某时间段日志:
$ docker logs -t --since="2018-02-08T13:23:37" --until "2018-02-09T12:23:37" CONTAINER_ID
# 退出容器
# 使用Ctrl + P + Q退出容器,就不会中断工程,等于退出容器后,还可访问容器的工程,再进入,也是使用命令:docker attach 容器ID
# ctrl+d 退出容器且关闭, docker ps 查看无
# ctrl+p+q 退出容器但不关闭
# 附加:进入容器中,安装jdk和tomcat的步骤和在linux中安装步骤一致,你可以把容器当成一个linux虚拟机。
进入容器:
docker exec -it 容器ID sh
查看容器中日志文件:
tail -f -n 2000 (文件名)
1、从容器里面拷文件到宿主机?
docker cp 容器名:要拷贝的文件在容器里面的路径 要拷贝到宿主机的相应路径
示例: 假设容器名为testtomcat,要从容器里面拷贝的文件路为:/usr/local/tomcat/webapps/test/js/test.js, 现在要将test.js从容器里面拷到宿主机的/opt路径下面, :在宿主机上面执行命令
docker cp testtomcat:/usr/local/tomcat/webapps/test/js/test.js /opt
2、从宿主机拷文件到容器里面
docker cp 要拷贝的文件路径 容器名:要拷贝到容器里面对应的路径
示例:假设容器名为testtomcat,现在要将宿主机/opt/test.js文件拷贝到容器里面的/usr/local/tomcat/webapps/test/js路径下面,在宿主机上面执行如下命令
docker cp /opt/test.js testtomcat:/usr/local/tomcat/webapps/test/js
3、在这里在记录一个问题,怎么看容器名称?
执行命令:docker ps,,其中NAMES就是容器名了。
4.需要注意的是,不管容器有没有启动,拷贝命令都会生效。
,tar镜像包可以拷贝到其他机器docker环境中加载
docker save test -o test.tar
docker load -i test.tar
docker删除一个镜像必须先删除此镜像中运行的容器,要删除容器,必须 先停止容器,所以删除镜像的步骤为:
docker stop 容器ID
docker rm 容器ID
docker rmi 镜像ID(镜像名)
删除none的镜像,要先删除镜像中的容器。要删除镜像中的容器,必须先停止容器。
$ docker stop $(docker ps -a | grep "Exited" | awk '{print $1 }') #停止容器
1b7067e19d6f
a840f345c423
9d74eff1c4e4
17d361107a21
dd51ead96da7
ad0032609294
95e713ab1bdf
$ docker rm $(docker ps -a | grep "Exited" | awk '{print $1 }') #删除容器
1b7067e19d6f
a840f345c423
9d74eff1c4e4
17d361107a21
dd51ead96da7
ad0032609294
95e713ab1bdf
$ docker rmi $(docker images | grep "none" | awk '{print $3}') #删除镜像
Deleted: sha256:168b258ceea3f5ee9d7f066e04c89c4858f0e337687f18b5939a78aea13ea6c8
Deleted: sha256:d3984014bcbe856f569dcade31ce70aae8cc5ead3806e47ae08229467c9ed3ca
Deleted: sha256:b2c5d34941c646a1962d2acd9ff968708495a82916c33797f5fb3d94de403c6d
Deleted: sha256:5a23f5ad9107bb1111f32d490982e2146cf0811c8b75c7a6cd67ca45fc2f50dd
Deleted: sha256:392d616344b17b0bb7b8ad46cc9a8c6f5ab4be8bd59c3d5973016e8759a1668c
Deleted: sha256:33fbf9c999e8beac51b184a0f2baeaf1a2b99b10c4cc1f654075af42779fb62e
Deleted: sha256:b3535d64be668cd7e3389c4da224ae6e3aaedadff05ed24f428fc83e96c65a03
Deleted: sha256:da47261567b38193ba4894e7c832d9eba78d9cc3a501101ebf5fd7304efef5b9
Deleted: sha256:b81b2578fd4e803fac0bd416e606362ed14432370088eba8bf5c43a4fca8f7ed
Deleted: sha256:6f4b2f9fd5be471ac80c599c9616feaaf3952ce8a68d5d8c26645bfaff7aae4a
Deleted: sha256:480e2b77d27aea6e128db8d3c400f37b74da1b365b0eb663022d7208a9694209
实际开发过程中,我们都是从dockerhub中拉取现有镜像,然后基于此构建自己的镜像,实际上,这样的操作虽然方便,但是带来的问题也很大。比如我们按照以上流程打包后的镜像大小在900MB以上,镜像体积太大,传输和部署都不方便。
选择基础镜像这里有些常用标准,可根据特定情况有所侧重:稳定性 :你希望今天的构建能够为你提供与明天构建相同的基本库,目录结构和基础结构,否则你的应用程序将可能随时崩溃。
安全更新 :你希望基础映像得到良好维护,以便及时获得基本操作系统的安全更新。
最新的依赖关系
:除非你构建一个非常简单的应用程序,否则你可能依赖于操作系统安装的库和应用程序(例如编译器),希望他们版本不要太老。
广泛的依赖关系 :对于某些应用程序,可能需要不太流行的依赖关系 - 包含大量库的基本映像更适合该条原则。
最新的Python :虽然可以通过自己安装Python来解决这个问题,但拥有最新的Python可以节省你的工作量。
小镜像 :在所有条件相同的情况下,拥有较小的Docker镜像比使用更大的Docker镜像更好。
Docker python基础镜像
FROM python:3.6
Alpine Linux ,最初是为小型设备设计的操作系统,因此往往有小包装。
FROM python:3.6-alpine
Debian Stretch
,安装了许多常见软件包。镜像本身很大,但理论上这些软件包是通过其他Docker镜像将使用的公共镜像层安装的,因此整体磁盘使用率会很低。
FROM python:3.6-stretch
Debian Stretch slim
版。这缺少了通用软件包的层,因此镜像本身要小得多,但如果你使用Stretch以外的许多其他Docker镜像,整体磁盘使用量会更高一些。
FROM python:3.6-slim-stretch
查看Python镜像大小,其中alpine 是最小的。
$ docker images | grep python
python 3.6-alpine bb1ccaa5880c 4 days ago 86.7MB
python 3.6-stretch 32260605cf7a 7 days ago 929MB
python 3.6-slim-stretch e0d20fa24f01 7 days ago 143MB
python 3.6 ad01f54ca3a9 2 months ago 923MB
对于想要小镜像的人来说,一个常见的建议是使用Alpine Linux,但使用它会产生一些问题。首先,Alpine的库比我上面提到的其他Linux发行版少得多,因此你可能会缺少库。
Alpine和其他Linux发行版之间也存在重大差异:Alpine使用不同的C库,而不是更常见的glibc。 理论上,musl和glibc 大多是兼容的,但这些差异可能会导致奇怪的问题。
大多数这些问题已经得到解决,但可能发现更多问题。为了减少镜像体积,而导致可能发生的不确定性问题,这是不值得的。因此,这里建议不要使用Alpine。
直接使用 Debian Stretch 毫无意义,因为最新Python的基本映像就是基于此。
截至2019年6月:
python:3.6-slim-stretch 或者 python:3.6-stretch (或者你使用的任何Python版本而不是3.6)是一个比较好的基础镜像,slim变体版本可能会有更小的体积。
如果你需要比 Debian Stretch 提供的更新的库或编译器,你可能想要使用 ubuntu:18.04 ,它比 CentOS 更新。
一旦发布了 Debian Buster ,这个python镜像可能会有是一个更好的选择:它将预装新版本的Python和与 ubuntu:18.04 等效或更新的软件包。
当2020年4月到来时, ubuntu:20.04 将率先拥有最新的软件包
在 Docker 容器里跑 Python 程序时,我们经常遇到通过print函数或者logging模块输出的信息在容器 log 中迷之失踪,过了好久又迷之出现。这是因为 Python 在写 stdout 和 stderr 的时候有缓冲区,导致输出无法实时更新进容器 log。
有如下几种方法解决:
增加环境变量
对于使用print函数打印的内容,在运行容器时增加环境变量PYTHONUNBUFFERED=0就可以解决。
配置 logging 的 stream 参数,stream与filename不能同时存在
import logging
logging.basicConfig(stream=sys.stdout)
这样,通过 logging 模块打印的日志都会直接写到标准输出 stdout。
或者自定义两个StreamHandler分别配置为输出到 stdout 和 stderr,来对不同 log 分别进行输出处理。
以下链接的博文中介绍 了6种压缩Docker镜像的方法,可以参考
https://www.cnblogs.com/sevck/p/13608320.html
以下链接的博文中介绍 了Python Docker 最小化镜像:
https://www.jianshu.com/p/393b0b3ce82a