Day 65:【99天精通Python】Python 操作 Docker - 容器化开发第一步
Day 65:【99天精通Python】Python 操作 Docker - 容器化开发第一步
前言
欢迎来到第65天!
在现代软件开发中,Docker 已经成为了标准配置。
- 环境一致性:不再有 “我本地跑得好好的,怎么服务器上就报错?” 的问题。
- 快速部署:一行命令启动数据库、Redis、Web 服务。
虽然 Docker 通常使用命令行(CLI)操作,但作为 Python 开发者,我们经常需要用代码来控制 Docker(比如自动化测试、CI/CD 流水线、或者做一个简单的容器管理平台)。
Python 提供了官方的 Docker SDK (docker-py),让你能用 Python 代码轻松管理镜像和容器。
本节内容:
- Docker 基础概念回顾
- 安装 Docker SDK
- 镜像管理 (pull, list)
- 容器管理 (run, stop, logs)
- 实战练习:用 Python 一键部署 Redis 和 MySQL
一、Docker 基础回顾
如果你对 Docker 完全陌生,只需记住这三个概念:
- 镜像 (Image):软件的安装包(只读)。
- 容器 (Container):镜像运行起来的实例(进程)。
- 仓库 (Registry):存放镜像的地方(如 Docker Hub)。
二、环境准备
2.1 安装 Docker
请确保你的电脑上已经安装并运行了 Docker Desktop (Windows/Mac) 或 Docker Engine (Linux)。
2.2 安装 Python Docker SDK
pip install docker
2.3 建立连接
import docker
try:
# 自动连接本地 Docker 守护进程
client = docker.from_env()
print("Docker 连接成功!")
print(f"Docker 版本: {client.version()['Version']}")
except docker.errors.DockerException:
print("连接失败,请检查 Docker 是否正在运行。")
三、镜像管理 (Images)
3.1 拉取镜像 (Pull)
print("正在拉取 hello-world 镜像...")
image = client.images.pull("hello-world")
print(f"镜像 ID: {image.id}")
3.2 列出所有镜像 (List)
images = client.images.list()
for img in images:
# tags 可能是列表,也可能为空
print(f"镜像: {img.tags}, ID: {img.short_id}")
四、容器管理 (Containers)
4.1 运行容器 (Run)
# client.containers.run(镜像, 命令, 参数...)
# detach=True: 后台运行
# remove=True: 容器停止后自动删除
container = client.containers.run(
"alpine",
"echo Hello Docker SDK",
detach=True,
remove=True
)
# 获取日志
print(f"容器日志: {container.logs().decode('utf-8')}")
4.2 启动一个 Nginx 服务
# 端口映射: {'容器端口': '主机端口'}
container = client.containers.run(
"nginx:latest",
name="my_nginx",
ports={'80/tcp': 8080},
detach=True
)
print(f"Nginx 已启动,ID: {container.short_id}")
print("请访问 http://localhost:8080")
4.3 停止与删除
# 获取指定容器
try:
c = client.containers.get("my_nginx")
print(f"正在停止容器 {c.name}...")
c.stop()
print("正在删除容器...")
c.remove()
print("清理完成。")
except docker.errors.NotFound:
print("容器不存在。")
五、实战练习:一键部署开发环境
假设你新接手一个项目,需要 Redis 和 MySQL。手动去配太麻烦,我们写个 Python 脚本一键拉起。
import docker
import time
client = docker.from_env()
def start_redis():
print("启动 Redis...")
try:
c = client.containers.run(
"redis:alpine",
name="dev_redis",
ports={'6379/tcp': 6379},
detach=True
)
print(f"Redis 启动成功: {c.short_id}")
except Exception as e:
print(f"Redis 启动失败 (可能已存在): {e}")
def start_mysql():
print("启动 MySQL...")
try:
# MySQL 需要配置环境变量 (Root密码)
c = client.containers.run(
"mysql:5.7",
name="dev_mysql",
ports={'3306/tcp': 3306},
environment=["MYSQL_ROOT_PASSWORD=123456"],
detach=True
)
print(f"MySQL 启动成功: {c.short_id}")
except Exception as e:
print(f"MySQL 启动失败: {e}")
if __name__ == "__main__":
start_redis()
start_mysql()
# 列出当前运行的容器
print("\n--- 当前运行容器 ---")
for c in client.containers.list():
print(f"{c.name} ({c.status}) - {c.image.tags}")
六、Dockerfile 构建镜像
除了管理现有的,我们还可以用 Python 代码来触发 docker build。
假设当前目录下有一个 Dockerfile:
FROM python:3.9-slim
CMD ["python", "-c", "print('Build Success!')"]
构建脚本:
print("开始构建镜像...")
# path: Dockerfile 所在目录
# tag: 镜像名称:版本
image, build_logs = client.images.build(path=".", tag="my_python_app:v1")
for chunk in build_logs:
if 'stream' in chunk:
print(chunk['stream'], end='')
print("\n构建完成!")
七、常见问题
Q1:权限拒绝 (Permission denied)?
在 Linux 上,普通用户默认没有权限访问 Docker 守护进程。
解决:sudo usermod -aG docker $USER,然后重新登录。
Q2:拉取镜像太慢?
配置 Docker 国内镜像加速器(如阿里云、网易云)。这需要在 Docker 配置文件 (daemon.json) 中设置,Python 代码无法直接加速网络。
Q3:containers.list() 为什么看不到停止的容器?
默认只列出运行中的。要看所有的(包括已退出的),使用 client.containers.list(all=True)。
八、小结
关键要点:
- Python 可以完全替代 Docker CLI 命令。
client.containers.run(detach=True)是最常用的启动方式。- 通过代码管理容器,非常适合集成测试和自动化运维脚本。
九、课后作业
- 清理脚本:编写一个脚本,删除所有状态为
Exited(已停止) 的容器,清理磁盘空间。 - 健康检查:编写一个脚本,每隔 10 秒检查一下
dev_redis容器的状态。如果发现它挂了(不在 running 列表里),自动重启它。 - 日志监控:实时读取某个容器的日志流 (类似于
docker logs -f),如果发现日志里出现 “ERROR” 字样,发送一封邮件报警(结合 Day 43)。
下节预告
Day 66:Python 操作 Kubernetes (K8s) - 玩转了单机 Docker,接下来我们要挑战集群!K8s 是容器编排的终极 Boss。明天我们初探 Python K8s 客户端。
系列导航:
- 上一篇:Day 64 - 异步任务队列Celery
- 下一篇:Day 66 - Python操作Kubernetes(待更新)
更多推荐

所有评论(0)