Python Docker
最后修改于 2024 年 1 月 29 日
Python Docker 教程展示了如何为 Python 应用程序使用 Docker。
Docker
Docker 是一个供开发人员和系统管理员使用容器构建、运行和共享应用程序的平台。Docker 促进了应用程序的可移植性和可伸缩性。Docker 提供应用程序隔离,从而消除了许多由库和环境差异引起的问题。它有助于自动化开发和部署。通过预定义的社区镜像,开发人员可以节省时间并改善他们的整体体验。
一个 Docker 镜像 是一个只读模板,其中包含创建 Docker 容器的说明。一个 Docker 容器 是镜像的一个可运行实例。
Docker 镜像存储在仓库中。Docker Hub 是官方 Docker 仓库。Docker Engine 是底层的客户端-服务器技术,它使用 Docker 的组件和服务来构建和运行容器。
一个 Dockerfile 是一个特殊的文件,其中包含构建 Docker 镜像所需的指令。
$ sudo docker --version Docker version 19.03.12, build 48a66213fe
这是我们使用的 Docker 版本。
Python Docker hello 示例
在下面的示例中,我们将创建一个非常简单的 Docker 镜像并运行它。当我们运行镜像时,将执行一个简单的 Python 文件。
#!/usr/bin/python
import sys
print("hello there!")
print(sys.version)
这是将在容器内执行的简单文件。
FROM python:3.8 COPY hello.py /tmp/ CMD ["python", "/tmp/hello.py"]
这些是构建 Docker 镜像的指令。
FROM python:3.8
我们的镜像基于社区的 python:3.8 镜像。
COPY hello.py /tmp/
COPY 指令将 hello.py 文件复制到镜像的 tmp 目录中。
CMD ["python", "/tmp/hello.py"]
CMD 指令启动 Python 程序。
$ sudo docker build -t hello .
我们构建镜像并将其命名为 hello。
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello latest 60251c18f538 5 minutes ago 882MB firstimage latest 319917db1025 5 hours ago 111MB python slim 38cd21c9e1a8 5 days ago 113MB python 3.8 79cc46abd78d 5 days ago 882MB python latest 79cc46abd78d 5 days ago 882MB
我们使用 docker images 命令列出可用的镜像。
$ sudo docker run hello hello there! 3.8.5 (default, Aug 5 2020, 08:22:02) [GCC 8.3.0]
我们运行 hello 镜像。
Python Docker 交互模式
我们可以通过使用 -it 选项以交互模式运行镜像。-it 指示 Docker 分配一个连接到容器 stdin 的伪 TTY;在容器中创建一个交互式 bash shell。
$ sudo docker run -it python3.8:slim bash root@98ece0c01946:/#
我们运行镜像并在容器内获取 bash shell。
root@98ece0c01946:/# python -c "import os; print(os.system('ls -l'))"
total 68
drwxr-xr-x 1 root root 4096 Aug 4 16:25 bin
drwxr-xr-x 2 root root 4096 Jul 10 21:04 boot
drwxr-xr-x 5 root root 360 Aug 19 13:40 dev
drwxr-xr-x 1 root root 4096 Aug 19 13:39 etc
drwxr-xr-x 2 root root 4096 Jul 10 21:04 home
drwxr-xr-x 1 root root 4096 Aug 4 16:25 lib
drwxr-xr-x 2 root root 4096 Aug 3 07:00 lib64
drwxr-xr-x 2 root root 4096 Aug 3 07:00 media
drwxr-xr-x 2 root root 4096 Aug 3 07:00 mnt
drwxr-xr-x 2 root root 4096 Aug 3 07:00 opt
dr-xr-xr-x 345 root root 0 Aug 19 13:40 proc
drwx------ 1 root root 4096 Aug 4 16:18 root
drwxr-xr-x 3 root root 4096 Aug 3 07:00 run
drwxr-xr-x 2 root root 4096 Aug 3 07:00 sbin
drwxr-xr-x 2 root root 4096 Aug 3 07:00 srv
dr-xr-xr-x 13 root root 0 Aug 19 13:40 sys
drwxrwxrwt 1 root root 4096 Aug 11 20:37 tmp
drwxr-xr-x 1 root root 4096 Aug 3 07:00 usr
drwxr-xr-x 1 root root 4096 Aug 3 07:00 var
0
我们可以运行 Python 代码。
root@98ece0c01946:/# python -c "import sys; print(sys.version)" 3.8.5 (default, Aug 4 2020, 16:24:08) [GCC 8.3.0]
在我们的例子中,我们预装了 Python 3.8.5。
Python Docker get 请求
在下一个示例中,我们将构建一个检索 HTML 页面的镜像。我们使用 requests 库,该库必须安装在镜像中。
#!/usr/bin/python
import requests as req
resp = req.get("http://webcode.me")
print(resp.text)
代码示例通过发出 GET 请求来重试一个简单的网页。
FROM python:slim RUN pip install requests COPY get_req.py /tmp/ CMD ["python", "/tmp/get_req.py"]
这是 Dockerfile。
FROM python:slim
在此示例中,我们使用社区的 python:slim 镜像,该镜像占用的空间要小得多。
RUN pip install requests
使用 RUN 指令,我们执行 pip管理器并安装 requests 模块。
COPY get_req.py /tmp/
COPY 指令将 get_req.py 文件从我们的主机复制到容器的 /tmp/ 目录。如果目录不存在,则会创建该目录。
CMD ["python", "/tmp/get_req.py"]
CMD 指令在容器启动时运行程序。
$ sudo docker build -t pygetreq .
我们构建镜像并称之为 pygetreq。
$ sudo docker images | grep pygetreq pygetreq latest 0d3c5953ff60 23 seconds ago 121MB
此镜像仅需要 121MB。
$ sudo docker run pygetreq
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My html page</title>
</head>
<body>
<p>
Today is a beautiful day. We go swimming and fishing.
</p>
<p>
Hello there. How are you?
</p>
</body>
</html>
Python Docker Flask
在下一个示例中,我们将在 Docker 容器中运行一个简单的 Flask 应用程序。
#!/usr/bin/python
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello there!'
这是一个带有单个主路由的简单 Flask 应用程序。
FROM python:slim COPY app.py /app/ WORKDIR /app RUN pip install flask RUN export FLASK_APP=app.py EXPOSE 5000 CMD ["/usr/local/bin/flask", "run", "--host", "0.0.0.0"]
这是 Dockerfile。
FROM python:slim
我们的镜像基于 python-slim 镜像。
COPY app.py /app/ WORKDIR /app
我们将一个文件复制到镜像中的一个目录,并设置工作目录。如果目录尚不存在,则会创建它。
RUN pip install flask
使用 RUN 指令,我们安装 Flask。
RUN export FLASK_APP=app.py
我们将 FLASK_APP 环境变量设置为 app.py 应用程序文件。
EXPOSE 5000
我们暴露端口。
CMD ["/usr/local/bin/flask", "run", "--host", "0.0.0.0"]
使用 CMD 指令,我们设置了容器启动时运行的默认命令。我们将主机 IP 设置为 0.0.0.0,以便应用程序可以在容器外部访问。
$ sudo docker build -t flasksimple .
我们构建镜像。
$ docker run -p 5000:5000 flasksimple
我们运行镜像。容器的 5000 端口映射到我们计算机的 5000 端口。
$ curl localhost:5000/ Hello there!
使用 curl 工具,我们向应用程序生成一个 GET 请求。
Python Docker MariaDB
在以下示例中,我们将创建一个基于 mariadb 镜像的容器。
USE testdb;
DROP TABLE IF EXISTS cities;
CREATE TABLE cities(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), population INT);
INSERT INTO cities(name, population) VALUES('Bratislava', 432000);
INSERT INTO cities(name, population) VALUES('Budapest', 1759000);
INSERT INTO cities(name, population) VALUES('Prague', 1280000);
INSERT INTO cities(name, population) VALUES('Warsaw', 1748000);
INSERT INTO cities(name, population) VALUES('Los Angeles', 3971000);
INSERT INTO cities(name, population) VALUES('New York', 8550000);
INSERT INTO cities(name, population) VALUES('Edinburgh', 464000);
INSERT INTO cities(name, population) VALUES('Berlin', 3671000);
这是 cities 表的 SQL 代码。
FROM mariadb
RUN apt-get update && apt-get install -y \
python3.8 \
python3-pip
RUN pip3 install pymysql
ADD schema.sql /docker-entrypoint-initdb.d
ENV MYSQL_USER=user7
ENV MYSQL_PASSWORD=7user
ENV MYSQL_DATABASE=testdb
ENV MYSQL_ROOT_PASSWORD=s$cret
EXPOSE 3306
我们的镜像源自 mariadb 镜像。
RUN apt-get update && apt-get install -y \
python3.8 \
python3-pip
在镜像上,我们安装 Python 和 pip。
RUN pip3 install pymysql
我们安装 pymysql 驱动程序。
ADD schema.sql /docker-entrypoint-initdb.d
/docker-entrypoint-initdb.d 目录下的 SQL 脚本在容器初始化时运行。我们使用 ADD 指令复制 schema 文件。
ENV MYSQL_USER=user7 ENV MYSQL_PASSWORD=7user ENV MYSQL_DATABASE=testdb ENV MYSQL_ROOT_PASSWORD=s$cret
通过环境变量,我们创建一个新用户、一个新数据库,并为 root 用户设置密码。
EXPOSE 3306
EXPOSE 指令通知 Docker 容器在运行时监听指定的网络端口。
#!/usr/bin/python
import pymysql
con = pymysql.connect(host='localhost', user='user7',
password='7user', database='testdb', port=3306)
try:
with con.cursor() as cur:
cur.execute('SELECT * FROM cities')
rows = cur.fetchall()
for row in rows:
print(f'{row[0]}, {row[1]}, {row[2]}')
finally:
con.close()
该示例连接到正在容器内运行的 MariaDB testdb 数据库。它显示了 cities 表中的所有行。
$ sudo docker build -t pymaria-simple .
Sending build context to Docker daemon 4.608kB
Step 1/9 : FROM mariadb
---> b95867b52886
Step 2/9 : RUN apt-get update && apt-get install -y python3.8 python3-pip
---> Using cache
---> 9370769248ed
Step 3/9 : RUN pip3 install pymysql
---> Using cache
---> 108146aaa2d8
...
我们构建镜像。
$ sudo docker run -p 3306:3306 pymaria-simple
我们从自定义的 pymaria-simple 镜像运行容器。使用 -p 选项,我们将容器的 3306 端口发布到主机的 3306 端口。
$ ./app.py 1, Bratislava, 432000 2, Budapest, 1759000 3, Prague, 1280000 4, Warsaw, 1748000 5, Los Angeles, 3971000 6, New York, 8550000 7, Edinburgh, 464000 8, Berlin, 3671000
容器启动后,我们运行 app.py 程序,该程序显示城市。
来源
在本文中,我们使用 Python 和 Docker 进行了实践。
作者
列出所有 Python 教程。