Posted at

Gitlab + Jenkins + hugo(in Docker)で静的サイトをpush時に自動Deploy

More than 1 year has passed since last update.


概要

hugo で作っている静的サイトを、 Gitlabpush したらあとは自動的にデプロイできないかな、と思ったのがことの始まり。方法はいくらでもあるんでしょうけど、 Jenkinsを触ってみたかった ってだけでとりあえず Jenkins でやってみることにしました。 Gitlab の実際の本番環境とか触りたくなかったので以下の構成で自分のMacbook Proで検証。(Docker in Dockerはやりたくなかったので、VirtualBoxにUbuntu入れてその中にJenkins入れてます)

hugodeploy.png

「こうした方がいいのでは?」という意見など大歓迎です!


前提知識

この記事ではDocker, Virtualbox, Gitlabをそれとなく使ったことある人、かつ hugo のコードベースが既にある人を前提に書いています。なのでこれらが揃ってない人はよくわからない内容になっている可能性が高いです(ごめんなさい)。


Gitlabの準備

Webhookを試せるようにテスト用のGitlabを準備します。お手軽なDockerのイメージが sameersbn/docker-gitlab にあるのでこちらを使わせてもらいます。

docker-compose up

叩いたら本当にすぐにGitlabが使えます。とりあえずここに自分の hugogit リポジトリを上げておきましょう。また、後ほど jenkins さんと連携したいので、 jenkins ユーザもGitlabに追加します。

Gitlabの Admin Area > Users > New User に行って jenkins ユーザ追加しましょう。

image

External Userでいいはずなので、チェックを忘れずに。

image

作ったあとは Edit ページからパスワードを設定します。適当に「jenkinsjenkins」とでもしておきましょう。

ユーザが追加できたら、対象となる hugo プロジェクトのメンバーにReporterとして追加しておきます。

image

これでGitlab側の準備はいったん完了。


Jenkinsの準備


Jenkins初期設定

VirtualBoxをダウンロードして、Ubuntu(とりあえず16.04.1)もダウンロードしてVirtualBoxの中にインストールします。

インストールが完了したら基本的にこちらのサイトに記載されている手順でJenkinsをインストールします。

# LTSバージョンのPPA追加

wget -q -O - http://pkg.jenkins-ci.org/debian-stable/jenkins-ci.org.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'

# Jenkinsのインストール
sudo apt-get update
sudo apt-get install jenkins

インストールが完了しますと http://<VMのIP>:8080/ にアクセスすると、 Administrator Password を入力してくださいっていうような画面が出て来るはずです。

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

これで最初のパスワードが手に入るので入力すると先の画面に進むことができます。

次の画面では Select plugins to install の方を選択して、この時点でGitlabのプラグインをインストールしちゃいましょう。

image

次にAdmin Userを作る画面にいくので適当に admin というような名前のユーザでも作っておきます。これで初回のセットアップ完了です。


Docker Pluginのインストール

さっそく先程作った admin ユーザでログインして、今度は Docker Plugin をインストールしましょう。

Jenkinsの管理 > プラグインの管理利用可能 タブをクリックして、検索ボックスで Docker と入力します。 Docker Plugin というのが見つかるはずなのでインストールしましょう。

image

Jenkinsも再起動しておいて、これでいったん準備完了です。


Dockerの準備


dockerのインストール

JenkinsのSlaveとしてDockerを使うので、UbuntuにDockerをインストールします。こちらを参考にインストールしました。

# とりあえずパッケージデータベースをアップデート

sudo apt-get update

# GPG keyの登録
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

# リポジトリ追加
sudo apt-add-repository 'deb https://apt.dockerproject.org/repo ubuntu-xenial main'

# パッケージデータベース再びアップデート
sudo apt-get update

# dockerインストール
sudo apt-get install -y docker-engine

# docker起動してるか確認
sudo systemctl status docker

# jenkinsユーザでdockerが使えるようにdockerグループに追加
sudo usermod -aG docker jenkins

これでdockerのインストール完了です。一応 jenkins ユーザで使えるかテストしておきましょう。

# rootユーザになって

sudo -i

# jenkinsユーザになって
su jenkins

# hello-worldコンテナ実行してみる
docker run hello-world

↑これが正常に実行できたらdockerの準備OKです。一応ここで OSの再起動 しておきます。(たぶんOSの再起動じゃなくてJenkinsの再起動だけで大丈夫ですが、念のため)


hugoのビルド用Dockerイメージ準備

JenkinsのSlaveとして使うDockerイメージの準備をします。 hugo が叩けたら良いんですけど、とりあえずはpublysher/docker-hugoがお手頃に見つかったので、これをベースにDockerイメージを作っていきます。 ssh できるようにしておきたいのと、 jdk が必要なのでこのイメージにインストールしておきます。

# publysher/docker-hugoからdockerコンテナ作ってbash起動

docker run -it publysher/docker-hugo

# ↓ここからdockerコンテナの中
# パッケージデータベースの更新
apt-get update

# sshサーバインストール
apt-get install openssh-server
mkdir /var/run/sshd

# jdkインストール(とりあえずの7)
apt-get install openjdk-7-jdk

# ssh用のjenkinsユーザ追加(このときのパスワード覚えておくこと)
adduser jenkins

# ssh起動しとく
/usr/sbin/sshd

# コンテナから抜ける
exit
# ↑dockerコンテナの中ここまで

# 今作ったコンテナを確認
docker ps -a
# ↓こんなのが出てくるはずなのでCONTAINER IDを取得
# CONTAINER ID IMAGE COMMAND
# 223f94679c0f publysher/hugo "/bin/bash"

# コンテナをjenkins-hugoイメージとして登録(このイメージ名覚えておく)
docker commit 223f94679c0f jenkins-hugo

# イメージの確認
docker images
# ↓こういうのがあるはず
# REPOSITORY TAG IMAGE ID
# jenkins-hugo latest cfbeadf0f958

以上でコンテナの準備完了です!


JenkinsにDocker設定&ジョブ追加


Dockerの設定

Jenkinsで「Jenkinsの管理 > システムの設定」にて、一番下に「クラウド」という項目があるので、そこで Docker を選択します。

image

項目は以下のようにしときます。ローカルのDocker使うので Docker URLunix:///var/run/docker.sock にします。ここまでうまく設定できていたら Test Connection も正常にパスするはずです。

image

下の方の項目にAdd Docker Templateというのがあるので追加します。

image

Docker Image には先程作ったイメージ名( jenkins-hugo )を。 Labels はあとで使うのでわかりやすい名前にします。 用途 には「このマシーンを特定ジョブ専用にする」を指定して、明示的に指定されたときだけ使われるようにします。 Launch method は 「Docker SSH computer launcher」として認証情報には先程のSSH用のユーザ情報を入力します。

image


ジョブの設定

Jenkinsに新規ジョブを追加します。「フリースタイル」で hugo-deploy とでも名前をつけて作りましょう。

「実行するノードを制限」の項目で先程のDockerでの設定で指定したラベルを入力します。

image

「ソースコード管理」ではpull元となるGitlabのURLを入力し、 external で登録したGitlabのユーザの認証情報も追加します。

hugo-deploy_Config__Jenkins_.png

「ビルド・トリガ」の項目で以下の部分に注目。Gitlab連携のURLをコピーしておきます。

hugo-deploy_Config__Jenkins_.png

「ビルド」ではとりあえず hugo でビルドして、生成された public をデプロイ先にコピーします。(検証用なので、以下は単純に scp だけしてます。実際はここで awss3sync とかすることになります。)

image

ジョブの設定はこれで完了!


実行!

それでは、あとはGitlabにwebhookを追加して、push 時にJenkinsのジョブが発火するようにします。

Webhooks_·_Settings_·_fukuyama___SSL_·_GitLab.png

今までの設定が正常にできていれば、これでJenkinsジョブが発火して、Jenkinsのコンソールログには以下のような内容が出力されるはずです。

Started by user admin

Building remotely on docker-ee2d2b9f2a26 (hugo-docker-slave) in workspace /home/jenkins/workspace/hugo-deploy
Cloning the remote Git repository
Cloning repository http://192.168.56.1:10080/hoge/hoge.git
> git init /home/jenkins/workspace/hugo-deploy # timeout=10
Fetching upstream changes from http://192.168.56.1:10080/hoge/hoge.git
> git --version # timeout=10
using GIT_ASKPASS to set credentials
> git fetch --tags --progress http://192.168.56.1:10080/hoge/hoge.git +refs/heads/*:refs/remotes/origin/*
> git config remote.origin.url http://192.168.56.1:10080/hoge/hoge.git # timeout=10
> git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
> git config remote.origin.url http://192.168.56.1:10080/hoge/hoge.git # timeout=10
Fetching upstream changes from http://192.168.56.1:10080/hoge/hoge.git
using GIT_ASKPASS to set credentials
> git fetch --tags --progress http://192.168.56.1:10080/hoge/hoge.git +refs/heads/*:refs/remotes/origin/*
> git rev-parse refs/remotes/origin/master^{commit} # timeout=10
> git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision 56d16c24249d9fa87de990f03e006b1b7412706e (refs/remotes/origin/master)
> git config core.sparsecheckout # timeout=10
> git checkout -f 56d16c24249d9fa87de990f03e006b1b7412706e
> git rev-list 56d16c24249d9fa87de990f03e006b1b7412706e # timeout=10
[hugo-deploy] $ /bin/sh -xe /tmp/hudson4974744254848556844.sh
+ hugo
Started building sites ...
Built site for language en:
0 draft content
0 future content
0 expired content
78 regular pages created
18 other pages created
0 non-page files copied
24 paginator pages created
1 tags created
9 categories created
total in 226 ms
+ scp -r public ubuntu@172.17.0.1:/home/ubuntu/.
Finished: SUCCESS

実際のデプロイ方法は変わってきますが、これをベースに本当のデプロイフローも組んでいけるかな、っていうのがわかりました!楽しいですね!