在 GitLab CI/CD 中通过 SCP 部署运行 Composer 和 npm 脚本
- Tier: Free, Premium, Ultimate
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
本指南介绍如何使用 GitLab CI/CD 通过 npm 脚本编译资源,同时构建 PHP 项目的依赖。
虽然您可以创建包含自定义 PHP 和 Node.js 版本的自定义镜像,但为简洁起见,我们使用一个现成的 Docker 镜像,该镜像已安装了 PHP 和 Node.js。
image: tetraweb/php下一步是安装 zip/unzip 包并使 composer 可用。我们将这些操作放在 before_script 部分:
before_script:
- apt-get update
- apt-get install zip unzip
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php composer-setup.php
- php -r "unlink('composer-setup.php');"这确保我们已准备好所有必需的依赖项。接下来,运行 composer install 获取所有 PHP 依赖项,运行 npm install 加载 Node.js 包。然后运行 npm 脚本。我们需要将它们添加到 before_script 部分:
before_script:
# ...
- php composer.phar install
- npm install
- npm run deploy在这个特定情况下,npm deploy 脚本是一个 Gulp 脚本,执行以下操作:
- 编译 CSS 和 JS
- 创建精灵图
- 复制各种资源(图片、字体)
- 替换某些字符串
所有这些操作都将所有文件放入一个 build 文件夹中,该文件夹已准备好部署到生产服务器。
如何将文件传输到生产服务器
您有多种选择,如 rsync、SCP 或 SFTP。现在,我们使用 SCP。
要实现此功能,您必须添加一个 GitLab CI/CD 变量(可在 gitlab.example/your-project-name/variables 访问)。将此变量命名为 STAGING_PRIVATE_KEY,并将其设置为服务器的 私有 SSH 密钥。
安全提示
创建一个只能访问需要更新的文件夹的用户。
创建该变量后,确保在运行时将密钥添加到 Docker 容器中:
before_script:
# - ....
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- mkdir -p ~/.ssh
- eval $(ssh-agent -s)
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'按顺序,这意味着:
- 我们检查
ssh-agent是否可用,如果不可用则安装它。 - 我们创建
~/.ssh文件夹。 - 我们确保正在运行 bash。
- 我们禁用主机检查(当我们首次连接到服务器时,不会要求用户接受, 因为每个作业都相当于首次连接,所以我们需要这样做)。
这基本上就是您在 before_script 部分所需的所有内容。
如何部署
如前所述,我们需要将 Docker 镜像中的 build 文件夹部署到我们的服务器。为此,我们创建一个新作业:
stage_deploy:
artifacts:
paths:
- build/
rules:
- if: $CI_COMMIT_BRANCH == "dev"
script:
- ssh-add <(echo "$STAGING_PRIVATE_KEY")
- ssh -p22 server_user@server_host "mkdir htdocs/wp-content/themes/_tmp"
- scp -P22 -r build/* server_user@server_host:htdocs/wp-content/themes/_tmp
- ssh -p22 server_user@server_host "mv htdocs/wp-content/themes/live htdocs/wp-content/themes/_old && mv htdocs/wp-content/themes/_tmp htdocs/wp-content/themes/live"
- ssh -p22 server_user@server_host "rm -rf htdocs/wp-content/themes/_old"以下是详细说明:
rules:if: $CI_COMMIT_BRANCH == "dev"表示此构建仅在推送内容到dev分支时运行。您可以完全删除此块,让每次推送都运行所有内容(但这可能不是您想要的)。ssh-add ...我们将您在 Web UI 中添加的私钥添加到 Docker 容器中。- 我们通过
ssh连接并创建一个新的_tmp文件夹。 - 我们通过
scp连接并将build文件夹(由npm脚本生成)上传到我们之前创建的_tmp文件夹。 - 我们再次通过
ssh连接并将live文件夹移动到_old文件夹,然后将_tmp移动到live。 - 我们连接到 SSH 并删除
_old文件夹。
artifacts 是什么意思?我们告诉 GitLab CI/CD 保留 build 目录(稍后您可以根据需要下载)。
为什么我们这样做
如果您仅将此用于暂存服务器,可以分两步完成:
- ssh -p22 server_user@server_host "rm -rf htdocs/wp-content/themes/live/*"
- scp -P22 -r build/* server_user@server_host:htdocs/wp-content/themes/live问题是,在某个时间段内,您的服务器上没有应用程序。
因此,对于生产环境,我们使用额外的步骤来确保在任何给定时间都有可用的应用程序。
下一步去哪里
由于这是一个 WordPress 项目,它包含真实的代码片段。您可以探索的一些进一步想法:
- 为默认分支使用略有不同的脚本,允许您从该分支部署到生产服务器,从任何其他分支部署到暂存服务器。
- 与其直接推送上线,您可以将其推送到 WordPress 官方仓库。
- 您可以动态生成国际化文本域。
我们的最终 .gitlab-ci.yml 文件如下所示:
stage_deploy:
image: tetraweb/php
artifacts:
paths:
- build/
rules:
- if: $CI_COMMIT_BRANCH == "dev"
before_script:
- apt-get update
- apt-get install zip unzip
- php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
- php composer-setup.php
- php -r "unlink('composer-setup.php');"
- php composer.phar install
- npm install
- npm run deploy
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- mkdir -p ~/.ssh
- eval $(ssh-agent -s)
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- ssh-add <(echo "$STAGING_PRIVATE_KEY")
- ssh -p22 server_user@server_host "mkdir htdocs/wp-content/themes/_tmp"
- scp -P22 -r build/* server_user@server_host:htdocs/wp-content/themes/_tmp
- ssh -p22 server_user@server_host "mv htdocs/wp-content/themes/live htdocs/wp-content/themes/_old && mv htdocs/wp-content/themes/_tmp htdocs/wp-content/themes/live"
- ssh -p22 server_user@server_host "rm -rf htdocs/wp-content/themes/_old"