本教程包括。
- 对Python应用程序进行 "Docker化"
- 设置一个管道来构建和测试一个镜像
- 将Docker镜像部署到Docker Hub上
CI/CD系统遵循多层环境模式:开发、测试、暂存和生产发布都是这个过程的一部分。这个周期中的每个设置都可能有各种设置和配置。因此,为不同的环境设置单独的配置可能是不方便的,也是很麻烦的。
在本教程中,我们将看看什么是Docker,以及它如何将开发者从设置问题和端口冲突中解放出来。我将介绍如何将一个Python应用程序 "Docker化"。然后,我将指导你建立一个管道来构建一个镜像,并在测试通过后将其推送到Docker Hub。
先决条件
完成本教程需要以下条件。
- 在您的系统上安装Python。
- 一个CircleCI账户。
- 一个GitHub账户,并了解一些Github操作,如
commit和push。 - 一个Docker Hub账户。
- 对管道如何工作有基本的了解。 有了这些,你就可以开始了。
为什么使用Docker?
想象一下,你是一个测试项目的开发者。你在做项目的时候使用的是Python 2.7 ,但由于某些原因,你要在生产中使用Python 3.9 。另外,Devops团队目前正在使用Python 3.6 ,为组织托管应用程序。
这些版本的不一致可能会使开发过程变得有些痛苦。它们也可能给Devops团队带来头痛,因为他们要努力跟上每个需要托管的应用程序的不同版本。幸运的是,Docker提供了一个解决方案。首先,让我解释一下与Docker的使用相关的一些概念。
**Docker**是一个使用容器化技术的平台,允许开发人员快速创建、共享和运行应用程序,并保持其创建时的状态。
A **Docker container**是一个应用程序的运行环境,由打包好的代码和所有依赖关系组成。为了启动一个Docker容器,你可以使用Docker镜像。
A **Docker image**是一个可执行文件(模板),包含了应用程序正常运行所需的一切,包括代码、依赖关系和虚拟环境。
Docker镜像是通过一个被称为Dockerfile 的特殊文件创建的。Docker文件是一个文件,它包含了一组Docker在创建镜像时要遵循的指令。
Docker不需要担心机器的配置,因为它在容器本身中启动了所有的配置。这确保了应用程序在所有设置了Docker的机器上运行一致。
与虚拟机不同,使用Docker会使微服务架构的开发和部署易于管理。这不仅导致了精简的组织,也导致了解耦的系统。解耦系统将发生故障的几率降到最低,使其比单体应用的风险更小。
Docker促进了跨平台的兼容性和可维护性,以及简单性、快速部署和安全性。
Docker化你的Python应用程序
"Dockerizing "一个应用程序包括这些步骤。
- 设置一个API来建立一个镜像和
- 创建一个Docker文件
设置一个API来构建一个镜像
为了演示本节教程中的Docker过程,在本地使用FastAPI RestAPI。该API已经为你创建。首先用这个命令克隆仓库。
git clone https://github.com/CIRCLECI-GWP/dockerhub-automated-circleci-deployments.git;
cd dockerhub-automated-circleci-deployments;
这样就把GitHub仓库克隆到一个名为dockerhub-automated-circleci-deployments 的目录中,然后进入该目录。
在dockerhub-automated-circleci-deployments 目录内,创建一个虚拟环境,并使用为你的操作系统提供的命令激活它。
## Windows OS ##
# create a venv
python -m venv venv
# activate venv
venv\Scripts\activate
## Linux/Mac OS ##
#create a venv
python3 -m venv venv
# activate venv
source venv/bin/activate
一旦创建了虚拟环境,你就可以用这个命令来安装依赖项。
pip install -r requirements.txt
运行该应用程序。
uvicorn app.main:app --reload
现在你已经验证了你的API运行成功,继续为你的应用程序创建一个Dockerfile 。
创建一个Docker文件
如前所述,Dockerfile 是一本创建镜像的食谱。当你运行docker build 命令时,Docker将从Dockerfile中读取指令并构建一个镜像。
在这种情况下,你需要Docker文件来。
- 下载
Python 3.10.2版本 - 在应用程序中找到你的包
- 执行安装 一旦安装成功,你需要镜像在容器内启动你的应用程序。
把这个添加到你的Docker文件中。
FROM python:3.10.2
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
在这个Docker配置中,WORKDIR 命令指定了工作目录,这是你目录的绝对路径。COPY 命令将requirements.txt 文件复制到你的应用程序所在的目录中。RUN 命令安装了你运行应用程序所需的软件包。最后,CMD 指定了运行镜像时将执行的命令。
你可能想知道在应用程序的RUN 命令中,主机和端口是用来干什么的。Docker将使用uvicorn 作为服务器和你的应用程序的入口端口。主机和端口将确保你可以在容器外访问该应用程序。
如果你想在本地构建镜像以验证你的Docker文件是否正常,你可以运行这个命令。
docker build -t fastapi-app .
接下来,你需要在GitHub上创建一个新的仓库,提交,然后先把所有的修改推送到仓库。然后你就可以开始使用CircleCI将你的Docker容器部署到Docker Hub的过程了。
使用CircleCI将Docker镜像部署到Docker Hub上
Docker Hub是一个Docker镜像的存储库,类似于GitHub。它使搜索和与其他开发者分享Docker镜像变得更加容易。
设置CircleCI
为了确保您的应用程序与CircleCI的集成,创建一个配置文件,告诉CircleCI如何初始化您的存储库和运行测试。从根目录,创建一个新的目录,称为.circleci/ 。在这个新目录中,创建一个新的文件,称为config.yml 。把它添加到你的config.yml 文件中。
version: 2
jobs:
build:
docker:
- image: cimg/python:3.10.2
steps:
- checkout
- run:
name: Install pip packages
command: |
python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
- run:
name: Test with pytest
command: |
. venv/bin/activate
pytest
workflows:
version: 2
build-master:
jobs:
- build
这个配置定义了 Python3.10.2 镜像。然后,一旦镜像被下载,该配置就会建立虚拟环境,安装所有的应用程序依赖,然后运行你的测试。
添加完我们的CircleCI配置文件后,提交并推送你的修改到你的远程GitHub仓库。
现在你可以在仪表板上创建一个CircleCI项目。
点击Set Up Project来开始构建。你会被提示在你的项目的仓库内使用配置文件。输入配置文件所在的分支的名称。在这种情况下,它是main 分支。

点击Set Up Project来完成这一过程。
现在,你已经在CircleCI上运行了测试,你的工作已经完成了一半接下来,你需要将你的应用程序部署到Docker Hub。你将需要添加一个选项,首先登录到Docker Hub,然后在每次测试通过后建立一个镜像。
向Docker Hub推送任何镜像将始终需要认证。你首先需要在CirclecI仪表板上配置你的Docker HubUSER_ID,PASSWORD 和镜像名称。转到CircleCI仪表板。从设置部分,选择环境变量。
使用这种格式添加环境变量。
DOCKER_HUB_USER_ID是你的Docker Hub ID。DOCKER_HUB_PASSWORD是你的Docker Hub密码。
添加Docker镜像名称作为环境变量,环境名称为IMAGE_NAME 。给它分配一个唯一的名字作为值。

目前,你的CircleCI配置只运行你的测试。你需要修改它,使它首先运行测试,然后构建一个Docker镜像,并在所有测试通过后将其推送到Docker Hub。
像这样在你的config.yml 文件中添加一个deploy 工作。
version: 2
jobs:
build:
docker:
- image: cimg/python:3.10.2
steps:
- checkout
- run:
name: Install pip packages
command: |
python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
- run:
name: Test with pytest
command: |
. venv/bin/activate
pytest
deploy:
docker:
- image: cimg/base:2022.06
steps:
- checkout
- setup_remote_docker:
version: 19.03.13
- run:
name: Build and push to Docker Hub
command: |
docker build -t $DOCKER_HUB_USER_ID/$IMAGE_NAME:latest .
echo "$DOCKER_HUB_PASSWORD" | docker login -u "$DOCKER_HUB_USER_ID" --password-stdin
docker push $DOCKER_HUB_USER_ID/$IMAGE_NAME:latest
workflows:
version: 2
build-master:
jobs:
- build
- deploy:
requires:
- build
这个配置文件包含一个workflow ,其中有两个作业。
build作业构建并测试代码。deploy作业构建并将你的Docker镜像推送到Docker Hub。
在增加的配置部署步骤中,deploy 作业在启动远程Docker引擎之前检索代码。当创建用于部署的Docker镜像时,你必须使用setup_remote_docker 选项。为了安全起见,该选项为每次构建都创建了一个单独的远程环境。这个环境是专门为运行Docker命令而设置的。
一旦完成了这些,你就可以开始运行Docker命令来构建和标记你的镜像。
docker build -t $DOCKER_HUB_USER_ID/$IMAGE_NAME:latest .
这个命令建立了一个Docker镜像,并用:latest 标签来标记它。镜像名称的前缀是你在CircleCI仪表板上作为环境变量设置的Docker Hub用户名,后面是镜像的实际名称,(也是你设置的环境变量)。
一旦你有了一个内置的镜像,使用CircleCI和存储的环境变量登录你的Docker Hub账户。
echo "$DOCKER_HUB_PASSWORD" | docker login -u "$DOCKER_HUB_USER_ID" --password-stdin
这就是配置文件中的命令的作用。现在你有了一个镜像并登录到Docker Hub,你的镜像就会使用配置文件中定义的这个命令推送到Docker Hub。
docker push $DOCKER_HUB_USER_ID/$IMAGE_NAME:latest
为了确保管道的完整性,有一个条件要求你的构建和测试工作在部署到Docker Hub之前必须通过。这发生在最后的配置块中,在workflow 。
workflows:
version: 2
build-master:
jobs:
- build
- deploy:
requires:
- build
最后,我们需要提交并推送我们所有的修改到GitHub。一旦我们这样做了,我们就可以继续检查CircleCI仪表板,看看我们的测试和部署的进展。
瞧!我们的deploy 和build 步骤都是绿色的,检查deploy 工作,我们的镜像已经成功构建并推送到Docker hub。

为了验证我们的镜像是否被推送到了Docker Hub,我们可以去Docker Hub网站查看镜像的状态。在我们的案例中,我们的镜像被命名为circleci-automated-dockerhub-image ,我们可以在Docker hub的仪表板上看到它,如下图所示。

这样一来,我们不仅验证了我们的CircleCI配置是有效的,而且还验证了我们的镜像被成功推送到Docker Hub。虽然感觉很多,但我们已经能够使用CircleCI和Docker Hub创建一个CI/CD流程,为我们自己节省了大量的时间,否则就会花费在手动Docker Hub部署上。
总结
在本教程中,我们已经学会了如何使用CirclecI来构建和部署Docker镜像到Docker Hub。我们还学习了如何使用我们项目中定义的Dockerfile来构建Docker镜像。
在本教程的最后一节,我们还介绍了如何创建一个管道,构建一个镜像,并在测试通过后才将其推送到Docker Hub。