Ubuntu16.04でGitフックを使用してJekyllサイトをデプロイする方法
著者は、 Diversity in Tech Fund を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。
序章
Jekyll は静的サイトジェネレーターであり、コンテンツ管理システム(CMS)の利点のいくつかを提供すると同時に、そのようなデータベース駆動型サイトによってもたらされるパフォーマンスとセキュリティの問題を回避します。 これは「ブログ対応」であり、日付で整理されたコンテンツを処理するための特別な機能が含まれていますが、その有用性はブログサイトに限定されません。 Jekyllは、オフラインで作業する必要があり、コンテンツのメンテナンスのためにWebフォームよりも軽量のエディターを好み、バージョン管理を使用してWebサイトへの変更を追跡したい人に最適です。
このチュートリアルでは、Nginxを使用してJekyllサイトをホストするように本番環境を構成し、Gitを使用して変更を追跡し、変更をサイトリポジトリにプッシュしたときにサイトを再生成します。 また、git-shell
をインストールして構成し、本番サーバーを不正アクセスからさらに保護します。 最後に、ローカル開発マシンを構成して、リモートリポジトリを操作し、変更をリモートリポジトリにプッシュします。
前提条件
このチュートリアルに従うには、次のものが必要です。
-
Ubuntu 16.04チュートリアルを使用した初期サーバーセットアップに従って構成された、本番用の1つのUbuntu16.04サーバー。
- Nginx、Ubuntu16.04チュートリアルにNginxをインストールする方法の最初の2つの手順に従ってインストールします。
- Jekyll、 Ubuntu16.04でJekyll開発サイトをセットアップする方法に従ってインストールされます。
-
Gitがインストールされた開発マシンと、 Ubuntu16.04チュートリアルでJekyll開発サイトをセットアップする方法に従って作成されたJekyllサイト。
-
オプションで、Jekyllについて詳しく知りたい場合は、次の2つのチュートリアルを確認できます。
- Jekyllのデフォルトコンテンツの調査。
- JekyllでのURLとリンクの制御。
ステップ1—Gitユーザーアカウントを設定する
セキュリティ上の理由から、JekyllサイトのGitリポジトリをホストするユーザーアカウントを作成することから始めます。 このユーザーはGitフックスクリプトを実行します。このスクリプトは、変更を受け取ったときにサイトを再生成するために作成します。 次のコマンドは、gitという名前のユーザーを作成します。
- sudo adduser git
パスワードを入力して繰り返してから、ユーザーに関する必須ではない基本情報を入力するように求められます。 最後に、Yと入力して情報を確認するように求められます。
OutputAdding user `git' ...
Adding new group `git' (1001) ...
Adding new user `git' (1001) with group `git' ...
Creating home directory `/home/git' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for git
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n]
また、生成されたサイトを保持するためのWebルートを準備します。 まず、/var/www/html
ディレクトリからデフォルトのWebページを削除します。
- sudo rm /var/www/html/index.nginx-debian.html
ここで、ディレクトリの所有権を git ユーザーに設定します。これにより、このユーザーは変更を受け取ったときにサイトのコンテンツを更新し、所有権をwww-data
グループにグループ化できます。 このグループは、Webサーバーが/var/www/html
にあるファイルにアクセスして管理できるようにします。
- sudo chown git:www-data /var/www/html
チュートリアルを続行する前に、SSHキーを新しく作成した git ユーザーにコピーして、Gitを使用して本番サーバーに安全にアクセスできるようにします。 これを行うには、Ubuntu16.04チュートリアルを使用したサーバーの初期設定のステップ4に従います。 最も簡単な方法はssh-copy-id
コマンドを使用することですが、手動でキーをコピーすることもできます。
次に、JekyllサイトのGitリポジトリを作成し、更新時に再構築するようにGitフックを構成しましょう。
ステップ2—Gitリポジトリを設定する
Gitリポジトリには、変更やコミットの履歴など、Gitサイトに関するデータが含まれます。 このステップでは、サイトを再生成する受信後フックを使用して、本番サーバーにGitリポジトリを設定します。
リポジトリはgitユーザーのホームディレクトリにあるため、前の手順の後でこのユーザーアカウントからログアウトした場合は、su
コマンドを使用して役割を切り替えます。
- su - git
ホームディレクトリに、Gitリポジトリを含むフォルダーを作成します。 ディレクトリがホームディレクトリにあり、repo-name.git
形式を使用して名前が付けられている必要があるため、git
コマンドで検出できます。 通常、repo-name
はサイトの名前である必要があるため、git
はサイトとリポジトリを簡単に認識できます。 私たちのサイトをsammy-blog
と呼びます。
- mkdir ~/sammy-blog.git
ディレクトリに切り替え、git init
コマンドを使用してGitリポジトリを初期化します。 --bare
フラグは、サーバーでホストするためのリポジトリを設定し、複数のユーザー間のコラボレーションを可能にします。
- cd ~/sammy-blog.git
- git init --bare
出力には、正常に初期化されたリポジトリに関する情報が含まれています。
OutputInitialized empty Git repository in /home/git/sammy-blog.git
このような出力が表示されない場合は、チュートリアルを続行する前に、画面上のログに従って問題を解決してください。
作成したフォルダには、リポジトリをホストするために必要なディレクトリとファイルが含まれています。 次のように入力すると、内容を確認できます。
- ls
Outputbranches config description HEAD hooks info objects refs
このタイプの出力が表示されない場合は、適切なディレクトリに切り替えて、git init
を正常に実行したことを確認してください。
hooks ディレクトリには、Gitフックに使用されるスクリプトが含まれています。 デフォルトでは、Gitフックのタイプごとにサンプルファイルが含まれているため、簡単に開始できます。 このチュートリアルでは、リポジトリが最新の変更で更新されたら、post-receiveフックを使用してサイトを再生成します。
hooks
ディレクトリにpost-receive
という名前のファイルを作成し、選択したテキストエディタで開きます。
- nano ~/sammy-blog.git/hooks/post-receive
最新の変更を一時ディレクトリに複製し、それを再生成して、生成されたサイトを/var/www/html
に保存するようにフックを構成して、簡単にアクセスできるようにします。
次のコンテンツをファイルにコピーします。
#!/usr/bin/env bash
GIT_REPO=$HOME/sammy-blog.git
TMP_GIT_CLONE=/tmp/sammy-blog
PUBLIC_WWW=/var/www/html
git clone $GIT_REPO $TMP_GIT_CLONE
pushd $TMP_GIT_CLONE
bundle exec jekyll build -d $PUBLIC_WWW
popd
rm -rf $TMP_GIT_CLONE
exit
完了したら、ファイルを保存してテキストエディタを閉じます。
スクリプトが実行可能であることを確認してください。そうすれば、gitユーザーは変更を受け取ったときにスクリプトを実行できます。
- chmod +x ~/sammy-blog.git/hooks/post-receive
この時点で、完全に構成されたGitリポジトリと、変更が受信されたときにサイトを更新するためのGit受信後フックがあります。 サイトをリポジトリにプッシュする前に、SSH経由で接続するときにユーザーにさまざまなGitコマンドを提供できるインタラクティブシェルであるgit-shell
を構成することにより、本番サーバーをさらに保護します。
ステップ3—インタラクティブログインを無効にするようにGitシェルを構成する
ユーザーは次の方法でgit-shell
を実装できます。対話型シェルとして、SSH経由で接続するときにさまざまなコマンドを提供して、新しいリポジトリの作成や新しいSSHキーの追加を可能にするか、非対話型シェルとして。 SSH経由でサーバーのコンソールへのアクセスを無効にしますが、git
コマンドを使用して既存のリポジトリを管理できるようにします。
git ユーザーのSSHキーを他のユーザーと共有すると、SSH経由でインタラクティブなBashセッションにアクセスできるようになります。 これは、ユーザーがサイトに関連しない他のデータにアクセスする可能性があるため、セキュリティ上の脅威を表しています。 git-shell
を非対話型シェルとして構成するため、gitユーザーを使用して対話型Bashセッションを開始することはできません。
gitユーザーとしてログインしていることを確認してください。 前の手順の後でセッションを終了した場合は、前と同じコマンドを使用して再度ログインできます。
- su - git
git-shell
が機能するために必要なgit-shell-commands
ディレクトリを作成することから始めます。
- mkdir ~/git-shell-commands
no-interactive-shell
ファイルは、インタラクティブなシェルアクセスを許可したくない場合の動作を定義するために使用されるため、選択したテキストエディターで開きます。
- nano ~/git-shell-commands/no-interactive-login
次の内容をファイルにコピーします。 SSH経由でログインしようとすると、ウェルカムメッセージが表示されます。
#!/usr/bin/env bash
printf '%s\n' "You've successfully authenticated to the server as $USER user, but interactive sessions are disabled."
exit 128
完了したら、ファイルを保存してテキストエディタを閉じます。
git-shell
が実行できるように、ファイルが実行可能であることを確認する必要があります。
- chmod +x ~/git-shell-commands/no-interactive-login
root以外のsudoユーザーに戻って、gitユーザーのプロパティを変更できるようにします。 以前のsu
コマンドを使用した場合は、次を使用してセッションを閉じることができます。
- exit
最後に、gitユーザーのシェルをgit-shell
に変更する必要があります。
- sudo usermod -s $(which git-shell) git
開発マシンからSSHを実行して、対話型シェルにアクセスできないことを確認します。
- ssh git@production_server_ip
次のようなメッセージが表示されます。 そうでない場合は、チュートリアルを続行する前に、適切なSSHキーが設定されていることを確認し、前の手順をたどって問題を解決してください。
OutputWelcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-109-generic x86_64)
...
You've successfully authenticated to the server as git user, but interactive sessions are disabled.
Connection to production_server_ip closed.
次に、このGitリポジトリを使用するようにローカル開発マシンを構成してから、サイトをリポジトリにプッシュします。 最後に、サイトが生成され、Webブラウザからアクセスできることを確認します。
ステップ4—変更をリポジトリにプッシュする
これで、本番サーバーでGitリポジトリを初期化して構成しました。 開発マシンでは、リモートリポジトリに関するデータとローカルリポジトリで行われた変更を含むローカルリポジトリを初期化する必要があります。
開発マシンで、サイトを含むディレクトリに移動します。
- cd ~/www
コンテンツをリモートリポジトリにプッシュできるように、サイトのルートディレクトリにあるGitリポジトリを初期化する必要があります。
- git init
出力には、リポジトリの初期化が成功したことに関するメッセージが含まれています。
OutputInitialized empty Git repository in /home/sammy/www
このような出力が表示されない場合は、画面上のメッセージに従って問題を解決してから続行してください。
次に、リモートオブジェクトを作成します。これは、作業中のリモートリポジトリとブランチの追跡に使用されるGitオブジェクトを表します。 通常、デフォルトのリモートは origin と呼ばれるため、このチュートリアルの目的で使用します。
次のコマンドは、 origin リモートを作成します。このリモートは、gitユーザーを使用して本番サーバー上のsammy-blogリポジトリを追跡します。
- git remote add origin git@production_server_ip:sammy-blog.git
出力がない場合は、正常に動作したことを示します。 エラーメッセージが表示された場合は、次の手順に進む前に必ず解決してください。
変更をリモートリポジトリにプッシュするたびに、それらをコミットしてから、コミットをリモートリポジトリにプッシュする必要があります。 リモートリポジトリがコミットを受信すると、最新の変更を加えてサイトが再生成されます。
コミットは、行った変更を追跡するために使用されます。 それらには、そのコミットで行われた変更を説明するために使用されるコミットメッセージが含まれています。 コミットで行われた最も重要な変更の詳細を含め、メッセージは短く簡潔にすることをお勧めします。
変更をコミットする前に、コミットするファイルを選択する必要があります。 次のコマンドは、すべてのファイルにコミットのマークを付けます。
- git add .
出力がない場合は、コマンドが正常に実行されたことを示します。 エラーが表示された場合は、続行する前に必ず解決してください。
次に、-m
フラグを使用してすべての変更をコミットします。これには、コミットメッセージが含まれます。 これが最初のコミットであるため、「初期コミット」と呼びます。
- git commit -m "Initial commit."
出力には、そのコミットで変更されたディレクトリとファイルのリストが含まれます。
Commit output 10 files changed, 212 insertions(+)
create mode 100644 .gitignore
create mode 100644 404.html
create mode 100644 Gemfile
create mode 100644 Gemfile.lock
create mode 100644 _config.yml
create mode 100644 _posts/2017-09-04-link-test.md
create mode 100644 about.md
create mode 100644 assets/postcard.jpg
create mode 100644 contact.md
create mode 100644 index.md
エラーが表示された場合は、チュートリアルを続行する前に必ず解決してください。
最後に、次のコマンドを使用して、コミットされた変更をリモートリポジトリにプッシュします。
- git push origin master
出力には、プッシュの進行状況に関する情報が含まれます。 完了すると、次のような情報が表示されます。
Push outputCounting objects: 14, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 110.80 KiB | 0 bytes/s, done.
Total 14 (delta 0), reused 0 (delta 0)
remote: Cloning into '/tmp/sammy-blog'...
remote: done.
remote: /tmp/sammy-blog ~/sammy-blog.git
remote: Configuration file: /tmp/sammy-blog/_config.yml
remote: Source: /tmp/sammy-blog
remote: Destination: /var/www/html
remote: Incremental build: disabled. Enable with --incremental
remote: Generating...
remote: done in 0.403 seconds.
remote: Auto-regeneration: disabled. Use --watch to enable.
remote: ~/sammy-blog.git
To [email protected]:sammy-blog.git
* [new branch] master -> master
そうでない場合は、チュートリアルを続行する前に、画面上のログに従って問題を解決してください。
この時点で、サイトはサーバーにアップロードされ、しばらくすると再生成されます。 Webブラウザをhttp://production_server_ip
に移動します。 サイトが稼働していることを確認する必要があります。 そうでない場合は、前の手順に戻って、意図したとおりにすべてを実行したことを確認してください。
何かを変更したときにサイトを再生成するには、最初のコミットで行ったように、ファイルをコミットに追加してコミットし、変更をプッシュする必要があります。
ファイルに変更を加えたら、次のコマンドを使用して、変更されたすべてのファイルをコミットに追加します。 新しいファイルを作成した場合は、最初のコミットで行ったように、git add
を使用してそれらを追加する必要もあります。 ファイルをコミットする準備ができたら、変更を説明する別のコミットメッセージを含める必要があります。 メッセージを「更新されたファイル」と呼びます。
- git commit -am "updated files"
最後に、変更をリモートリポジトリにプッシュします。
- git push origin master
出力は、最初のプッシュで見たものと同じようになります。
Push outputCounting objects: 14, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 110.80 KiB | 0 bytes/s, done.
Total 14 (delta 0), reused 0 (delta 0)
remote: Cloning into '/tmp/sammy-blog'...
remote: done.
remote: /tmp/sammy-blog ~/sammy-blog.git
remote: Configuration file: /tmp/sammy-blog/_config.yml
remote: Source: /tmp/sammy-blog
remote: Destination: /var/www/html
remote: Incremental build: disabled. Enable with --incremental
remote: Generating...
remote: done in 0.403 seconds.
remote: Auto-regeneration: disabled. Use --watch to enable.
remote: ~/sammy-blog.git
To [email protected]:sammy-blog.git
* [new branch] master -> master
この時点で、サイトは新たに生成され、最新の変更が加えられています。
結論
このチュートリアルでは、Gitリポジトリに変更をプッシュした後にWebサイトをデプロイする方法を学びました。 Gitについて詳しく知りたい場合は、Gitチュートリアルシリーズをご覧ください。
また、他のGitフックについて詳しく知りたい場合は、Gitフックを使用して開発およびデプロイタスクを自動化する方法を確認してください。