如果你曾想确保你的应用程序环境的一致性,你很可能知道容器化是最佳选择。要对一个Python应用程序进行容器化,首先让我们设置一个简单的文件结构:
python_docker
|- src
| |- app.py
|- Dockerfile
|- requirements.txt
现在添加一个简单的Python应用程序:
import time
if __name__ == '__main__':
while True:
print('来自容器内部的问候', flush=True)
time.sleep(1)
初学者注意: 你可能会想知道为什么在打印函数的末尾添加了
flush
。在 Docker 容器中运行时,标准输出(stdout)通常连接到一个管道,而不是直接的终端。Python 为了提高效率,会对输出进行缓冲,仅在缓冲区满、程序结束或明确请求 flush 时发送数据。如果没有flush
,日志可能会在容器停止时一次性出现,而不是每秒出现一次。当在系统终端中运行相同的应用程序时,你不需要flush
,因为 stdout 切换到行缓冲模式,当遇到换行符时会自动刷新缓冲区。
有了这些,接下来是编写 Dockerfile:
# 使用官方 Python 运行时作为父镜像
FROM python:3.9-slim
# 设置容器中的工作目录
WORKDIR /app
# 将当前目录内容复制到容器的 /app 目录
COPY . /app
# 安装 requirements.txt 中指定的任何所需包
RUN pip install --no-cache-dir -r requirements.txt
# 当容器启动时运行 app.py
CMD ["python", "app.py"]
当 Dockerfile 准备好后,您可以通过运行以下命令来构建 Docker 镜像:
docker build -t python_docker_image .
如果您不想在每次调用 docker
命令时都使用 sudo
,您可以通过运行 sudo chmod 666 /var/run/docker.sock
来更改其中一个 docker 文件的权限。
初学者注意: 请记住,更改 /var/run/docker.sock 的权限可能会带来安全方面的后果,因此在生产环境中执行此操作之前请三思而后行!
成功构建后,您可以通过运行以下命令来检查镜像列表:
docker images
这将显示一个类似于以下的表格:
REPOSITORY TAG IMAGE ID CREATED SIZE
python_docker_image latest e132d245100b 大约一分钟前 132MB
要从您的镜像创建一个容器,请使用命令:
docker run python_docker_image
这是该命令的最简单形式,但您很可能希望通过以下选项和标志来扩展它:
--rm
– 停止后删除容器--name
– 允许您为容器分配一个自定义名称(否则 Docker 将选择一个随机名称)-d
– 将进程从当前终端分离,这实际上使容器在后台运行。
最终我们的命令如下所示:
docker run --rm --name my_python_application -d python_docker_image
现在您可以使用 docker ps
命令检查当前运行的容器列表。如果一切正常,您应该看到如下输出:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
005a84629e1b python_docker_image "python src/app.py" 3 seconds ago Up 2 seconds my_python_application
最后,让我们查看应用程序的日志。运行 docker logs my_python_application
并检查是否看到以下输出:
Hello from the inside of the container
Hello from the inside of the container
Hello from the inside of the container
如果是的话,恭喜你,成功将一个 Python 应用程序容器化了。
初学者注意: 如果你这样离开容器,它将会在后台永远运行。要停止应用程序,请运行 docker container stop my_python_application
命令。
高级用户注意: 如果你需要更深入地查看你的容器,可以使用命令 docker container exec -it my_python_application /bin/bash
进入容器的 shell 终端。你也可以在容器启动时使用命令 docker run -it python_docker_image /bin/bash
来实现这一点。