简介
持续集成/持续部署(CI/CD) 是一种开发实践,它允许软件团队在多个平台上更方便、更快捷地构建、测试和部署应用程序。CircleCI是一个流行的自动化平台,可让您为项目构建和维护 CI/CD 工作流程。
持续部署有很多好处。它有助于使应用程序的部署步骤标准化,并保护其免受未记录更改的影响。它还有助于避免执行重复步骤,让您更专注于开发。有了 CircleCI,您就可以在开发、测试和生产的所有不同部署流程中拥有单一视图。
在本教程中,您将在本地创建一个 Node.js 应用程序,并将其推送到 GitHub 上。随后,您将配置 CircleCI 以连接到运行 Ubuntu 18.04 的虚拟专用服务器 (VPS),并完成在 VPS 上自动部署代码的设置步骤。文章结束时,您将拥有一个可运行的 CI/CD 管道,CircleCI 会接收您从本地环境推送到 GitHub 代码库的任何代码,并将其部署到您的 VPS 上。
先决条件
在开始之前,您需要具备以下条件:
- 一个 GitHub 账户,可以在GitHub 网站上创建。
- 一台 Ubuntu 18.04 服务器,按照Initial Server Setup for Ubuntu 18.04教程进行设置,包括一个 sudo 非 root 用户和一个防火墙。
- 一个 CircleCI 账户,可以在CircleCI 网站上创建。
- 了解git 版本控制的基础知识会有帮助。您可以使用 如何在 GitHub 上创建拉取请求 和 Git 简介:安装、使用和分支 学习基础知识。
- 在本地环境和远程服务器上都需要运行 Node.js 的开发环境;本教程在 Node.js 10.22.0 版和 npm 6.14.6 版上进行了测试。要在 macOS 或 Ubuntu 18.04 上安装,请按照如何在 macOS 上安装 Node.js 并创建本地开发环境 或如何在 Ubuntu 18.04 上安装 Node.js 的 ** 使用 PPA 安装** 部分中的步骤操作。
步骤 1 - 创建本地节点项目
在本步骤中,您将在本地创建一个 Node.js 项目,作为本教程的示例应用程序。稍后您将把该项目推送到 GitHub 上的 repo。
请在本地终端上运行这些命令,以便快速创建 Node 开发环境。
首先,为测试项目创建一个目录:
1[environment local]
2mkdir circleci-test
切换到新目录:
1[environment local]
2cd circleci-test
之后,如果有依赖关系,请初始化一个 npm 环境以提取依赖关系。y "标志将自动接受 "npm init "发出的所有提示:
1[environment local]
2npm init -y
有关 npm
的更多信息,请查看我们的 如何使用 npm 和 package.json 来使用 Node.js 模块 教程。
接下来,创建一个基本服务器,当有人访问任何路由时,它都会提供Hello World!
。使用文本编辑器,在项目根目录下创建一个名为 app.js
的文件。本教程将使用 nano:
1[environment local]
2nano app.js
在 app.js
文件中添加以下代码:
1[label circleci-test/app.js]
2const http = require('http');
3
4http.createServer(function (req, res) {
5 res.write('Hello World!');
6 res.end();
7}).listen(8080, '0.0.0.0');
此示例服务器使用 http
软件包监听端口 8080
上的任何传入请求,并触发一个请求监听器函数,以 string Hello World
作为回复。
保存并关闭文件。
您可以在本地计算机上进行测试,在终端中的同一目录下运行以下命令。这将创建一个运行服务器的 Node 进程 (app.js
):
1[environment local]
2node app.js
现在访问浏览器中的 http://localhost:8080
URL。浏览器将显示字符串 Hello World!
。测试应用程序后,在启动 Node 进程的同一终端上按下 CTRL+C
,停止服务器。
现在您已经设置好了示例应用程序。下一步,您将在项目中添加一个配置文件,以便 CircleCI 可以使用它进行部署。
第 2 步 - 为项目添加配置文件
CircleCI 根据项目文件夹中的配置文件执行工作流。在本步骤中,您将创建该文件以定义部署工作流。
在项目根目录下创建一个名为.circleci
的文件夹:
1[environment local]
2mkdir .circleci
在其中添加一个名为 config.yml
的新文件:
1[environment local]
2nano .circleci/config.yml
这将打开一个扩展名为 YAML 的文件。YAML 是一种常用于配置管理的语言。
在新的 config.yml
文件中添加以下配置:
1[label circleci-test/.circleci/config.yml]
2version: 2.1
3
4# Define the jobs we want to run for this project
5jobs:
6 pull-and-build:
7 docker:
8 - image: arvindr226/alpine-ssh
9 steps:
10 - checkout
11 - run: ssh -oStrictHostKeyChecking=no -v $USER@$IP "./deploy.sh"
12
13# Orchestrate our job run sequence
14workflows:
15 version: 2
16 build-project:
17 jobs:
18 - pull-and-build:
19 filters:
20 branches:
21 only:
22 - main
保存该文件并退出文本编辑器。
该文件告诉 CircleCI 管道以下内容
- 有一个名为 "pull-and-build "的任务,其步骤包括启动一个Docker 容器,通过 SSH 连接到 VPS,然后运行 "deploy.sh "文件。
- Docker 容器的作用是为执行配置中 "步骤 "部分提到的命令创建一个临时环境。在这种情况下,你需要做的就是 SSH 登录 VPS 并运行
sh deploy.sh
命令,因此环境需要轻量级,但仍允许 SSH 命令。Docker 映像arvindr226/alpine-ssh
是支持 SSH 的 Alpine Linux 映像。 deploy.sh
是一个将在 VPS 中创建的文件。它将作为部署过程的一部分每次运行,并将包含针对您项目的特定步骤。- 在 "工作流 "部分,你会告知 CircleCI,它需要根据某些过滤器来执行这项工作,在本例中就是只有对主分支的更改才会触发这项工作。
然后,提交这些文件并推送到 GitHub 仓库。为此,您需要在项目目录下运行以下命令。
首先,将 Node.js 项目目录初始化为 git repo:
1[environment local]
2git init
继续将新改动添加到 git 仓库:
1[environment local]
2git add .
然后提交更改:
1[environment local]
2git commit -m "initial commit"
如果这是第一次提交,git 会提示您运行一些 git config
命令来识别您的身份。
从浏览器导航至 GitHub,并使用 GitHub 账户登录。创建一个名为 "circleci-test "的新仓库,其中不包含 README 或许可证文件。创建仓库后,返回命令行将本地文件推送到 GitHub。
要遵循 GitHub 协议,请使用以下命令重命名分支 main
:
1[environment local]
2git branch -M main
首次推送文件前,需要将 GitHub 添加为远程仓库。请运行
1[environment local]
2git remote add origin https://github.com/GitHub_username/circleci-test
然后执行 push
命令,将文件传输到 GitHub:
1[environment local]
2git push -u origin main
现在您已将代码推送到 GitHub。下一步,您将在 VPS 中创建一个新用户,该用户将执行 "拉取并构建 "部分的 "步骤"。
第 3 步 - 创建新用户进行部署
项目准备就绪后,您将在 VPS 中创建一个部署用户。
以 sudo
用户身份连接 VPS
1[environment local]
2ssh your_username@your_server_ip
接下来,使用 useradd
命令创建一个不使用密码登录的新用户。
1sudo useradd -m -d /home/circleci -s /bin/bash circleci
该命令将在系统中创建一个新用户。-m
标志指示命令创建一个由-d
标志指定的主目录。
在这种情况下,"circleci "将成为新的部署用户。为了安全起见,你不会将该用户添加到 sudo
组,因为该用户的唯一任务就是创建从 VPS 到 CircleCI 网络的 SSH 连接,并运行 deploy.sh
脚本。
确保 VPS 的防火墙对 8080
端口开放:
1sudo ufw allow 8080
现在需要创建一个 SSH 密钥,新用户可以用它登录。创建的 SSH 密钥不能有口令,否则 CircleCI 将无法解密。更多信息请参阅 CircleCI 官方文档。此外,CircleCI 希望 SSH 密钥的格式是 PEM 格式,因此在创建密钥对时必须执行这一点。
回到本地系统,移至主文件夹:
1[environment local]
2cd
然后运行以下命令:
1[environment local]
2ssh-keygen -m PEM -t rsa -f .ssh/circleci
该命令创建一个 RSA 密钥,其 PEM 格式由 -m
标志指定,密钥类型由 -t
标志指定。你还可以指定 -f
来创建名为 circleci
和 circleci.pub
的新密钥对。指定名称可避免覆盖现有的 id_rsa
文件。
打印出新的公开密钥:
1[environment local]
2cat ~/.ssh/circleci.pub
这将输出您生成的公钥。您需要在 VPS 中注册此公钥。将此复制到剪贴板。
回到 VPS,为 circleci
用户创建一个 .ssh
目录:
1sudo mkdir /home/circleci/.ssh
在这里,你将把从本地机器复制的公钥添加到名为 "authorized_keys "的文件中:
1sudo nano /home/circleci/.ssh/authorized_keys
在此处添加复制的公钥,保存文件并退出文本编辑器。
为 circleci
用户提供目录权限,使其在部署过程中不会遇到权限问题。
1sudo chown -R circleci:circleci /home/circleci
验证能否使用私钥以新用户身份登录。在本地系统上打开一个新终端并运行
1[environment local]
2ssh circleci@your_server_ip -i ~/.ssh/circleci
现在,您将以 circleci
用户身份登录 VPS。这表明 SSH 连接成功。接下来,将 GitHub 仓库连接到 CircleCI。
第 4 步 - 将 GitHub 项目添加到 CircleCI
在这一步中,您将把 GitHub 账户连接到 CircleCI 账户,并为 CI/CD 添加 circleci-test
项目。如果使用 GitHub 账户注册,GitHub 会自动与 CircleCI 账户连接。如果没有,请访问 https://circleci.com/account
并连接。
要添加 "circleci-test "项目,请导航到位于 https://app.circleci.com/projects/project-dashboard/github/your_username
的 CircleCI 项目控制面板:
这里列出了 GitHub 上的所有项目。点击 Circleci-test 项目的 ** Set Up Project** 。这将带你进入项目设置页面:
在 CircleCI 界面中设置项目](assets/67406/2.png)
现在你可以选择为项目设置配置,你已经在 repo 中设置了配置。既然已经设置好了,请选择使用现有配置 选项。这将弹出一个确认要构建管道的弹出框:
确认 CircleCI 构建配置文件的弹出窗口](assets/67406/3.png)
在这里,点击开始构建 。这将带您进入 "circleci-test "管道页面。目前,该管道会失败。这是因为你必须先更新项目的 SSH 密钥。
导航至 "https://app.circleci.com/settings/project/github/your_username/circleci-test "的项目设置,选择左侧的SSH 键 部分。
运行以下命令,从本地计算机读取先前创建的名为 circleci
的私人密钥:
1[environment local]
2cat ~/.ssh/circleci
复制该命令的输出结果。
在 Additional SSH Keys 部分,单击 ** Add SSH Key** 按钮。
设置页面的 "添加 SSH 密钥 "部分](assets/67406/4.png)
这将打开一个窗口,要求你输入主机名和 SSH 密钥。输入你选择的主机名,并添加从本地环境复制的 SSH 密钥。
现在,CircleCI 可以使用此密钥以新的 circleci
用户身份登录 VPS。
最后一步是向 CircleCI 提供 VPS 的用户名和 IP。在同一项目设置 页面,转到左侧的** 环境变量** 选项卡:
设置页面的环境变量部分](assets/67406/5.png)
添加一个名为USER 的环境变量,其值为 "circleci",** IP** 的值为 VPS 的 IP 地址(如果有 DNS 记录,则为 VPS 的域名)。
创建这些变量后,就完成了 CircleCI 所需的设置。接下来,通过 SSH 授予 circleci
用户访问 GitHub 的权限。
第 5 步 - 向 GitHub 添加 SSH 密钥
现在,您需要为 circleci
用户提供一种与 GitHub 进行身份验证的方式,以便它能执行 git pull
等操作。
为此,您需要为该用户创建一个 SSH 密钥,以便通过 GitHub 进行身份验证。
以 circleci
用户身份连接 VPS:
1[environment local]
2ssh circleci@your_server_ip -i ~/.ssh/circleci
创建无口令的新 SSH 密钥对:
1ssh-keygen -t rsa
然后输出公钥:
1cat ~/.ssh/id_rsa.pub
复制输出,然后前往位于 https://github.com/your_username/circleci-test/settings/keys
的 circleci-test
GitHub repo 的部署密钥设置。
点击添加部署密钥 ,添加复制的公钥。在 ** Title** 字段中填写你想要的密钥名称,然后在 ** Key** 字段中添加复制的公钥。最后,点击** 添加密钥** 按钮,将密钥添加到账户中。
现在,"circleci "用户可以访问你的 GitHub 账户,你将使用 SSH 身份验证来建立你的项目。
第 6 步 - 在 VPS 上设置项目
现在,您要克隆该 repo,并以 circleci
用户身份在 VPS 上对项目进行初始设置。
在 VPS 上运行以下命令:
1git clone [email protected]:your_username/circleci-test.git
导航进入:
1cd circleci-test
首先,安装依赖项:
1npm install
现在,运行您构建的服务器来测试应用程序:
1node app.js
打开浏览器,尝试输入地址 http://your_vps_ip:8080
。您将收到输出Hello World!
。
使用 CTRL+C
停止此进程,然后使用 pm2
将此应用程序作为后台进程运行。
安装 pm2
以便将 Node 应用程序作为独立进程运行。pm2
是一个用 Node.js 编写的多功能进程管理器。在这里,它将帮助您保持示例 Node.js 项目作为活动进程运行,即使在您注销服务器后也是如此。您可以在 如何在 Ubuntu 18.04 上设置用于生产的 Node.js 应用程序 教程中阅读更多相关内容。
1npm install -g pm2
<$>[注意]
注意: 在某些系统(如 Ubuntu 18.04)上,全局安装 npm 软件包可能会导致权限错误,从而中断安装。由于安全方面的最佳做法是避免在使用 npm install
时使用 sudo
,因此你可以通过更改 npm 的默认目录来解决这个问题。如果遇到 EACCES
错误,请遵循 npm 官方文档中的说明。
<$>
您可以使用 pm2 start
命令将 app.js
文件作为 Node 进程运行。您可以使用 --name
标志将其命名为 app
,以便日后识别:
1pm2 start app.js --name "app"
您还需要提供部署指令。这些命令将在 circleci
用户每次部署代码时运行。
返回主目录,因为这将是 circleci
用户成功登录时的路径:
1cd ~
继续创建包含部署说明的 deploy.sh
文件:
1nano deploy.sh
现在,您将使用 Bash 脚本 自动进行部署:
1[label deploy.sh]
2#!/bin/bash
3
4#replace this with the path of your project on the VPS
5cd ~/circleci-test
6
7#pull from the branch
8git pull origin main
9
10# followed by instructions specific to your project that you used to do manually
11npm install
12export PATH=~/.npm-global/bin:$PATH
13source ~/.profile
14
15pm2 restart app
这会自动将工作目录更改为项目根目录,从 GitHub 提取代码,安装依赖项,然后重启应用程序。保存并退出文件。
运行该文件,使其成为可执行文件:
1chmod u+x deploy.sh
现在回到本地计算机,快速更改并测试一下。进入你的项目目录:
1[environment local]
2cd circleci-test
打开你的 app.js
文件:
1[environment local]
2nano circleci-test/app.js
现在添加以下突出显示的一行:
1[label circleci-test/app.js]
2const http = require('http');
3
4http.createServer(function (req, res) {
5 res.write('Foo Bar!');
6 res.end();
7}).listen(8080, '0.0.0.0');
保存文件并退出文本编辑器。
添加此更改并提交:
1[environment local]
2git add .
3git commit -m "modify app.js"
现在将其推送到主分支:
1[environment local]
2git push origin main
这将触发一个新的部署管道。导航至 https://app.circleci.com/pipelines/github/your_username
查看管道的运行情况。
成功后,刷新浏览器 http://your_vps_ip:8080
。现在,Foo Bar!
将在浏览器中呈现。
结论
以下是将 CircleCI 与 GitHub 仓库和基于 Linux 的 VPS 集成的步骤。您可以修改 deploy.sh
以获得与您的项目相关的更多具体说明。
如果您想了解有关 CI/CD 的更多信息,请查看我们的 CI/CD 主题页面。有关使用 CircleCI 设置工作流的更多信息,请访问 CircleCI 文档。