こんにちは、最近YouTuberになったあんちぽです。今日はですね、弊社の提供しているレンタルサーバー(ロリポップ!、ヘテムル)を、GitHub Actionsを使ってもっと便利にしよう!という話をしたいと思います。
この記事の対象読者
以下の内容を満たす方々を対象読者として想定しています。
- ロリポップ!やヘテムルといったレンタルサーバーを使っている方
- Webサイトの開発・制作をされている方(趣味・仕事を問いません)
- Gitを使っているがCI/CDは実践しておらず、開発・制作フローを効率化したい方
この記事を読むとできるようになること
- 手元で開発した変更をGitHubにpushしたら、自動的に本番環境(ロリポップ!やヘテムル)へリリースできるようになります
- Hugoを使ったより複雑なサイトについても、GitHub Actionsを使ってリリースの自動化ができるようになります
- ワークフローを自動化することで、属人性を排除したリリース作業を実現し、パスワードのような秘匿情報を安全に管理できるようになります
ロリポップ!やヘテムルのようなレンタルサーバーを使ったWeb開発・制作も、GitHub Actionsのような最新技術を用いることで、とても便利になります。是非、お試しください。
昨今のWeb開発のキーワード: CI/CD
昨今のWeb開発(だけじゃないですが)の流れとして、CI/CDというようなことがいわれて久しいですね、。Continuous IntegrasionおよびContinuous Deliveryの略称です。どちらもContinuous(=継続的)とあるように、開発からリリースまでの流れをフェーズごとに分断するのではなく、つねに継続的につながっていくものとしてとらえようという考え方です。
そこで重要になるのが自動化です。コードを書いてテストしてリリースして……という流れを 、できるだけひとつながりの営みとして実現するには、フェーズのつなぎを自動化することが欠かせません。そんな時に便利なのがGitHub Actionsです。これまで、様々な技術的な工夫やツール等を組み合わせて実現していた自動化が、この仕組みひとつで実現できます。
GitHub Actionsを使うメリット
コード管理にGit等のバージョン管理システムを使うというのは、もはや広く行われていることと思います。Web開発・制作会社さんも、近年は案件でGitHubを使うことが多いことでしょう。バージョン管理システムやGitHubを使うことのメリットは、もはや自明だといえます。GitHub上でコード管理をしているならば、GitHub Actionsも是非使ってみましょう。
GitHubを使ってチーム開発をしているとします。手元で開発したコードを本番コードに取り込む際に、Pull Requestを立てて、チームメンバーにレビューをしてもらいますよね。その際、コードの内容をじっくり見る前に、テストが壊れていないかどうかをまず確認したいところです。GitHub Actionsを使えば、Pull Requestへのテストの実行も自動的に行なえます(もちろん、GitHub Actions以前もできましたが、より簡便にできるようになったということです)。
レビューが終わり、本番コードへマージすることができました。本番環境(あるいは、その前のステージング環境等)へのリリース作業が必要になりますね。レンタルサーバーを利用している方の場合、FTPS/SFTPによってリリースすることも多いでしょう。その際、「誰がリリース権限を持っているのか?」「リリースする順番は?」「リリース忘れはない?」など、考えるべきことがあれこれあります。また、Git上で誤ったコードをrevert(巻き戻し)したのに、リリースをわすれてしまった!なんてことも防ぐ必要がありますね。GitHub Actionsで自動化してしまいましょう。
このように、Web開発におけるCI/CDを実現するためにGitHub Actionsはとても便利です。
GitHub Actionsをとりあえず使ってみる
HTMLファイルが一枚だけのシンプルな例
本記事では、GitHub Actionsの用途として使われることが最も多いであろう、コードの本番環境へのリリースにフォーカスして、みていきます。想定しているのは、以下のような流れです(もちろん、実際のWeb開発・制作現場ではもっと複雑なフローがあると思いますが、簡単のためにポイントのみを取り上げます。そのため、Pull Requestを作ることをせず直接masterにpushするフロー(!)で説明します)。
- 手元でコードを書いて、ローカルリポジトリのmasterブランチにコミットする
- GitHub上のリポジトリの、masterブランチにpushする
- pushされたコードを、本番環境にFTPを通じてリリースする
まずはシンプルに、HTMLを手書きしたindex.html
が一枚あるだけ、というリポジトリを例に説明します。以下のような感じです。
├── .github
│ └── workflows
│ └── lolipop.yml
└── public
└── index.html
ご覧の通り、コンテンツは、public/index.html
のみです(その他のファイルについては、後述)。この内容を更新して、本番環境へリリースしたい場合を想定します(コードをkentaro/lolipop-gh-actionsに公開していますので、そちらもご参照ください)。
GitHub Actionsで使うワークフローの中身
GitHub Actionsを使うには、リポジトリ内に.github/workflows
というディレクトリを作り、その中にイベント発生時(Pull Requestの作成、コードのpush等)に起こしたいアクションを書いていくことになります。この例では、以下のワークフローを定義しています。
- GitHub上のリポジトリのmasterブランチにコードがpushされたら
- リポジトリからコードをチェックアウトしてきて
- FTPを使って、指定されたサーバにコードをリリースする
いろいろ書かれていますが、やっていることは簡単ですね。自らいつもやっていることをワークフローとして書き出すことで、リリース作業を自動化できるのがすごいところです。
さて、こんなYAMLフォーマットでこんなファイルを書きました。
name: lolipop
on:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy via FTP
uses: SamKirkland/FTP-Deploy-Action@3.0.0
with:
ftp-server: ${{ secrets.FTP_HOST }}
ftp-username: ${{ secrets.FTP_USERNAME }}
ftp-password: ${{ secrets.FTP_PASSWORD }}
git-ftp-args: --remote-root ${{ secrets.FTP_REMOTE_ROOT }}
local-dir: public
上から読んでいくと、さきほど説明したワークフローにそった内容になっていることが見て取れるでしょう。FTPアップロードをする箇所は、SamKirkland/FTP-Deploy-Actionという便利なものを作った方がいらっしゃるので、ありがたく使わせてもらうことにします。
ちなみに上記のファイルの最後あたりにsecrets.FTP_***
という記述がありますが、詳しくは後述するとして、git-ftp-args: --remote-root ${{ secrets.FTP_REMOTE_ROOT }}
という設定内容は、FTPサーバー上のどのディレクトリにファイルをアップロードしたいかを指定する項目です。その他の内容は、そのまんまの意味ですので、解説は不要でしょう。
秘匿情報の管理と利用
直前に見た通り、ファイルの中にsecrets.FTP_***
という記述がありますね。特に、パスワードのような秘密にしておくべき情報は、コードに書き込むようなことはしてはなりません。そこで、${{ secrets.FTP_PASSWORD }}
ような形であらかじめ設定した値を読み込むようにすることで、秘匿情報を適切に管理できます。また、プロジェクトの管理者が一度設定しておけば、他の人も(中身をみることなく)情報を利用することが出来ます。このようにワークフローを自動化することは、情報セキュリティ上も有効です。
その秘密情報は、設定画面(Settings
→Secrets
とリンクをたどってください)から設定します。この場合はFTPサーバのユーザ名、パスワード、どのディレクトリに置くかを設定しています。ロリポップであれば、ロリポップ!ユーザー専用ページ - アカウント情報から参照できます。
設定が完了したら、以下の画面のように表示されるでしょう。
コードの変更をpushし、本番へリリースする
さて、コードの変更が終わったら、GitHubへpushしましょう。そうすると、Actionタブからたどれるページにおいて、以下のようにワークフローが起動したことを確認できます。
上記のリンクをたどってワークフローの詳細にはいっていきます。YAMLファイルで定義したアクションがどんどん実行されていく様子を確認できます。しばらく待っていると、以下のようにエラーなく完了しました。
もしエラーがでた場合は、▶
ボタンをクリックすることで、エラーの原因を知ることができます。自分でいちからワークフローを書いた場合はエラーになることが多いので、よく確認しましょう。また、ワークフローを初めてpushしたコミットではそのワークフローの記述は実行されないので、ワークフローのpushは前もって行うようにしましょう(ハマりがちなポイントです)。
というわけで、ごく簡単なページではありますが、コードの変更から本番へのリリース(この場合はロリポップ!のサーバー)まで、GitHub Actionsで自動化することができました!
Hugoで作ったサイトをGitHub Actionsでリリースする
ここまでは、手書きのHTML1枚によるごくシンプルなWebサイトを例に説明しました。昨今では、スタティックサイトジェネレーターを用いてWebサイトを作ることが多くなっていると思います(このブログもそのようなツールのひとつであるmiddlemanを用いて作られています)。そこで、次は広くスタティックサイトジェネレーターのひとつHugoを用いる例を簡単に紹介します。
スタティックサイトジェネレーターの仕組み
スタティックサイトジェネレーターとはなんでしょうか?たとえばWordPressのようなWebアプリケーション、すなわち動的なサイトは、URLへのリクエストに応じてコンテンツをHTMLとして構築し、ブラウザに対して応答します。スタティックサイトジェネレーターは、あらかじめあり得るコンテンツをすべて前もって作っておくことで、コンテンツの表現能力を動的サイトに近いレベルで実現するとともに、配信されるのはHTMLのみであるためサーバ負荷にもやさしい仕組みです。そのため、レンタルサーバーにおいて利用するのに向いています。
Webサイトの開発・制作にHugoを用いる例
では、さっそくHugoを使った例をみていきましょう。Hugoのクイックスタートガイドを上から実行していくと、以下のようなディレクトリ構造ができます。
├── .git-ftp-include
├── .github
│ └── workflows
│ └── lolipop.yml
├── .gitmodules
├── archetypes
│ └── default.md
├── config.toml
├── content
│ └── posts
│ └── my-first-post.md
├── data
├── layouts
├── public
└── static
ここではGitHub Actionsによるワークフローの例を示すだけなので、上記の細かい内容は特に気にする必要はありません。実際にHugoを用いて制作を始める際には、クイックスタート等、公式ドキュメントを参照してください(デプロイする前にmy-first-post.md
のdraft: false
という箇所をtrue
にしないと、コンテンツがデプロイされないので、実際に試す方は気をつけてください)。
(コードをkentaro/lolipop-gh-actions-hugoに公開していますので、そちらもご参照ください)。
GitHub Actionsで使うワークフローの中身
Hugoを用いるといっても、ざっくり見る分には、さきほどのシンプルな例と大きく変わるわけではありません。コードの変更からリリースまでのワークフローをあらためて整理しましょう(今回もあれこれはしょって、masterブランチに直接pushする流れで例示します)。
- 手元でコードを書いて、ローカルリポジトリのmasterブランチにコミットする
- GitHub上のリポジトリの、masterブランチにpushする
- pushされたコードを、スタティックサイトジェネレーターでビルドする
- ビルドにより作成されたWebサイトを、本番環境にFTPを通じてリリースする
あらたに追加されたフローは3番目の内容のみです(4番目では、ビルドされた内容をリリースするところだけが異なります)。
Hugoを始めとするスタティックサイトジェネレーターによるWebサイト開発・制作の特徴は、上述のフローで「3. pushされたコードを、スタティックサイトジェネレーターでビルドする」とある通り、「ビルド」というフローが入るということです。
ビルドとは、Webサイトの中身となるコンテンツ(上記の例だとcontent/posts/my-first-post.md
)、WebサイトのテンプレートやCSS、JavaScriptファイル等を、スタティックサイトジェネレーターによってひとつのWebサイトとしてまとめあげる工程です。そして、実際に本番サーバーにリリースするのはできあがったWebサイトのみであり、開発・制作につかった素材としてのファイルはアップロードしません。
以下が、Hugoを使ったWebサイトを、FTPを通じてデプロイするワークフローの例です。ポイントとしては、サイトのビルドのためにpeaceiris/actions-hugoというサードパーティのアクションを用いている点と、さきほどの例と同様に、最後でFTPを通じて本番サーバーにデプロイしているところです。
name: lolipop
on:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Checkout submodules
shell: bash
run: |
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: latest
- name: Build
run: hugo --minify
- name: Deploy via FTP
uses: SamKirkland/FTP-Deploy-Action@3.0.0
with:
ftp-server: ${{ secrets.FTP_HOST }}
ftp-username: ${{ secrets.FTP_USERNAME }}
ftp-password: ${{ secrets.FTP_PASSWORD }}
git-ftp-args: --remote-root ${{ secrets.FTP_REMOTE_ROOT }}
local-dir: public
それぞれで何をやっているのかについて細かくは説明しません。それぞれのライブラリのドキュメントを参照してください。ここでも、secrets.FTP_PASSWORD
等の内容を参照しています。あらかじめ設定画面から設定しておきましょう。
ワークフローの実行結果については、先述のシンプルな例とほぼ同様なので、説明を省略します。
HugoによるサイトをFTPアップロードする際の注意点
ところで、実際に試すとハマるひとがきっと出てくると思うので、注意点について少し書いておきます。さきほど、実際にサーバーにアップロードするのはできあがったWebサイトそのもののみであると書きました。Hugoを使う場合、その最終的な成果物としてのWebサイトはpublic
ディレクトリに生成されます。そのため、上記のワークフローでは最後にlocal-dir: public
という設定を追加しています。
注意すべきポイントがもう一点あります。スタティックサイトジェネレーターを使った制作では、一般に、ビルドによってできあがる内容はGitにコミットしません。そのため、このワークフローで用いているライブラリでデプロイする際には、リポジトリにコミットされていないファイルをデプロイ対象とする設定を追加する必要があります。そのためには、.git-ftp-include
というファイルにpublic
ディレクトリを指定してください。詳細についてはドキュメントを参照してください。
おわりに
本記事では、昨今のWeb開発・制作において必須の考え方・実践であるCI/CDを実現する仕組みとしてのGitHub Actionsを用いて、ロリポップ!やヘテムルといったレンタルサーバを利用するWebサイト開発・制作を効率化する方法について解説しました。
- 手元で開発した変更をGitHubにpushしたら、自動的に本番環境(ロリポップ!やヘテムル)へリリースできるようになりました
- Hugoを使ったより複雑なサイトについても、GitHub Actionsを使ってリリースの自動化ができるようになりました
- ワークフローを自動化することで、属人性を排除したリリース作業を実現し、パスワードのような秘匿情報を安全に管理できるようになりました
非常に便利な仕組みですので、もし利用したことがなければ、是非お試しください。GitHub Actionsを使って、ロリポップ!とヘテムルによる効率的かつ安全なWeb開発・制作をよりお楽しみいただけることを願っています。