GitLab CI/CDでSCP経由のデプロイを伴うComposerとnpmスクリプトの実行
このガイドでは、GitLab CI/CDを使ってnpmスクリプトでアセットをコンパイルしながら、PHPプロジェクトの依存関係を構築する方法を説明します。
PHPとNode.jsのバージョンをカスタマイズして独自のイメージを作成することも可能ですが、ここでは簡潔にするためにPHPとNode.jsがインストールされた既存のDockerイメージを使用します。
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を実行していることを確認します。
- ホストチェックを無効にします(最初にサーバーに接続するときにユーザーのacceptを求めません。すべてのジョブが最初の接続に等しいので、これが必要です)。
そして、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 ...ウェブUIで追加した秘密鍵をDockerコンテナに追加します。
- 
ssh経由で接続し、新しい_tmpフォルダを作成します。
- 
scp経由で接続し、buildフォルダー(npmスクリプトによって生成されたもの)を、以前に作成した_tmpフォルダーにアップロードします。
- 
ssh経由で再度接続し、liveフォルダーを_oldフォルダーに移動し、_tmpをliveに移動します。
- SSHに接続し、_oldフォルダーを削除します。
アーティファクトはどうするの?GitLab CI/CDにbuild ディレクトリを保持するように伝えます(後で、必要に応じてダウンロードできます)。
なぜこのようにするのか
ステージ・サーバーだけに使うのであれば、2つのステップでできます:
- 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"
