部署
在编写完成各类插件后,我们需要长期运行机器人来使得用户能够正常使用。通常,我们会使用云服务器来部署机器人。
我们在开发插件时,机器人运行的环境称为开发环境;而在部署后,机器人运行的环境称为生产环境。与开发环境不同的是,在生产环境中,开发者通常不能随意地修改/添加/删除代码,开启或停止服务。
部署前准备
项目依赖管理
由于部署后的机器人运行在生产环境中,因此,为确保机器人能够正常运行,我们需要保证机器人的运行环境与开发环境一致。我们可以通过以下几种方式来进行依赖管理:
- Poetry
- PDM
- pip
Poetry 是一个 Python 项目的依赖管理工具。它可以通过声明项目所依赖的库,为你管理(安装/更新)它们。Poetry 提供了一个 poetry.lock
文件,以确保可重复安装,并可以构建用于分发的项目。
Poetry 会在安装依赖时自动生成 poetry.lock
文件,在项目目录下执行以下命令:
# 初始化 poetry 配置
poetry init
# 添加项目依赖,这里以 nonebot2[fastapi] 为例
poetry add nonebot2[fastapi]
PDM 是一个现代 Python 项目的依赖管理工具。它采用 PEP621 标准,依赖解析快速;同时支持 PEP582 和 virtualenv。PDM 提供了一个 pdm.lock
文件,以确保可重复安装,并可以构建用于分发的项目。
PDM 会在安装依赖时自动生成 pdm.lock
文件,在项目目录下执行以下命令:
# 初始化 pdm 配置
pdm init
# 添加项目依赖,这里以 nonebot2[fastapi] 为例
pdm add nonebot2[fastapi]
pip 是 Python 包管理工具。他并不是一个依赖管理工具,为了尽可能保证环境的一致性,我们可以使用 requirements.txt
文件来声明依赖。
pip freeze > requirements.txt
安装 Docker
Docker 是一个应用容器引擎,可以让开发者打包应用以及依赖包到一个可移植的镜像中,然后发布到服务器上。
我们可以参考 Docker 官方文档 来安装 Docker 。
在 Linux 上,我们可以使用以下一键脚本来安装 Docker 以及 Docker Compose Plugin:
curl -fsSL https://get.docker.com | sh -s -- --mirror Aliyun
在 Windows/macOS 上,我们可以使用 Docker Desktop 来安装 Docker 以及 Docker Compose Plugin。
安装脚手架 Docker 插件
我们可以使用 nb-cli-plugin-docker 来快速部署机器人。
插件可以帮助我们生成配置文件并构建 Docker 镜像,以及启动/停止/重启机器人。使用以下命令安装脚手架 Docker 插件:
nb self install nb-cli-plugin-docker
Docker 部署
快速部署
使用脚手架命令即可一键生成配置并部署:
nb docker up
当看到 Running
字样时,说明机器人已经启动成功。我们可以通过以下命令来查看机器人的运行日志:
nb docker logs
如果需要停止机器人,我们可以使用以下命令:
nb docker down
自定义部署
通常情况下,自动生成的配置文件并不能满足复杂场景,我们需要根据实际需求手动修改配置文件。使用以下命令来生成基础配置文件:
nb docker generate
nb-cli 将会在项目目录下生成 docker-compose.yml
和 Dockerfile
等配置文件,我们可以参考 Dockerfile 文件规范和 Compose 文件规范修改这两个文件。
修改完成后我们可以直接启动或者手动构建镜像:
# 启动机器人
nb docker up
# 手动构建镜像
nb docker build
持续集成
我们可以使用 GitHub Actions 来实现持续集成(CI),我们只需要在 GitHub 上发布 Release 即可自动构建镜像并推送至镜像仓库。
首先,我们需要在 Docker Hub (或者其他平台,如:GitHub Packages、阿里云容器镜像服务等)上创建镜像仓库,用于存放镜像。
前往项目仓库的 Settings
> Secrets
> actions
栏目 New Repository Secret
添加构建所需的密钥:
DOCKERHUB_USERNAME
: 你的 Docker Hub 用户名DOCKERHUB_TOKEN
: 你的 Docker Hub PAT(创建方法)
将以下文件添加至项目目录下的 .github/workflows/
目录下,并将文件中高亮行中的仓库名称替换为你的仓库名称:
name: Docker Hub Release
on:
push:
tags:
- "v*"
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Setup Docker
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Generate Tags
uses: docker/metadata-action@v4
id: metadata
with:
images: |
{organization}/{repository}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
- name: Build and Publish
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
持续部署
在完成发布并构建镜像后,我们可以自动将镜像部署到服务器上。
前往项目仓库的 Settings
> Secrets
> actions
栏目 New Repository Secret
添加部署所需的密钥:
DEPLOY_HOST
: 部署服务器的 SSH 地址DEPLOY_USER
: 部署服务器用户名DEPLOY_KEY
: 部署服务器私钥(创建方法)DEPLOY_PATH
: 部署服务器上的项目路径
将以下文件添加至项目目录下的 .github/workflows/
目录下,在构建成功后触发部署:
name: Deploy
on:
workflow_run:
workflows:
- Docker Hub Release
types:
- completed
jobs:
deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- name: Start Deployment
uses: bobheadxi/deployments@v1
id: deployment
with:
step: start
token: ${{ secrets.GITHUB_TOKEN }}
env: bot
- name: Run Remote SSH Command
uses: appleboy/ssh-action@master
env:
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
key: ${{ secrets.DEPLOY_KEY }}
envs: DEPLOY_PATH
script: |
cd $DEPLOY_PATH
docker compose up -d --pull always
- name: update deployment status
uses: bobheadxi/deployments@v0.6.2
if: always()
with:
step: finish
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
env: ${{ steps.deployment.outputs.env }}
deployment_id: ${{ steps.deployment.outputs.deployment_id }}
将上一部分的 docker-compose.yml
文件以及 .env.prod
配置文件添加至 DEPLOY_PATH
目录下,并修改 docker-compose.yml
文件中的镜像配置,替换为 Docker Hub 的仓库名称:
- build: .
+ image: {organization}/{repository}:latest