如何在Ubuntu18.04上使用CircleCI和GitHub自动部署

来自菜鸟教程
跳转至:导航、​搜索

作为 Write for DOnations 计划的一部分,作者选择了 International Medical Corps 来接受捐赠。

介绍

持续集成/持续部署 (CI/CD) 是一种开发实践,允许软件团队在多个平台上更轻松、更快速地构建、测试和部署应用程序。 CircleCI 是一个流行的自动化平台,允许您为项目构建和维护 CI/CD 工作流。

持续部署在许多方面都是有益的。 它有助于标准化应用程序的部署步骤并保护它免受未记录的更改。 它还有助于避免执行重复的步骤,让您更专注于开发。 使用 CircleCI,您可以在开发、测试和生产的所有不同部署过程中拥有单一视图。

在本教程中,您将在本地构建一个 Node.js 应用程序并将其推送到 GitHub。 之后,您将配置 CircleCI 以连接到运行 Ubuntu 18.04 的虚拟专用服务器 (VPS),并且您将完成设置代码以在 VPS 上自动部署的步骤。 在本文结束时,您将拥有一个有效的 CI/CD 管道,CircleCI 将在其中提取您从本地环境推送到 GitHub 存储库的任何代码,并将其部署到您的 VPS 上。

先决条件

在开始之前,您需要具备以下条件:

第 1 步 - 创建本地节点项目

在此步骤中,您将在本地创建一个 Node.js 项目,您将在本教程中将其用作示例应用程序。 稍后您将把它推送到 GitHub 上的存储库。

继续并在您的本地终端上运行这些命令,以便您可以设置快速的 Node 开发环境。

首先,为测试项目创建一个目录:

mkdir circleci-test

切换到新目录:

cd circleci-test

通过初始化 npm 环境来跟进此操作,以提取依赖项(如果有)。 -y 标志将自动接受 npm init 抛出的每个提示:

npm init -y

有关 npm 的更多信息,请查看我们的 如何将 Node.js 模块与 npm 和 package.json 一起使用教程。

接下来,创建一个 基本服务器,当有人访问任何路由时为 Hello World! 提供服务。 使用文本编辑器,在项目的根目录中创建一个名为 app.js 的文件。 本教程将使用 nano

nano app.js 

将以下代码添加到 app.js 文件中:

circleci-test/app.js

const http = require('http');

http.createServer(function (req, res) {
  res.write('Hello World!'); 
  res.end(); 
}).listen(8080, '0.0.0.0'); 

此示例服务器使用 http 包来侦听端口 8080 上的任何传入请求,并触发以 string Hello World 回复的请求侦听器函数。

保存并关闭文件。

您可以通过从终端的同一目录运行以下命令在本地计算机上进行测试。 这将创建一个运行服务器的 Node 进程(app.js):

node app.js

现在在浏览器中访问 http://localhost:8080 URL。 您的浏览器将呈现字符串 Hello World!。 测试应用程序后,在启动 Node 进程的同一终端上按 CTRL+C 停止服务器。

您现在已经设置了示例应用程序。 在下一步中,您将在项目中添加一个配置文件,以便 CircleCI 可以将其用于部署。

第 2 步 — 将配置文件添加到您的项目中

CircleCI 根据项目文件夹中的配置文件执行工作流。 在此步骤中,您将创建该文件以定义部署工作流。

在项目的根目录中创建一个名为 .circleci 的文件夹:

mkdir .circleci

在其中添加一个名为 config.yml 的新文件:

nano .circleci/config.yml

这将打开一个带有 YAML 文件扩展名的文件。 YAML 是一种经常用于配置管理的语言。

将以下配置添加到新的 config.yml 文件中:

circleci-test/.circleci/config.yml

version: 2.1

# Define the jobs we want to run for this project
jobs:
  pull-and-build:
    docker:
      - image: arvindr226/alpine-ssh
    steps:
      - checkout
      - run: ssh -oStrictHostKeyChecking=no -v $USER@$IP "./deploy.sh"

# Orchestrate our job run sequence
workflows:
  version: 2
  build-project:
    jobs:
      - pull-and-build:
          filters:
            branches:
              only:
                - main

保存此文件并退出文本编辑器。

该文件告诉 CircleCI 管道以下内容:

  • 有一个名为 pull-and-build 的作业,其步骤包括启动 Docker 容器 ,从它通过 SSH 连接到 VPS,然后运行 deploy.sh 文件。
  • Docker 容器的目的是创建一个临时环境来执行配置的 steps 部分中提到的命令。 在这种情况下,您只需 SSH 进入 VPS 并运行 sh deploy.sh 命令,因此环境需要轻量级但仍允许 SSH 命令。 Docker 镜像 arvindr226/alpine-ssh 是一个支持 SSH 的 Alpine Linux 镜像。
  • deploy.sh 是您将在 VPS 中创建的文件。 它将作为部署过程的一部分每次运行,并将包含特定于您的项目的步骤。
  • workflows 部分中,您通知 CircleCI 它需要根据一些过滤器执行此作业,在这种情况下,只有对主分支的更改才会触发此作业。

接下来,您将提交这些文件并将其推送到 GitHub 存储库。 您将通过从项目目录运行以下命令来执行此操作。

首先,将 Node.js 项目目录初始化为 git repo:

git init

继续并将新的更改添加到 git repo:

git add .

然后提交更改:

git commit -m "initial commit"

如果这是第一次提交,git 会提示你运行一些 git config 命令来识别你。

从您的浏览器导航到 GitHub 并使用您的 GitHub 帐户登录。 创建一个名为 circleci-test 的新存储库,无需 README 或许可证文件。 创建存储库后,返回命令行将本地文件推送到 GitHub。

要遵循 GitHub 协议,请使用以下命令重命名您的分支 main

git branch -M main

在首次推送文件之前,您需要将 GitHub 添加为远程存储库。 通过运行来做到这一点:

git remote add origin https://github.com/GitHub_username/circleci-test

使用 push 命令执行此操作,这会将文件传输到 GitHub:

git push -u origin main

您现在已将代码推送到 GitHub。 在下一步中,您将在 VPS 中创建一个新用户,该用户将执行 pull-and-build 部分中的 steps

第 3 步 — 为部署创建新用户

现在您已经准备好项目,您将在 VPS 中创建一个部署用户。

sudo 用户身份连接到您的 VPS

ssh your_username@your_server_ip

接下来,使用 useradd 命令创建一个不使用密码登录的新用户。

sudo useradd -m -d /home/circleci -s /bin/bash circleci

此命令在系统上创建一个新用户。 -m 标志指示命令创建由 -d 标志指定的主目录。

在这种情况下,circleci 将是新的部署用户。 出于安全考虑,您不会将此用户添加到 sudo 组,因为此用户的唯一工作是创建从 VPS 到 CircleCI 网络的 SSH 连接并运行 [X198X ] 脚本。

确保您的 VPS 上的防火墙对端口 8080 开放:

sudo ufw allow 8080

您现在需要创建一个 SSH 密钥,新用户可以使用它来登录。 您将创建一个没有密码的 SSH 密钥,否则 CircleCI 将无法解密它。 您可以在 官方 CircleCI 文档 中找到更多信息。 此外,CircleCI 期望 SSH 密钥的格式为 PEM 格式,因此您将在创建密钥对时强制执行该格式。

回到您的本地系统,移动到您的主文件夹:

cd

然后运行以下命令:

ssh-keygen -m PEM -t rsa -f .ssh/circleci

此命令使用 -m 标志指定的 PEM 格式和 -t 标志指定的密钥类型创建 RSA 密钥。 您还可以指定 -f 来创建一个名为 circlecicircleci.pub 的新密钥对。 指定名称将避免覆盖现有的 id_rsa 文件。

打印出新的公钥:

cat ~/.ssh/circleci.pub

这将输出您生成的公钥。 您需要在您的 VPS 中注册此公钥。 将此复制到剪贴板。

回到 VPS,为 circleci 用户创建一个 .ssh 目录:

sudo mkdir /home/circleci/.ssh

在这里,您将从本地计算机复制的公钥添加到名为 authorized_keys 的文件中:

sudo nano /home/circleci/.ssh/authorized_keys

在此处添加复制的公钥,保存文件,然后退出文本编辑器。

circleci 用户授予目录权限,使其在部署期间不会遇到权限问题。

sudo chown -R circleci:circleci /home/circleci

验证您是否可以使用私钥以新用户身份登录。 在本地系统上打开一个新终端并运行:

ssh 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-testSet Up Project。 这将带您进入项目设置页面:

您现在可以选择为项目设置配置,您已经在存储库中设置了该配置。 由于已经设置好了,请选择 Use Existing Config 选项。 这将弹出一个弹出框,确认您要构建管道:

从这里,继续并单击 开始构建 。 这将带您进入 circleci-test 管道页面。 目前,此管道将失败。 这是因为您必须首先更新项目的 SSH 密钥。

导航到 https://app.circleci.com/settings/project/github/your_username/circleci-test 处的项目设置,然后选择左侧的 SSH 密钥 部分。

通过运行以下命令从本地计算机检索您之前创建的名为 circleci 的私钥:

cat ~/.ssh/circleci

复制此命令的输出。

Additional SSH Keys 部分下,单击 Add SSH Key 按钮。

这将打开一个窗口,要求您输入主机名和 SSH 密钥。 输入您选择的主机名,并添加您从本地环境复制的私有 SSH 密钥。

CircleCI 现在可以使用此密钥作为新的 circleci 用户登录到 VPS。

最后一步是向 CircleCI 提供 VPS 的用户名和 IP。 在同一个项目设置页面,进入左侧的环境变量选项卡:

添加一个名为 USER 的环境变量,其值为 circleciIP 的值为您的 VPS 的 IP 地址(或您的 VPS 的域名,如果您有 DNS 记录)。

创建这些变量后,您就完成了 CircleCI 所需的设置。 接下来,您将授予 circleci 用户通过 SSH 访问 GitHub 的权限。

第 5 步 — 将 SSH 密钥添加到 GitHub

您现在需要提供一种方法,使 circleci 用户可以通过 GitHub 进行身份验证,以便它可以执行 git 操作,如 git pull

为此,您将为该用户创建一个 SSH 密钥以针对 GitHub 进行身份验证。

circleci 用户连接到 VPS:

ssh circleci@your_server_ip -i ~/.ssh/circleci

创建一个没有密码的新 SSH 密钥对:

ssh-keygen -t rsa 

然后输出公钥:

cat ~/.ssh/id_rsa.pub

复制输出,然后转到 circleci-test GitHub 存储库 https://github.com/your_username/circleci-test/settings/keys 的部署密钥设置。

点击 Add deploy key 添加复制的公钥。 用您想要的密钥名称填写 Title 字段,然后在 Key 字段中添加复制的公钥。 最后,点击添加密钥按钮将密钥添加到您的帐户。

现在 circleci 用户可以访问您的 GitHub 帐户,您将使用此 SSH 身份验证来设置您的项目。

第 6 步 — 在 VPS 上设置项目

现在设置项目,您将克隆存储库并以 circleci 用户身份在 VPS 上进行项目的初始设置。

在您的 VPS 上,运行以下命令:

git clone git@github.com:your_username/circleci-test.git

导航到它:

cd circleci-test

首先,安装依赖项:

npm install

现在通过运行您构建的服务器来测试应用程序:

node app.js

转到您的浏览器并尝试地址 http://your_vps_ip:8080。 您将收到输出 Hello World!

使用 CTRL+C 停止此进程并使用 pm2 将此应用程序作为后台进程运行。

安装 pm2 以便您可以将 Node 应用程序作为独立进程运行。 pm2 是一个用 Node.js 编写的多功能进程管理器。 在这里,它将帮助您保持示例 Node.js 项目作为活动进程运行,即使在您注销服务器后也是如此。 您可以在 How To Set Up a Node.js Application for Production on Ubuntu 18.04 教程中了解更多相关信息。

npm install -g pm2

注意: 在某些系统上,例如Ubuntu 18.04,全局安装npm包会导致权限错误,从而中断安装。 由于避免将 sudonpm install 一起使用是一种安全最佳实践,因此您可以通过更改 npm 的默认目录来解决此问题。 如果遇到 EACCES 错误,请按照 npm 官方文档 中的 说明进行操作。


您可以使用 pm2 start 命令将 app.js 文件作为 Node 进程运行。 您可以使用 --name 标志将其命名为 app 以便稍后识别它:

pm2 start app.js --name "app"

您还需要提供部署说明。 每次 circleci 用户部署代码时,这些命令都会运行。

回到主目录,因为这将是 circleci 用户在成功登录尝试期间登陆的路径:

cd ~

继续创建 deploy.sh 文件,其中将包含部署说明:

nano deploy.sh

您现在将使用 Bash 脚本 来自动化部署:

部署.sh

#!/bin/bash

#replace this with the path of your project on the VPS
cd ~/circleci-test

#pull from the branch
git pull origin main

# followed by instructions specific to your project that you used to do manually
npm install
export PATH=~/.npm-global/bin:$PATH
source ~/.profile

pm2 restart app

这将自动将工作目录更改为项目根目录,从 GitHub 拉取代码,安装依赖项,然后重新启动应用程序。 保存并退出文件。

通过运行使该文件成为可执行文件:

chmod u+x deploy.sh

现在回到您的本地机器并快速更改以对其进行测试。 切换到你的项目目录:

cd circleci-test

打开你的 app.js 文件:

nano circleci-test/app.js

现在添加以下突出显示的行:

circleci-test/app.js

const http = require('http');

http.createServer(function (req, res) {
  res.write('Foo Bar!');
  res.end();
}).listen(8080, '0.0.0.0');

保存文件并退出文本编辑器。

添加此更改并提交:

git add .
git commit -m "modify app.js"

现在将其推送到您的主分支:

git 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 文档