CI/CD さくらVPS Docker Git

GithubのActionsでdocker-composeの内容をさくらVPSにデプロイしてみた

どうも、シローです。

ここ最近は個人サービスの開発をしてました。
作ったのはこちら=>Emovee(https://emovee.org)

そこで今回は、GithubのActionを使ったCI/CDについてのお話をしようと思います。

GithubのActionsとは

ブランチに対するpushやPR(pull request)を送ったのをトリガーとして、

  • ソースコードのビルドやテスト
  • 運用環境に対するデプロイ

を行なってくれます。

ちなみに、このような機能をCI/CDと言われます。

公式(https://github.co.jp/features/actions)

Actionsのワークフローの書き方

ビルドやデプロイをまとめた一連の処理の流れをワークフローと呼びます。

ワークフローの設定方法は

  1. プロジェクトの「Actions」をクリック
  2. 「New Workflow」をクリック
  3. テンプレートを選択するか、自分で一から記述したい場合は「Set up a workflow yourself」をクリック
  4. 「Start Commit」を選択してプロジェクトのディレクトリの該当ブランチに「.github/workflows/xxx.yml」ファイルを作成する
  5. ローカル環境でブランチを最新にして「.github/workflows/xxx.yml」を編集する

もしくは、直接プロジェクトのディレクトリに「.github/workflows/xxx.yml」というファイルを作成してそれを編集することになります。

公式 => (https://docs.github.com/ja/actions/quickstart)

今回のCI/CDの対象となるプロジェクトの構成

リリースしたEmoveeというサービスは

  • サーバサイド:Laravel6
  • フロントサイド:Next.js
  • データベース:MySQL5.8
  • リバースプロキシ:Nginx

という構成で動かしてます。

ちなみ、LaravelとNext.jsの環境構築のリポジトリはこちらです=>(https://github.com/smithshiro/docker-adramelech)

もしよければこちらもご参考までに🙌

構成図

ワークフローの流れ

上記のアプリケーションをさくらVPSにデプロイするまでの流れをまとめると次のようになりました。

  1. CI/CDで使うPHPのバージョンをコンテナ(PHP-fpm)で使っているバージョンに合わせる
  2. docker-compose.yml、Next.js、Laravelで使用している環境変数ファイル「.env」を本番用に差し替える
  3. Laravelのソース配下でcomposerパッケージを更新して、vendorフォルダを生成する
  4. Next.jsのソース配下でnpmパッケージを更新して、node_modulesを最新にしてソースコードをビルドする
  5. デプロイ先のサーバに接続するためのSSHキーを取得する
  6. rsyncコマンドを使用して、2,3,4でビルドしたソースコードをデプロイ先のサーバに転送する
  7. デプロイ先のサーバでdocker-compose build + runを実行するためのスクリプトを起動させる

ワークフローのソースコードの中身

実際に今回僕が記述したワークフローのソースコードはこちらです。

PHPのバージョンをDockerのコンテナ内で使用しているバージョン(7.4.22)に合わせる

composerでパッケージをインストールするときにcomposer.lock、composer.jsonで指定されているPHPのバージョンとずれていると「composer install」でエラーが起きますので、

「Setup PHP」で実行するPHPのバージョンを"7.4.22"に設定しました。

ワークフローの個々のステップは次のような構文になりまして、今回は第三者が作ったステップを利用するため「uses: shivammathur/setup-php@v2」としています。

ステップの構文

環境変数ファイルを本番用にセットする

このプロジェクトでは

docker-compose

  • MySQLのパスワード

Next.js

  • ホスティングしているURLのホスト

Laravel

  • MySQLの接続情報
  • 外部API接続のキー情報

などを開発環境と本番環境で違うため、

本番用の環境変数を「config」ディレクトリに格納して、デプロイ時に本番用の「.env」ファイルを生成しています。(.gitigoreで.envはソース管理されないようにしています)

そのため、「set env file」のステップではそれらの環境変数をセットするための記述をしています。

Laravelの「vendor」フォルダ、Next.jsのビルド用の「.next」フォルダの生成

Laravelの「vendor」フォルダ、Next.jsの「.next」フォルダは.gitignoreに追加されていないため、

デプロイ先で生成されている必要があります。

ここでは、CI/CDの段階でそれらのフォルダを生成するようにしています。

理由としては主に、サーバにデプロイ後に生成したすると実運用している環境でビルドに失敗すると利用できなくなる状態になってしまうリスクがあるためです。

そのため、ワークフロー内でビルドを成功させたものを後の「rsync」でデプロイ先のサーバに転送するようにしました。

デプロイ先のサーバに接続するための情報をSecretsから読み取る

デプロイ先のサーバにはSSHで接続します。

そのため、該当サーバにアクセスするためのIPアドレスや、プライベートキーをGithubの「Settings」=> 「Secrets」に設定した内容を読み込みます。

読み込み方は ${{ secrets.環境引数名 }}とすれば良いです。

この例では「Install SSH Key」というステップでSSHキーを読み込んで、以降のステップで利用できるようにしています。

設定箇所

rsyncで生成したファイル群をデプロイ先のサーバに転送する

rsyncコマンドを使って前のステップで環境変数ファイル「.env」やLaravelの「vendor」、Next.jsの「.next」をまとめたソースコードをデプロイ先のサーバに転送します。

rsyncで転送するときに、

  • 転送から除外するディレクトリの指定
  • 転送するときのオプション指定

でつまずきました。

”転送から除外するディレクトリの指定”ではMySQLのデータベースの中身(docker/mysql/data*)、node_modulesの中身を除外するようにしています。

特にnode_modulesのディレクトリをそのまま転送しますと、時間が非常にかかりますので個人的には指定必須です。

また、オプションですが色々あって「-rlOtcv」となりました。詳しい意味はちょっと忘れましたがこれでうまく行ったのです。

デプロイ先のサーバにSSHして、「docker-compose build」、「docker-compose up -d」を実行する

ここまでの流れでソースコードをビルドしたものをデプロイ先のサーバに転送はできました。

なので最終ステップとして、最新になったDocker環境とソースコードでプロジェクトを再起動する必要があります。

その一連の流れをスクリプトとして「deploy_scripts/prod_deploy.sh」に記述して、SSHで接続した先でこれを実行するようにします。

deploy_scripts/prod_deploy.sh

SSHでスクリプトを実行

 

以上の流れでdocker-composeで構築したローカルの環境をGithubのActionsでデプロイ先のサーバで動かすことができました。

おっしまい^^

まとめ

  • GithubのActionsではソースへのプッシュやPRをトリガーとしてソースのビルドやデプロイができる
  • ビルドやデプロイの流れをワークフローという
  • デプロイ先のサーバにソースを反映させるためには、ソースのビルド => rsyncで転送 => 再起動用のスクリプトを起動 という手順で可能

 

  • この記事を書いた人

シロー

Webシステムの開発のお仕事をさせて頂いております。 フリーランスの日常、Web開発に関する情報を発信しています。 趣味はゲーム、映画鑑賞、個人サービスを作ることです。

-CI/CD, さくらVPS, Docker, Git

© 2021 Shiro's secret base