实用版——python项目打包成docker容器镜像
摘要:本文介绍两种将Python项目打包为Docker镜像的方法。简单版(适合运维)直接导入项目文件到基础Python镜像,依赖需研发自行安装;复杂版(适合研发)通过requirements.txt自动安装依赖,但构建失败会产生缓存占用空间。文章详细说明了两种方法的Dockerfile编写、镜像构建步骤,并提供了清理Docker构建缓存的多种命令,包括危险但彻底的一键清理方式。最后指出可通过检查/
#!/bin/bash
简单版:(一次成功,后续下载对应的软件依赖)
方便运维、麻烦研发!
现有项目如下:

已经压缩成tar包,需要制作成容器镜像
如何操作?
第一步:肯定是构建dockerfile,如下:
FROM python:3.12.4 ##基于什么版本的python,取决于你的环境,可以pip检测一下
LABEL maintainer="laohu" ##命名标签
RUN mkdir -p /prediction_service_revised ##创建容器内的工作目录
COPY Miniconda3-latest-Linux-x86_64.sh /prediction_service_revised ##将自己构建所需要的工具复制到工作目录中
ADD ./prediction_service_revised.tar.gz /prediction_service_revised #将python包导入到容器
WORKDIR /prediction_service_revised ##定义工作目录
CMD ["python"] ##命令使用
第二步,构建镜像
docker build -t prediction_service_revised:v1 .
等待构建,构建完成!
docker images
此方法,构建快,但是完全为基础镜像,任何python所需要的库都没有,需要研发自行下载!

可查看构建缓存(只有镜像占用的位置,这里我删除了,所以不显示!)
docker system df
或者 docker system df -v

通用顺序如下:
1、程序依赖包写入requirements.txt文件
requests
numpy
pillow
tornado
2、编写Dockerfile
# 拉取基础镜像
FROM python:3.12.5
# 设置环境变量
ENV DEBIAN_FRONTEND=noninteractive
# 把当前所有文件拷贝到容器的/code文件夹里,并根据requirements.txt安装python依赖包
RUN mkdir /code \
&& apt-get update -y \
&& apt-get install -y libsm6 \
&& pip install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple
COPY . /code
RUN pip install -r /code/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
WORKDIR /code
# 设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' >/etc/timezone
CMD ["python3","http_server.py"]
3、执行命令
Docker允许通过外部访问容器或者容器之间互联的方式来提供网络服务。
容器启动之后,容器中可以运行一些网络应用,通过-p或-P参数来指定端口映射。
宿主机的一个端口只能映射到容器内部的某一个端口上,比如:8080->80之后,就不能8080->81
容器内部的某个端口可以被宿主机的多个端口映射,比如:8080->80,8090->80,8099->80
启动容器时,选择一个端口映射到容器内部开放端口上
-p 小写p表示docker会选择一个具体的宿主机端口映射到容器内部开放的网络端口上。
-P 大写P表示docker会随机选择一个宿主机端口映射到容器内部开放的网络端口上。
# 制作镜像
sudo docker build -t python_fun:test .
# 运行镜像,docker容器的端口映射到宿主机的端口
sudo docker run -ti --name http_server -p 8980:8980 python_fun:test
4、docker-compose启动
docker-compose.yml.service,通过配置docker环境变量的方式,传入一些参数设置
version: '3.1'
services:
python_mini_service:
build:
context: .
dockerfile: Dockerfile.cpu
image: python3.12_cpu:v1
restart: always
working_dir: /root/projects
ports:
- 8980:8980
environment:
- TZ=Asia/Shanghai
- host-ip=192.168.33.198
- host-port=8980
代码中相应的run_cfg.py也要做修改
import os
http_config = {
# 本地服务 ip 线上的话需要写具体部署http服务的ip
'server_host': os.environ['host-ip'],
# 服务名
'app_name': 'video-python',
# 端口
'port': int(os.environ['host-port'])
}
5、运行
docker-compose -f docker-compose.yml.service up -d
例:
[root@devops ~]# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos The official build of CentOS. 5421 [OK]
ansible/centos7-ansible Ansible on Centos7 121 [OK]
jdeathe/centos-ssh CentOS-6 6.10 x86_64 / CentOS-7 7.6.1810 x86… 110 [OK]
consol/centos-xfce-vnc Centos container with "headless" VNC session… 91 [OK]
imagine10255/centos6-lnmp-php56 centos6-lnmp-php56 57 [OK]
tutum/centos Simple CentOS docker image with SSH access 44
centos/postgresql-96-centos7 PostgreSQL is an advanced Object-Relational … 37
kinogmt/centos-ssh CentOS with SSH 27 [OK]
centos/php-56-centos7 Platform for building and running PHP 5.6 ap… 20
guyton/centos6 From official centos6 container with full up… 10 [OK]
pivotaldata/centos-gpdb-dev CentOS image for GPDB development. Tag names… 10
drecom/centos-ruby centos ruby 6 [OK]
pivotaldata/centos Base centos, freshened up a little with a Do… 3
darksheer/centos Base Centos Image -- Updated hourly 3 [OK]
miko2u/centos6 CentOS6 日本語環境 2 [OK]
pivotaldata/centos-mingw Using the mingw toolchain to cross-compile t… 2
ovirtguestagent/centos7-atomic The oVirt Guest Agent for Centos 7 Atomic Ho… 2
pivotaldata/centos-gcc-toolchain CentOS with a toolchain, but unaffiliated wi… 1
mcnaughton/centos-base centos base image 1 [OK]
blacklabelops/centos CentOS Base Image! Built and Updates Daily! 1 [OK]
indigo/centos-maven Vanilla CentOS 7 with Oracle Java Developmen… 1 [OK]
smartentry/centos centos with smartentry 0 [OK]
pivotaldata/centos7-dev CentosOS 7 image for GPDB development 0
pivotaldata/centos6.8-dev CentosOS 6.8 image for GPDB development 0
fortinj66/centos7-s2i-nodejs based off of ryanj/centos7-s2i-nodejs. Bigg… 0
[root@devops ~]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
8ba884070f61: Pull complete
Digest: sha256:b5e66c4651870a1ad435cd75922fe2cb943c9e973a9673822d1414824a1d0475
Status: Downloaded newer image for centos:latest
[root@devops ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
portainer/portainer latest da2759008147 2 weeks ago 75.4MB
centos latest 9f38484d220f 3 months ago 202MB
[root@devops ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
fc7181108d40: Pull complete
c4277fc40ec2: Pull complete
780053e98559: Pull complete
Digest: sha256:bdbf36b7f1f77ffe7bd2a32e59235dff6ecf131e3b6b5b96061c652f30685f3a
Status: Downloaded newer image for nginx:latest
##这里我们登陆一下的私有仓库
[root@devops ~]# docker login --username=抛物线linux registry.cn-beijing.aliyuncs.com
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
##然后开启运行一个镜像
[root@devops ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 719cd2e3ed04 12 days ago 109MB
portainer/portainer latest da2759008147 2 weeks ago 75.4MB
centos latest 9f38484d220f 3 months ago 202MB
[root@devops ~]# docker run -itd --name centospython --net=bridge centos /bin/bash
16f0c37e1fdd4ba18ff346b3a8444da1ff64cbff236417bf736760c9fccc182f
[root@devops ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
16f0c37e1fdd centos "/bin/bash" 3 seconds ago Up 2 seconds centospython
[root@devops ~]# docker exec -it 16f0c37e1fdd /bin/bash
[root@16f0c37e1fdd /]# ip a
[root@16f0c37e1fdd /]# yum search ifconfig
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
* base: mirror.bit.edu.cn
* extras: mirror.bit.edu.cn
* updates: mirror.bit.edu.cn
base | 3.6 kB 00:00:00
extras | 3.4 kB 00:00:00
updates | 3.4 kB 00:00:00
(1/4): base/7/x86_64/group_gz | 166 kB 00:00:01
(2/4): extras/7/x86_64/primary_db | 205 kB 00:00:01
(3/4): base/7/x86_64/primary_db | 6.0 MB 00:00:01
(4/4): updates/7/x86_64/primary_db | 6.4 MB 00:00:24
========================================================== Matched: ifconfig ==========================================================
net-tools.x86_64 : Basic networking tools
[root@16f0c37e1fdd /]# yum install -y net-tools.x86_64
Loaded plugins: fastestmirror, ovl
Loading mirror speeds from cached hostfile
* base: mirror.bit.edu.cn
* extras: mirror.bit.edu.cn
* updates: mirror.bit.edu.cn
Resolving Dependencies
--> Running transaction check
---> Package net-tools.x86_64 0:2.0-0.24.20131004git.el7 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
=======================================================================================================================================
Package Arch Version Repository Size
=======================================================================================================================================
Installing:
net-tools x86_64 2.0-0.24.20131004git.el7 base 306 k
Transaction Summary
=======================================================================================================================================
Install 1 Package
Total download size: 306 k
Installed size: 918 k
Downloading packages:
warning: /var/cache/yum/x86_64/7/base/packages/net-tools-2.0-0.24.20131004git.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY
Public key for net-tools-2.0-0.24.20131004git.el7.x86_64.rpm is not installed
net-tools-2.0-0.24.20131004git.el7.x86_64.rpm | 306 kB 00:00:00
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Importing GPG key 0xF4A80EB5:
Userid : "CentOS-7 Key (CentOS 7 Official Signing Key) <security@centos.org>"
Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5
Package : centos-release-7-6.1810.2.el7.centos.x86_64 (@CentOS)
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : net-tools-2.0-0.24.20131004git.el7.x86_64 1/1
Verifying : net-tools-2.0-0.24.20131004git.el7.x86_64 1/1
Installed:
net-tools.x86_64 0:2.0-0.24.20131004git.el7
Complete!
[root@16f0c37e1fdd /]#
[root@16f0c37e1fdd /]#
[root@16f0c37e1fdd /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
RX packets 4292 bytes 13959608 (13.3 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 3860 bytes 211812 (206.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@16f0c37e1fdd /]# python
Python 2.7.5 (default, Oct 30 2018, 23:45:53)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
##然后把我们的该容器打包成镜像
[root@devops ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
16f0c37e1fdd centos "/bin/bash" 21 minutes ago Up 21 minutes centospython
[root@devops ~]# docker export 16f0c37e1fdd > python3tar
[root@devops ~]# ls
anaconda-ks.cfg initial-setup-ks.cfg python3tar
[root@devops ~]# mv python3tar /opt/
[root@devops ~]# cat /opt/python3tar | docker import - python3:test
sha256:6121878c45f969eaef26aef5b193029ae396c53714ead35d19e67b122975cf31
[root@devops ~]# docker images | grep python3
python3 test 6121878c45f9 9 seconds ago 284MB
[root@devops ~]#
##这里由于compose中使用的是python2.7 的镜像 那么我们就重新tag 一下
[root@devops ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python3 test 6121878c45f9 53 seconds ago 284MB
python 2.7 693b5f09c0ee 7 minutes ago 307MB
nginx latest 719cd2e3ed04 12 days ago 109MB
portainer/portainer latest da2759008147 2 weeks ago 75.4MB
centos latest 9f38484d220f 3 months ago 202MB
[root@devops ~]# docker tag python3:test python2.7:test
[root@devops ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
python2.7 test 6121878c45f9 About a minute ago 284MB
python3 test 6121878c45f9 About a minute ago 284MB
python 2.7 693b5f09c0ee 8 minutes ago 307MB
nginx latest 719cd2e3ed04 12 days ago 109MB
portainer/portainer latest da2759008147 2 weeks ago 75.4MB
centos latest 9f38484d220f 3 months ago 202MB
[root@devops ~]#
复杂版:(构建多次,依赖包下载依赖于选择的库地址,构建缓存较大)
方便研发、麻烦运维!
依旧是之前的项目
第一步:在工作目录终端,使用pip freeze > requirements.txt 命令将项目依赖库进行导出。
(生成需要的依赖库环境包)
命令执行完成后会生成一个叫requirements.txt的文件
pip freeze > requirements.txt
这些依赖包并不能一次性下载完成,构建镜像时,若构建不成功,则会产生构建缓存,占空间!
第二步:构建dockerfile
FROM python:3.12.4
LABEL maintainer="laohu'
RUN apt-get update && apt-get install -y build-essential
RUN mkdir -p /prediction_service_revised
COPY requirements.txt /prediction_service_revised
ADD ./prediction_service_revised.tar.gz /prediction_service_revised
WORKDIR /prediction_service_revised
RUN pip install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/
RUN pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
CMD ["python"]

第三步,构建镜像
docker build -t prediction_service_revised:v1 .
出现下列之类的问题,就是下载对应的pip依赖库失败,需要根据问题响应,依次解决依赖库问题,直至构建成功!

例:

构建成功:
docker build -t prediction_service_revised:v1 .

构建缓存如下:
docker system df
或者 docker system df -v

那么问题来了,如何清理这些缓存?
镜像分层与缓存原理
Docker 在构建镜像时会逐条执行 Dockerfile 中的指令,每条指令生成一个新的镜像层。若某一层未发生变化,Docker 会复用该层及其之前的缓存,仅重新构建后续变更的层。这种机制极大提升了构建效率。
- ADD、COPY、RUN 等指令都会创建新层
- 缓存匹配基于内容哈希,而非指令文本
- 一旦某层缓存失效,其后的所有层均需重建
Dockerfile 编写优化建议
为最大化利用缓存,应将变动较少的操作前置。例如,先安装依赖再复制源码:
# 先复制并安装依赖(变化少)
COPY package.json /app/package.json
WORKDIR /app
RUN npm install
# 再复制应用代码(频繁变更)
COPY . /app
上述写法确保在源码修改时,node_modules 的安装步骤仍可命中缓存。
缓存查看与清理
可通过以下命令管理镜像缓存:
# 查看构建缓存
docker builder prune --dry-run
# 清理未使用缓存
docker builder prune -f
# 删除未使用的构建缓存
docker builder prune
# 更彻底,删除所有缓存,包括可能还会用到的
docker builder prune --all
docker builder prune --all 清理构建缓存
docker container prune 清理没用的容器
docker image prune 清理悬空镜像
docker volume prune 清理没用的卷
docker network prune 清理没用的网络
docker system prune -a --volumes 一键清理
graph TD A[基础镜像层] --> B[依赖安装层] B --> C[配置文件层] C --> D[应用代码层] D --> E[启动脚本层]
一键清理
如果你只是做实验,对数据不敏感,可以直接:
docker system prune:一键清理闲置资源
docker system prune -a --volumes
# 基础用法:清理未使用的资源
docker system prune
# 强制执行且不提示
docker system prune -f
# 清理所有镜像而不仅是悬空镜像
docker system prune --all
这会删除所有:
已停止的容器
没有 tag 的镜像
没用的卷
没用的网络
构建缓存
空间释放得最快,但要注意数据卷和缓存一旦清理,就无法恢复。
资源类型与影响范围
该命令通过 Docker 的引用计数机制判断资源是否“闲置”。只有当容器、镜像或网络未被任何运行实体引用时,才会被纳入清理队列。这一设计确保了运行中服务的完整性。
- 悬空镜像:无标签且未被容器引用的中间层镜像
- 已停止容器:处于非运行状态但保留元数据的实例
- 未使用网络:未连接任何容器的自定义网络
- 构建缓存:镜像构建过程中产生的临时数据层
docker image prune:精准清除悬空镜像
在长期使用Docker的过程中,频繁构建和更新镜像会产生大量无用的中间层镜像,尤其是“悬空镜像”(dangling images)。这些镜像是指没有标签且不被任何容器引用的孤立镜像层,占用宝贵磁盘空间。
docker container prune --filter "until=72h"
执行精准清理
清理所有悬空镜像的标准命令为:
docker image prune
执行后会提示释放空间量,并询问是否继续。添加 -f 参数可跳过确认步骤。
- 安全性高:仅删除无引用的镜像,不影响正在运行的容器
- 资源优化:定期执行可显著减少磁盘占用
docker container prune:高效回收停止容器
定期清理已停止的容器是维护Docker环境整洁的关键操作。`docker container prune`命令可自动删除所有处于停止状态的容器,释放磁盘空间并提升系统性能。
docker container prune --filter "until=72h"
该命令将清理超过72小时前创建的停止容器。`--filter`支持基于时间的过滤条件,实现精细化控制。
- 安全性:执行前会提示确认,避免误删
- 自动化集成:可结合cron定时任务实现周期性清理
- 资源释放:同时清理关联的匿名卷(需配合额外配置)
docker volume prune:安全清理无主数据卷
在长期运行的Docker环境中,大量未被容器引用的数据卷会占用磁盘空间并增加管理复杂度。`docker volume prune` 命令用于清理“无主”(dangling)数据卷,即那些未被任何容器使用的孤立卷。
##基本使用语法
docker volume prune [OPTIONS]
##该命令会提示确认操作以防止误删。添加 -f 或 --force 参数可跳过确认:
docker volume prune -f
此操作仅删除标记为“dangling”的卷,默认不触及仍在使用的卷或被显式保留的数据。
过滤与批量管理
支持通过标签筛选待清理的卷:
docker volume prune --filter "label=unused"
参数 --filter 可结合 label、until 等条件实现精细化控制,提升运维安全性。
- 清理前建议备份关键数据卷
- 生产环境应结合监控工具评估空间占用趋势
- 定期执行可纳入自动化运维流程
docker builder prune:彻底清除构建缓存
在长期使用Docker进行镜像构建的过程中,系统会积累大量中间层和元数据作为构建缓存,这些内容虽能加速后续构建,但也会占用可观的磁盘空间。
docker builder prune
该命令用于删除所有未被使用的构建缓存。执行后可显著释放磁盘空间,尤其适用于开发周期较长、频繁构建镜像的场景
参数说明与扩展操作
- -f 或 --force:跳过确认提示,直接执行清理;
- --filter until=24h:仅清除超过24小时的构建缓存;
- docker builder prune -a:清除所有构建缓存,包括正在被引用的缓存。
定期运行该命令有助于维护Docker环境的整洁性,提升系统资源利用率。
更深入的检查
有时候你清理完,空间还是很大,可以直接查看 /var/lib/docker 下哪些目录占用:
sudo du -h --max-depth=1 /var/lib/docker | sort -h
常见大户:
overlay2/:镜像和容器的文件系统
volumes/:卷的数据
buildkit/:构建缓存
如果 build kit 特别大,就说明问题出在构建缓存。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐




所有评论(0)