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"