Data Engineering Zoomcamp:用 Docker 容器化 Python 数据管道(pip 与 uv 双方案实战)

发布时间:2026/11/13 6:20:09

Data Engineering Zoomcamp:用 Docker 容器化 Python 数据管道(pip 与 uv 双方案实战) Data Engineering Zoomcamp用 Docker 容器化 Python 数据管道pip 与 uv 双方案实战【免费下载链接】data-engineering-zoomcampData Engineering Zoomcamp is a free 9-week course on building production-ready data pipelines. Join the course here 项目地址: https://gitcode.com/GitHub_Trending/da/data-engineering-zoomcamp导读本篇指南是 Data Engineering Zoomcamp 2027 模块 01「Containerization and Infrastructure as Code」的第三个单元讲解如何把上一单元中编写的 Python 数据管道脚本容器化。你将学会编写两种Dockerfile基于pip与基于uv掌握docker build/docker run的核心用法与参数传递方式并结合仓库中真实的数据摄取脚本ingest_data.py理解容器化在「CSV → 数据管道 → PostgreSQL」场景下的实际落地方式。读完本文你可以独立把一个 pandas 管道打包成可复用的 Docker 镜像。1. 为什么要把数据管道容器化在前一单元 02-virtual-environment.md 中我们创建了一个pipeline目录并在其中编写了pipeline.py脚本接收命令行参数如日期day用 pandas 构造 DataFrame 并输出为 Parquet 文件。为了管理 pandas、pyarrow 等依赖我们引入了uv虚拟环境来隔离项目依赖。但虚拟环境只解决了「本机依赖隔离」的问题。当管道需要部署到其他机器、云端或 CI 环境时仍然会遇到目标机器上缺少 Python 与依赖库需要重复安装不同环境间 Python 版本、依赖版本不一致导致「在我机器上能跑」每次部署都要手工执行安装步骤难以保证可复现。Docker 的解决方案是把「代码 运行时 依赖」一起打包进一个不可变镜像让管道在任何装有 Docker 的机器上以完全一致的方式运行。这正是本单元 03-dockerizing-pipeline.md 要完成的事。2. 方案一基于 pip 的简单 Dockerfile文档首先给出了一个最直观的容器化方案——直接在基础镜像中用pip安装依赖# base Docker image that we will build on FROM python:3.13.11-slim # set up our image by installing prerequisites; pandas in this case RUN pip install pandas pyarrow # set up the working directory inside the container WORKDIR /app # copy the script to the container. 1st name is source file, 2nd is destination COPY pipeline.py pipeline.py # define what to do first when the container runs # in this example, we will just run the script ENTRYPOINT [python, pipeline.py]2.1 指令逐行解析指令作用说明FROM指定基础镜像这里使用官方python:3.13.11-slimslim 变体体积更小适合作为运行管道的基础RUN在构建期间执行命令pip install pandas pyarrow一次性安装管道所需依赖WORKDIR设置容器内工作目录后续COPY、ENTRYPOINT都相对于该目录执行此处为/appCOPY将文件复制进镜像第一个参数是宿主机源文件第二个参数是容器内目标路径ENTRYPOINT定义容器启动时执行的默认命令此处直接运行python pipeline.py2.2 构建与运行假设pipeline.py与Dockerfile位于同一目录并在该目录下执行构建docker build -t test:pandas .镜像名repository为test标签tag为pandas若省略标签Docker 会默认使用latest命令末尾的.表示构建上下文build context为当前目录。运行容器并传入参数使管道脚本通过sys.argv接收到它docker run -it test:pandas some_number运行后你应看到与直接执行python pipeline.py some_number完全一致的输出——这正是容器化的意义同样的代码、同样的行为。-it表示以交互模式挂接终端便于观察管道日志输出。注意以上说明假定pipeline.py与Dockerfile在同一目录且 Docker 命令也在该目录下执行否则构建上下文将无法找到源文件。2.3 pip 方案的局限pip 方案足够简单但存在两个工程隐患版本不可复现pip install pandas pyarrow每次构建都拉取当时的最新版本依赖漂移会导致镜像内容随时间变化构建慢、缓存差代码与依赖安装混在一起改动一行代码就要重新解析依赖。这正是文档随后引入uv方案的原因。3. 方案二基于 uv 的 Dockerfile推荐uv是前序单元中已经使用的现代 Python 包管理器用 Rust 编写由 02-virtual-environment.md 介绍本单元把它带入容器构建流程# Start with slim Python 3.13 image FROM python:3.13.10-slim # Copy uv binary from official uv image (multi-stage build pattern) COPY --fromghcr.io/astral-sh/uv:latest /uv /bin/ # Set working directory WORKDIR /app # Add virtual environment to PATH so we can use installed packages ENV PATH/app/.venv/bin:$PATH # Copy dependency files first (better layer caching) COPY pyproject.toml uv.lock .python-version ./ # Install dependencies from lock file (ensures reproducible builds) RUN uv sync --locked # Copy application code COPY pipeline.py pipeline.py # Set entry point ENTRYPOINT [uv, run, python, pipeline.py]3.1 与 pip 方案的关键差异COPY --fromghcr.io/astral-sh/uv:latest /uv /bin/直接从官方 uv 镜像把二进制复制进当前镜像属于多阶段构建multi-stage build模式无需在容器内再用pip install uv先复制依赖清单、再复制代码pyproject.toml、uv.lock、.python-version先进入镜像并执行RUN uv sync --locked。由于 Docker 按层缓存只要依赖文件没变这层缓存就能被后续构建复用——改动代码时无需重新解析安装依赖RUN uv sync --locked严格按照锁文件uv.lock安装依赖保证每次构建产出的环境完全一致可复现构建ENV PATH/app/.venv/bin:$PATH把 uv 创建的虚拟环境加入PATH使容器内的python直接解析到虚拟环境中的解释器ENTRYPOINT [uv, run, python, pipeline.py]通过uv run启动脚本它会自动确认虚拟环境已就绪。3.2 为什么依赖清单里要有这三个文件文件作用pyproject.toml项目声明文件记录元数据与直接依赖及其版本约束uv.lock锁定全部依赖含传递依赖的精确版本是可复现构建的基石.python-version声明项目要求的 Python 版本uv 会据此解析解释器在仓库的 pipeline/pyproject.toml 中可以看到真实项目的依赖不止 pandas 与 pyarrow还包括click命令行参数解析、psycopg2-binaryPostgreSQL 驱动、sqlalchemy写库 ORM、tqdm进度条以及 dev 依赖组jupyter、pgcli。这种「依赖清单驱动构建」的方式正是 uv 方案面向生产可维护性的设计。4. 仓库中的真实 Dockerfile从 pipeline.py 到 ingest_data.py文档中的pipeline.py是教学用的最小示例。在课程后续单元中这个管道会演进为真正对接 PostgreSQL 的数据摄取脚本ingest_data.py见 06-ingestion-script.md其容器化 Dockerfile 位于 pipeline/DockerfileFROM python:3.13.11-slim COPY --fromghcr.io/astral-sh/uv:latest /uv /bin/ WORKDIR /code ENV PATH/code/.venv/bin:$PATH COPY pyproject.toml .python-version uv.lock ./ RUN uv sync --locked COPY ingest_data.py . ENTRYPOINT [python, ingest_data.py]4.1 与教学版 Dockerfile 的差异WORKDIR /code替代/app目录命名更贴近「代码运行目录」的语义依赖清单复制与uv sync --locked的顺序保持一致同样利用层缓存COPY ingest_data.py .只复制单个入口脚本镜像更精简入口为python ingest_data.py注意此处未再显式加uv run因为PATH已指向虚拟环境。4.2 从最小示例到生产管道的思路迁移ingest_data.py使用click定义了一组命令行选项--pg-user、--pg-pass、--pg-host、--pg-port、--pg-db、--year、--month、--target-table、--chunksize以 10 万行/块的方式流式读取 NYC 出租车数据并写入 PostgreSQL。容器化后构建与运行方式为cd pipeline docker build -t taxi_ingest:v001 . docker run -it \ --networkpg-network \ taxi_ingest:v001 \ --pg-userroot \ --pg-passroot \ --pg-hostpgdatabase \ --pg-port5432 \ --pg-dbny_taxi \ --target-tableyellow_taxi_trips这里有两个关键点详见 08-dockerizing-ingestion.md--networkpg-network必须放在镜像名之前用于让摄取容器找到另一个网络中的 PostgreSQL 容器--pg-host不再指向localhost而是指向 PostgreSQL 容器的服务名/容器名pgdatabase。5. 容器化管道的完整工作流结合 Docker Compose在实际课程练习中PostgreSQL 与 pgAdmin 往往通过 docker-compose.yaml 一键拉起详见 09-docker-compose.mdservices: pgdatabase: image: postgres:18 environment: POSTGRES_USER: root POSTGRES_PASSWORD: root POSTGRES_DB: ny_taxi volumes: - ny_taxi_postgres_data:/var/lib/postgresql ports: - 5432:5432 pgadmin: image: dpage/pgadmin4 environment: PGADMIN_DEFAULT_EMAIL: adminadmin.com PGADMIN_DEFAULT_PASSWORD: root volumes: - pgadmin_data:/var/lib/pgadmin ports: - 8085:80 volumes: ny_taxi_postgres_data: pgadmin_data:启动服务docker-compose up # 前台运行 docker-compose up -d # 后台detached运行 docker-compose down # 停止并移除容器 docker-compose down -v # 停止并连同数据卷一并移除 docker-compose logs # 查看日志当 PostgreSQL 由 compose 管理时摄取容器需加入 compose 自动创建的网络名称通常形如pipeline_default取决于目录名运行docker network ls docker run -it --rm \ --networkpipeline_default \ taxi_ingest:v001 \ --pg-userroot \ --pg-passroot \ --pg-hostpgdatabase \ --pg-port5432 \ --pg-dbny_taxi \ --target-tableyellow_taxi_trips至此**管道代码Docker 镜像与存储服务compose 网络**被清晰地解耦镜像只管「读数据、写数据」服务编排只负责「把数据库和监控工具跑起来」两者通过 Docker 网络按名称互相发现。6. 总结与实践要点对比维度pip 方案uv 方案依赖管理pip install版本不锁定uv sync --locked锁文件保证可复现构建缓存依赖与代码同层缓存收益低先拷依赖清单再拷代码代码改动命中缓存虚拟环境无显式隔离uv 自动管理.venv并写入PATH适用场景快速原型、演示面向生产、长期维护的管道动手实践建议按以下顺序验证参照 02-virtual-environment.md 编写pipeline.py并用uv初始化项目uv init --python3.13、uv add pandas pyarrow依次使用 pip 与 uv 两个 Dockerfile 构建镜像docker build -t test:pandas ./docker build -t test:uv .对比镜像构建速度与输出用docker run -it test:pandas 10传入参数验证sys.argv传递进阶练习把仓库中的 pipeline/Dockerfile 与 pipeline/ingest_data.py 结合 compose 跑通「下载 → 清洗 → 入 PostgreSQL」的完整链路。容器化的收益在后续所有模块中都会反复体现无论后续是 Spark 批处理、Flink 流处理还是 dbt 转换凡是涉及 Python 依赖的环节都可以复用本文的uv 锁文件 层缓存模式确保可复现、可迁移、可交付。【免费下载链接】data-engineering-zoomcampData Engineering Zoomcamp is a free 9-week course on building production-ready data pipelines. Join the course here 项目地址: https://gitcode.com/GitHub_Trending/da/data-engineering-zoomcamp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/13 6:20:07

SpringBoot+Vue智能健康管理系统设计与实现

1. 项目概述:企业级智能推荐卫生健康系统这个基于SpringBootVueMyBatis的卫生健康管理系统,本质上是一个融合了医疗健康数据管理与智能推荐算法的综合平台。我在实际医疗信息化项目实施中发现,传统健康管理系统最大的痛点在于:它们…

2026/11/8 18:55:54

PICO XR渲染报错renderPassIndex越界解决方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/13 6:17:19

西安汽车维修电工证在哪考不踩坑,别让培训费打水漂

西安汽车维修电工证在哪考不踩坑,别让培训费打水漂 怕考不过白交培训费?你不是一个人。西安汽车维修电工证报名门槛高、流程复杂,很多学员因为不了解流程,要么被坑钱,要么被退学,白白浪费了时间和金钱。本文就从三门峡一位培训机构学员的真实经历出发,…

2026/11/13 6:17:19

有电工证的英语老师怎么报名才能快速上岗找工作

有电工证的英语老师怎么报名才能快速上岗找工作 你可能没想到,一个英语老师手里拿着电工证,反而在求职路上多了个“加分项”,但别误会,这不是什么新奇职业,而是当前市场上部分行业交叉岗位的现实需求。特别是像市政工程、教育机构与技能培训融合的领域,…

2026/11/13 6:17:19

电工证ic照片实操考试考什么 考前押题如何拿高分

电工证ic照片实操考试考什么 考前押题如何拿高分 之前考的证在外省能不能转过来?这个问题我遇到过无数次,很多人因为在外省考的证,担心回老家用不了,结果耽误了工作机会。现在告诉你, 各地市安全生产教育培训中心…

2026/11/13 6:17:19

兰考电工证办理去那里网上查询学历不高怕报不上名

兰考电工证办理去那里网上查询学历不高怕报不上名 学历不高怕报不上名,这是很多想考电工证的人心里的顾虑。其实,特种作业操作证报考并不看学历,只要你年满18周岁,身体健康,具备初中及以上文化程度,就能报名。不过,很多人还是担心自己学历不够,怕被…

2026/11/13 6:17:19

低压电工证考试小技巧通过率揭秘,别让培训费打水漂

低压电工证考试小技巧通过率揭秘,别让培训费打水漂 怕考不过白交培训费?别急,今天咱们就来聊聊低压电工证考试小技巧,揭秘通过率背后的关键点,帮助你一次性通过,别让辛苦交的培训费打了水漂。 低压电工证到底是什么?为什么必须考?…

2026/11/12 20:35:13

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/13 0:01:06

办上海高压电工证良心建议:别被中介坑了,自己看这篇就够了

办上海高压电工证良心建议:别被中介坑了,自己看这篇就够了 你是不是也像我一样,第一次听说“高压电工证”这个名词,就感觉一头雾水?其实很多人都跟我一样,不知道去哪报名、怕被中介坑,结果花了冤枉钱还考不上。今天我就从一个在商丘培训过的学员角度,…

2026/11/13 0:01:06

黎里考电工证在哪里值不值得考

黎里考电工证在哪里值不值得考 之前考的证在外省能不能转过来?这是很多在外地工作、准备回老家发展的朋友最关心的问题。特别是在黎里地区,很多从事电力相关工作的朋友,都面临这样一个难题: 外省的电工证能否在本地使用?值不值得考?…

2026/11/13 0:01:06

毕节哪里考电工证 怎么报名学历不高也能上手

毕节哪里考电工证 怎么报名学历不高也能上手 你是不是也和我一样,学历不高,想着考个电工证,但又担心自己条件不够,怕报不上名?其实不然,只要符合条件,学历不高也能考电工证。今天就来聊聊【毕节哪里考电工证】这个问题,还有怎么报名,让你一步到位不…

2026/11/12 22:10:13

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/12 9:51:42

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑