Python Docker

Docker = 码头工人

Docker是开发人员和系统管理员使用容器构建、运行和共享应用程序的平台。Docker促进了应用程序的可移植性和可伸缩性。Docker提供了应用程序隔离,从而消除了库和环境差异引起的许多问题。它有助于自动化开发和部署。使用预定义的社区镜像(image),开发人员可以节省时间并改善他们的整体体验。

Docker镜像(image)是一个只读模板,包含创建Docker容器的说明。Docker容器是一个镜像的可运行实例。

Docker镜像存储在存储库中。Docker Hub是官方的Docker存储库。Docker引擎是底层的客户机-服务器技术,它使用Docker的组件和服务构建和运行容器。

Dockerfile是一个特殊的文件,它包含了构建Docker镜像所需的指令。

$ sudo docker --version
Docker version 19.03.12, build 48a66213fe

这是我们使用的Docker版本。

Python Docker hello示例

在下面的示例中,我们创建并运行一个非常简单的Docker镜像。当我们运行这个镜像时,会执行一个简单的Python文件。

hello.py

#!/usr/bin/python

import sys

print("hello there!")
print(sys.version)

这是要在容器内执行的简单文件。

Dockerfile

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 .

我们用docker build命令构建新的名为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]

我们用docker run运行hello镜像。

Python Docker交互模式

我们可以使用-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 request

在下一个示例中,我们构建一个检索HTML页面的镜像。我们使用请求库,它必须安装在镜像中。

get_req.py

#!/usr/bin/python

import requests as req

resp = req.get("http://webcode.me")

print(resp.text)

代码示例通过发出GET请求来重试一个简单的web页面。

Dockerfile

FROM python:slim
RUN pip install requests
COPY get_req.py /tmp/
CMD ["python", "/tmp/get_req.py"]

这是Dockerfile。

FROM python:slim

在本例中,我们使用社区python:slim镜像,它占用的空间少得多(slim有苗条的意思)。

RUN pip install requests

使用RUN指令,我们执行pip管理器并安装请求模块。

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



    
    
    My html page



    

Today is a beautiful day. We go swimming and fishing.

Hello there. How are you?

Python Docker Flask

在下一个示例中,我们将在Docker容器中运行一个简单的Flask应用程序。

app.py

#!/usr/bin/python

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello there!'

这是一个简单的Flask应用程序,只有一个主路由。

Dockerfile

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的image上。

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 .

我们构建image 文件。

$ docker run -p 5000:5000 flasksimple

我们运行image文件。容器的5000端口映射到主机的5000端口。

$ curl localhost:5000/
Hello there!

使用curl工具,我们生成一个到应用程序的GET请求。

Python Docker MariaDB

在下面的示例中,我们基于mariadb镜像创建一个容器。

schema.sql

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代码。

Dockerfile

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 image得到新的镜像。

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指令复制模式文件。

ENV MYSQL_USER=user7
ENV MYSQL_PASSWORD=7user
ENV MYSQL_DATABASE=testdb
ENV MYSQL_ROOT_PASSWORD=s$cret

使用环境变量,我们创建一个新用户、一个新数据库,并为root用户设置一个密码。

EXPOSE 3306

EXPOSE指令通知Docker容器在运行时监听指定的网络端口。

app.py

#!/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,python,docker,java)