{{< details >}}

  • Tier: 基础版, 专业版, 旗舰版
  • Offering: JihuLab.com, 私有化部署

{{< /details >}}

这篇指南涵盖了在使用 极狐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 脚本,执行以下操作:

  1. 编译 CSS 和 JS
  2. 创建精灵图
  3. 复制各种资源(图片、字体)
  4. 替换一些字符串

所有这些操作将所有文件放入一个 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'

顺序上,这意味着:

  1. 我们检查 ssh-agent 是否可用,如果不可用则安装它。
  2. 我们创建 ~/.ssh 文件夹。
  3. 我们确保正在运行 bash。
  4. 我们禁用主机检查(我们不要求用户在首次连接服务器时接受,因为每个作业都等于首次连接,我们需要这样做)。

这基本上就是您在 before_script 部分需要的全部内容。

如何部署

如上所述,我们需要将 build 文件夹从 Docker 镜像部署到我们的服务器。为此,我们创建一个新作业:

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"

以下是分解步骤:

  1. rules:if: $CI_COMMIT_BRANCH == "dev" 表示此构建仅在推送到 dev 分支时运行。您可以完全删除此块,使其在每次推送时运行(但可能这不是您想要的)。
  2. ssh-add ... 我们将您在 Web UI 上添加的私钥添加到 Docker 容器。
  3. 我们通过 ssh 连接并创建一个新的 _tmp 文件夹。
  4. 我们通过 scp 连接并将 build 文件夹(由 npm 脚本生成)上传到我们之前创建的 _tmp 文件夹。
  5. 我们再次通过 ssh 连接并将 live 文件夹移动到 _old 文件夹,然后将 _tmp 移动到 live
  6. 我们连接到 SSH 并删除 _old 文件夹。

产物是什么?我们告诉极狐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 官方库。
  • 您可以动态生成 i18n 文本域。

我们最终的 .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"