GitLab CI/CDでSCP経由のデプロイを伴うComposerとNPMスクリプトの実行
このガイドでは、GitLabCI/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/
only:
- 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"
内訳は以下の通り:
-
only:dev
は、dev
ブランチに何かがプッシュされたときにのみこのビルドが実行されることを意味します。 このブロックを完全に削除して、プッシュされるたびにすべてを実行させることもできます (しかし、おそらくこれは不要なことでしょう)。 -
ssh-add ...
ウェブUIで追加した秘密鍵をDockerコンテナに追加します。 -
ssh
経由で接続し、新しい_tmp
フォルダーを作成します。 -
scp
経由で接続し、(npm
スクリプトで生成された)build
フォルダを、以前に作成した_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のプロジェクトだったので、実際のコードスニペットをあげました。 さらに追求できるアイデアもあります:
-
master
ブランチ用に少し異なるスクリプトを用意しておくと、そのブランチから本番サーバーにデプロイしたり、他のブランチからステージサーバーにデプロイしたりできるようになります。 - ライブでプッシュする代わりに、(SVNコミットを作成するなどして)WordPress公式リポジトリにプッシュすることができます。
- その場で国際化テキストドメインを生成できます。
最終的な.gitlab-ci.yml
:
image: tetraweb/php
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'
stage_deploy:
artifacts:
paths:
- build/
only:
- 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"