百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

Docker系列四DockerFile打造Python镜像

off999 2024-10-14 12:05 16 浏览 0 评论

前言

起因是在更新博客的时候,发现可以用更优雅的方式来实现原有的目的,所以重新整理后,将原文改成了了两篇,都收录在了该系列中。

构建Docker镜像,简单来说分为以下两种:

  • 拉取CentOS的操作系统镜像并生成容器,然后在里面安装各种需要的环境,诸如SSH、Python等。好处就是容器内东西够多,几乎就是又一台服务器,想怎么玩都行。坏处就是吃机子服务器的性能,以我之前的某次作死为例,光镜像文件就得四个G,哪怕是备份文件也得七百兆起步。/捂脸
  • 直接拉取Python镜像,简单粗暴,当然,也是需要自己手动安装各种环境的。好处就是容器偏小,备份和恢复起来较为方便。

我接下来会介绍如何将Python项目使用DockerFile创建成为镜像,此时又根据项目的复杂程度,分为单文件和多文件的两种情况。

运行一次性的python脚本

首先编写一个基础脚本test.py

#!/usr/bin/python
import sys
print(sys.version)
print("Hello, World!")

将脚本test.py放入指定的目录/home/keen/docker/python3.7,运行得到结果后,再删除镜像。

export Temp=python-temp
# 运行容器
docker run \
    --name $Temp \
    -v /home/keen/docker/python3.7:/usr/src/myapp \
    -v /etc/localtime:/etc/localtime:ro \
    -w /usr/src/myapp \
    python:3.7-slim-buster \
    python3 test.py
#删除并销毁容器
docker stop $Temp && docker rm $Temp

但是有前提,必须这个脚本所需要的环境是存在于镜像中的,否则在里面运行会报错的。但是一般来说,官方镜像里面很难保证会有我们编写代码的所有依赖,所以必须要考虑在容器中新增指定依赖。但是总不能每次新启动容器就要重新下一遍依赖吧。

易经上说,穷则变,变则通,通则久。在这里不敢说长久能用,但是努把劲儿,至少得不穷了吧?

单文件创建镜像

适用于单文件创建镜像,一般是新手练手用,或者是功能真的很简单,只需要一个文件就能实现所有功能。

项目文件路径

任意路径建立一个文件夹,此时文件夹名称可以随意起名,我这里做例子起名为test1,跟多文件创建镜像的文件夹分开。

接下来使用命令创建文件夹和文件。其中keen_test1.py是我们的脚本文件,requirements.txt则是依赖和依赖的版本,Dockerfile指定了生成镜像的配置和运行命令。

# 创建文件夹
mkdir -p /home/keen/docker/test1/
# 生成脚本文件
touch /home/keen/docker/test1/keen_test1.py
# 生成依赖文件
touch /home/keen/docker/test1/requirements.txt
# 生成Dockerfile文件
touch /home/keen/docker/test1/Dockerfile

编写脚本文件

编写一个基础脚本keen_test.py,假设会需要引用第三方依赖,且会将计算结果保存到容器的绝对路径/out/中。

vim /home/keen/docker/test1/keen_test.py

脚本内容如下。

#!/usr/bin/python
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-10, 10, 0.01)
y = x**2
plt.plot(x, y)
# 将图片保存到容器的绝对路径/out/中
plt.savefig("/out/b.png") 
# 将变量保存到文件
log = open("/out/a.txt",mode="a",encoding="utf-8")
print(x,file = log)
print(y,file = log)
log.close()

编写依赖文件

这个样例简单么,所以手动编写requirements.txt文件。

vim /home/keen/docker/test1/requirements.txt

依赖内容如下。

numpy==1.21.3
matplotlib==3.4.3  

编写Dockerfile文件

编写Dockerfile文件新建镜像,是需要一个镜像作为基础,然后基于此继续构建新容器。比如此次我就是基于python:3.7的镜像来搭建新镜像,但是即使本地没有这个镜像也不用提前拉取,因为docker会自动拉取的。

vim /home/keen/docker/test1/Dockerfile

文件内容如下。

# syntax=docker/dockerfile:1
# 第一行是解析器指令,始终用版本1语法的最新版本
#基础镜像
FROM python:3.7-slim-buster
# 设置工作目录文件夹
WORKDIR /code
# 复制依赖文件
COPY requirements.txt requirements.txt
# 安装依赖
RUN pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
# 复制其他的脚本文件
COPY . .
#当启动容器时候,执行change_step.py程序
CMD ["python", "keen_test.py"]
  • # syntax=docker/dockerfile:1:别看第一个字符是#就以为他是注释,也可能是解释器指令,意义是使用dockerfile版本1的语法来运行当前脚本
  • FROM 镜像名称:版本号 :指明基础镜像
  • WORKDIR:指明工作目录
  • COPY :将宿主机的文件复制到镜像中
  • RUN :运行后面的命令,实现将安装依赖。
  • CMD:这是将镜像打包完并且生成镜像成功后才会运行的命令。

生成镜像

生成docker镜像,其中--tag会指明镜像名称和版本号。

docker build \
 --tag keen-dockerfiletest:1.0.3 \
 /home/keen/docker/test1

用镜像生成容器

创建并且运行容器,在当前目录新建out文件夹,并且将之映射成为容器的out文件夹。

docker run \
    -v ${PWD}/out:/out \
    keen-dockerfiletest:1.0.3

项目级创建Python镜像

这个则是部署Python项目的时候,用的多些。其实与上面相比,只不过是项目文件会出现层级,在Dockerfile里面要特别地指明添加哪些项目中的哪些内容。

项目文件路径

我这里做例子起名为test2,跟单文件创建镜像的文件夹分开。

接下来使用命令创建文件夹和文件。其中branch1下面的__init__.py是为了把这个文件夹声明成为包。

# 创建文件夹
mkdir -p /home/keen/docker/test2/
# 创建文件夹,并声明为包
mkdir -p /home/keen/docker/test2/branch1/
touch /home/keen/docker/test2/branch1/__init__.py
# 生成脚本文件
touch /home/keen/docker/test2/branch1/keen_test1.py
touch /home/keen/docker/test2/keen_test2.py
touch /home/keen/docker/test2/keen_test3.py
# 生成依赖文件
touch /home/keen/docker/test2/requirements.txt
# 生成Dockerfile文件
touch /home/keen/docker/test2/Dockerfile

编写脚本文件

总共要写三个脚本文件,第一个脚本文件存在一个方法,方法体是写信息进入TXT文件;第二个脚本文件是调用第三方库计算并生成图片,并且调用第一个脚本的方法;第三个文件是多余的,不应该被引入到镜像中的文件。

vim /home/keen/docker/test2/branch1/keen_test1.py
vim /home/keen/docker/test2/keen_test2.py

脚本文件keen_test1内容如下。

#!/usr/bin/python
class Keen:
    def keen_say(self):
        log = open("/out/a.txt",mode="a",encoding="utf-8")
        print("keen_test1",file = log)
        log.close()

脚本文件keen_test2内容如下。

#!/usr/bin/python
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-10, 10, 0.01)
y = x**2
plt.plot(x, y)
# 将图片保存到容器的绝对路径/out/中
plt.savefig("/out/b.png") 
# 查看文件和文件夹
import os
print(os.listdir())
# 调用方法
from branch1.keen_test1 import Keen
p = Keen()
p.keen_say()

脚本文件keen_test3没有内容,但是生成的容器里面不应该有这个文件

编写依赖文件

这个样例简单么,所以手动编写requirements.txt文件。

vim /home/keen/docker/test2/requirements.txt

依赖内容:

numpy==1.21.3
matplotlib==3.4.3  

编写Dockerfile文件

编写Dockerfile文件新建镜像,是需要一个镜像作为基础,然后基于此继续构建新容器。比如此次我就是基于python:3.7的镜像来搭建新镜像,但是即使本地没有这个镜像也不用提前拉取,因为docker会自动拉取的。

vim /home/keen/docker/test2/Dockerfile

文件内容:

# syntax=docker/dockerfile:1
# 第一行是解析器指令,始终用版本1语法的最新版本
#基础镜像
FROM python:3.7-slim-buster
# 设置工作目录文件夹
WORKDIR /code
# 复制依赖文件
COPY requirements.txt requirements.txt
# 安装依赖
RUN pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
#将文件添加到文件夹中,一个一个复制其实也可以的
ADD ./branch1/keen_test1.py /code/branch1/
ADD ./branch1/__init__.py  /code/branch1/
ADD ./keen_test2.py /code/
#当启动容器时候,执行change_step.py程序
CMD ["python", "keen_test2.py"]
  • ADD:将指定的文件复制到镜像的指定目录中

生成镜像

生成docker镜像,其中--tag会指明镜像名称和版本号。

docker build \
 --tag keen-dockerfiletest:1.0.5 \
 /home/keen/docker/test2

用镜像生成容器

创建并且运行容器,在当前目录新建out文件夹,并且将之映射成为容器的out文件夹。

docker run \
 -it \
    -v ${PWD}/out:/out \
    keen-dockerfiletest:1.0.5

感谢

感谢现在的好奇,为了能成为更好的自己。

用DockerFile生成python镜像

相关推荐

面试官:来,讲一下枚举类型在开发时中实际应用场景!

一.基本介绍枚举是JDK1.5新增的数据类型,使用枚举我们可以很好的描述一些特定的业务场景,比如一年中的春、夏、秋、冬,还有每周的周一到周天,还有各种颜色,以及可以用它来描述一些状态信息,比如错...

一日一技:11个基本Python技巧和窍门

1.两个数字的交换.x,y=10,20print(x,y)x,y=y,xprint(x,y)输出:102020102.Python字符串取反a="Ge...

Python Enum 技巧,让代码更简洁、更安全、更易维护

如果你是一名Python开发人员,你很可能使用过enum.Enum来创建可读性和可维护性代码。今天发现一个强大的技巧,可以让Enum的境界更进一层,这个技巧不仅能提高可读性,还能以最小的代价增...

Python元组编程指导教程(python元组的概念)

1.元组基础概念1.1什么是元组元组(Tuple)是Python中一种不可变的序列类型,用于存储多个有序的元素。元组与列表(list)类似,但元组一旦创建就不能修改(不可变),这使得元组在某些场景...

你可能不知道的实用 Python 功能(python有哪些用)

1.超越文件处理的内容管理器大多数开发人员都熟悉使用with语句进行文件操作:withopen('file.txt','r')asfile:co...

Python 2至3.13新特性总结(python 3.10新特性)

以下是Python2到Python3.13的主要新特性总结,按版本分类整理:Python2到Python3的重大变化Python3是一个不向后兼容的版本,主要改进包括:pri...

Python中for循环访问索引值的方法

技术背景在Python编程中,我们经常需要在循环中访问元素的索引值。例如,在处理列表、元组等可迭代对象时,除了要获取元素本身,还需要知道元素的位置。Python提供了多种方式来实现这一需求,下面将详细...

Python enumerate核心应用解析:索引遍历的高效实践方案

喜欢的条友记得关注、点赞、转发、收藏,你们的支持就是我最大的动力源泉。根据GitHub代码分析统计,使用enumerate替代range(len())写法可减少38%的索引错误概率。本文通过12个生产...

Python入门到脱坑经典案例—列表去重

列表去重是Python编程中常见的操作,下面我将介绍多种实现列表去重的方法,从基础到进阶,帮助初学者全面掌握这一技能。方法一:使用集合(set)去重(最简单)pythondefremove_dupl...

Python枚举类工程实践:常量管理的标准化解决方案

本文通过7个生产案例,系统解析枚举类在工程实践中的应用,覆盖状态管理、配置选项、错误代码等场景,适用于Web服务开发、自动化测试及系统集成领域。一、基础概念与语法演进1.1传统常量与枚举类对比#传...

让Python枚举更强大!教你玩转Enum扩展

为什么你需要关注Enum?在日常开发中,你是否经常遇到这样的代码?ifstatus==1:print("开始处理")elifstatus==2:pri...

Python枚举(Enum)技巧,你值得了解

枚举(Enum)提供了更清晰、结构化的方式来定义常量。通过为枚举添加行为、自动分配值和存储额外数据,可以提升代码的可读性、可维护性,并与数据库结合使用时,使用字符串代替数字能简化调试和查询。Pytho...

78行Python代码帮你复现微信撤回消息!

来源:悟空智能科技本文约700字,建议阅读5分钟。本文基于python的微信开源库itchat,教你如何收集私聊撤回的信息。[导读]Python曾经对我说:"时日不多,赶紧用Python"。于是看...

登录人人都是产品经理即可获得以下权益

文章介绍如何利用Cursor自动开发Playwright网页自动化脚本,实现从选题、写文、生图的全流程自动化,并将其打包成API供工作流调用,提高工作效率。虽然我前面文章介绍了很多AI工作流,但它们...

Python常用小知识-第二弹(python常用方法总结)

一、Python中使用JsonPath提取字典中的值JsonPath是解析Json字符串用的,如果有一个多层嵌套的复杂字典,想要根据key和下标来批量提取value,这是比较困难的,使用jsonpat...

取消回复欢迎 发表评论: