我开始使用Docker了
听说将制作的工具类放入容器中会非常方便,因此我决定开始使用之前一直关注的Docker。
这次,我打算将用Python的Flask构建的web服务器进行容器化,试着通过仅启动和停止容器来管理web服务器。
这是我使用的环境。
$ cat /etc/redhat-release
Red Hat Enterprise Linux release 8.2 (Ootpa)
$ docker --version
Docker version 19.03.12, build 48a66213fe
※ 顺便说一句,在安装Docker时,有些人可能会遇到在CentOS 8上找不到containerd.io的问题。就我个人而言,我已经成功地解决了这个问题,供您参考。
Docker复习
首先,简要整理如何使用Docker(创建容器)。创建Docker容器有以下4个步骤。
-
- 拉取基本映像
-
- 建立Dockerfile
-
- 構建Docker映像
- 从映像中生成和启动Docker容器
个人的看法是,我认为最初创建Dockerfile是最难理解的部分。因此,我首先会完成第一阶段,即在容器内运行简单的Python脚本,并逐步修改以实现第二阶段,即运行基于Flask的Web服务器。
在容器内执行Python脚本。
首先,我们将在容器中创建并执行以下 myapp.py 文件。
print("hello Docker!")
引用基本图像
搜索在Docker Hub上注册的Python 3系列镜像,准备一个作为Python 3环境的映像。
$ sudo docker search python3
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
rackspacedot/python37 11
sellpy/python3-jupyter-sklearn python3-jupyter-sklearn 5 [OK]
openwhisk/python3action Apache OpenWhisk runtime for Python 3 Actions 5
sellpy/python3-jupyter-sklearn-java python3-jupyter-sklearn-java 2 [OK]
quoinedev/python3.6-pandas-alpine Python 3.7 on alpine with numpy and pandas i… 2
(略)
这次我们将使用STARS最多的rackspacedot/python37版本。让我们拉取它。
$ sudo docker pull rackspacedot/python37
由于 rackspacedot/python37 是一个 Docker 镜像,因此在拉取后,您可以通过运行 docker images 命令进行确认。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rackspacedot/python37 latest 3d51361ee118 7 weeks ago 1.06GB
如果你有这个镜像,你就可以在容器内使用Python。你可以把这个作为基础,然后添加其他需要的部分(比如脚本的安排),就可以了。
创建Dockerfile
接下来,请创建一个名为Dockerfile的文件。
FROM rackspacedot/python37
WORKDIR /usr/local/script
COPY myapp.py .
CMD python myapp.py
简单来说,
FROM rackspacedot/python37
ベースとなるイメージを指定する部分です。先ほどpullしたイメージを指定します。
WORKDIR /usr/local/script
コンテナ内での作業ディレクトリを指定します。今自分がいるディレクトリと違っていても問題ありません。
COPY myapp.py .
myapp.pyをコンテナ内の第二引数で指定したディレクトリにコピーします。今回は . で指定しているので、 WORKDIR で指定したディレクトリにコピーされます。
CMD python myapp.py
コンテナ起動時に実行するコマンドです。
以下是我們目前準備好的文件列表。
$ ls -l
total 8
-rw-r--r--. 1 user developer 146 Sep 11 16:39 Dockerfile
-rw-r--r--. 1 user developer 173 Sep 11 17:04 myapp.py
构建Docker镜像并启动容器。
由于创建了Dockerfile,我们将开始构建镜像并启动容器。
首先是构建镜像。
$ sudo docker build -t myapp:test .
– 使用 -t 参数可以设置镜像的名称和标签(与脚本名称不同也可以)。使用 . 符号指定 Dockerfile 所在的目录路径。
如果成功创建了镜像,将显示其哈希值,然后可以通过 docker images 命令来确认。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myapp test e577339515a7 10 seconds ago 1.06GB
rackspacedot/python37 latest 3d51361ee118 7 weeks ago 1.06GB
由于已经有一个想法,我会创建并启动容器。
$ sudo docker run myapp:test
hello Docker!
我能够在无事容器中执行Python脚本。在这里启动的容器会保留下来,所以可以再次使用相同的命令来执行。此外,可以使用docker ps -a命令来确认创建的容器。
在容器中运行 Flask 服务器。
好的,既然已经可以在容器内运行Python脚本,那么作为第二步,让我们来创建一个使用Flask的服务器吧。
将myapp.py按照下面的方式进行修改。
from flask import Flask
app = Flask("myapp")
@app.route("/")
def main():
return "hello Docker!!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
为了能够明显区分之前和现在,我将叹号的数量改为两个。
让我们把它变成可以在容器中作为Web服务器使用的状态。
修改Docker文件
由于使用了Flask,需要在容器中安装Flask。rackspacedot/python37默认包含pip,因此将pip install部分添加到Dockerfile的镜像构建步骤中。
FROM rackspacedot/python37
RUN pip install flask
RUN useradd docker
USER docker
WORKDIR /usr/local/script
COPY myapp.py .
CMD python myapp.py
追加的部分需要解释一下,
RUN pip install flask
コンテナ内にflaskをインストールします。
RUN useradd docker / USER docker
docker というユーザーを追加し、その後の操作を docker ユーザーとして実行します。
今回は無くても動作しますが、セキュリティ上の理由で追加しています。
构建Docker镜像并启动容器。
由于修改了文件,所以需要重新构建镜像→启动容器。
首先进行重新构建。
$ sudo docker build -t myapp .
我们这次省略了标签,所以会自动分配一个名为latest的标签。让我们使用docker images来确认一下。
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myapp latest 6c747be5d597 3 seconds ago 1.06GB
myapp test e577339515a7 50 minutes ago 1.06GB
rackspacedot/python37 latest 3d51361ee118 7 weeks ago 1.06GB
那么让我们启动容器吧。由于这是一个Web服务器,所以我们需要添加一些选项。
$ sudo docker run -d -p 8080:8080 myapp
关于端口号,-p 的写法如下:接收端口号:容器端口号。接收端口号可以是任意数字,而容器端口号需要与容器内的 myapp.py 中指定的编号(本例中为8080)相同。
如果启动没有问题,您可以使用”docker ps”命令来确认正在运行的容器。
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
00d1ab6fc24a myapp "/bin/sh -c 'python …" 3 seconds ago Up 2 seconds 0.0.0.0:8080->8080/tcp thirsty_mccarthy
让我们试着实际访问一下。
$ curl http://localhost:8080
hello Docker!!
好啊。这样web服务器容器化就完成了。
如果想要停止容器的话
$ sudo docker stop thirsty_mccarthy
如果想要在停止后重新启动,请:
$ sudo docker start thirsty_mccarthy
请在”thirsty_mccarthy”的位置指定容器名称(显示在执行docker ps命令时的NAME字段)。如果使用docker start命令启动容器,它会自动在之前指定的端口上运行。
此外,将其容器化后,当在其他环境中运行已创建的容器时,只需进行镜像构建→容器启动即可立即运行,非常方便。
这次就到这里了。如果能够使用Docker Compose来一次性执行多个容器的命令,将会进一步拓宽范围,所以我以后可能也会学习这个。