どうも、シローです。
それでは前回の続きです。
今回は、前回のCMSのコンテンツを自動でデプロイ(Gitでpullして公開する)処理を作っていきます。
ファイル構成
1 2 3 4 5 6 |
shiro@shiro-mmm:~/shiro-mmm$ tree . ├── bin │ ├── conf.sh # 設定値 │ └── fetch.sh # GitのWebフックで実行される最新のソースを取得するプログラム └── deploy.sh # システムのインストールとfetch.shからcgiプログラムを作成するプログラム |
設定値プログラム
conf.sh
1 2 3 4 5 6 7 |
#!/bin/bash contents="shiro-mmm_contents" contents_owner="smithshiro" wwwdir="/var/www" contentsdir="$wwwdir/$contents" appdir="$wwwdir/shiro-mmm" |
デプロイ用スクリプトを作成
Gitから最新のソースを取得するスクリプトを作ります。
これは、最終的にGitでプルリクエストを受け取ったときに、GitのWebフック機能で自動実行されるようにします。
fetch.sh
1 2 3 4 5 6 7 8 |
#!/bin/bash -ex source "$(dirname $0)/conf.sh" [ -n "${CONTENT_LENGTH}" ] && dd bs=${CONTENT_LENGTH} > /dev/null echo -e 'Contents-type: text/html\n\n' cd "$contentsdir" git pull |
システムインストールプログラムを作成
デプロイ用プログラムをcgiとして実行できる用に/var/www/shiro-mmm_contentsにコンテンツ用のリポジトリをインストールして、/var/www/shiro-mmmにデプロイ用cgiをfetch.shから生成するプログラムを作ります。
deploy.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
#!/bin/bash -eux # -e ... コマンドにエラーがあったら終了する # -u ... 定義されていない変数があったら止まる # -x ... 実行したコマンドを標準エラーで出力に表示する source "$(dirname $0)/bin/conf.sh" [ "$USER" = "root" ] # root ユーザー以外は実行できない ### INSTALL THIS SYSTEM ### rsync -av --delete "$(dirname $0)/bin/" "$appdir/" # rsync ... ディレクトリを同期する # -a ... 転送元ディレクトリの内容を維持したままコピー # -v ... 実際に転送されたファイルのリストや、転送量などの統計情報を表示する chown www-data:www-data "$appdir" -R ### INSTALL THIS SYSTEM ### cd "$appdir" rnd=$(cat /dev/urandom | tr -cd 0-9a-zA-Z | head -c 32) # /dev/urandom 乱数 # tr ... テキスト変換 # -c xxx ... xxx以外をひょうじする # -d ... 文字を削除する # -cd xxx .... xxxのみを表示する # head ... 先頭のみ表示する # -c xxx ... xxx文字分表示する mv "fetch.sh" "fetch_$rnd.cgi" # 公開されるパスだから乱数で他のひとにはわからないようにする ### PULL CONTENTS ### rm -rf "${contentsdir:?}" # :? は変数に値が入っていないとエラーを返す cd "$wwwdir" git clone "https://github.com/$contents_owner/$contents" chown www-data:www-data "$contentsdir" -R echo "call fetch_$rnd.cgi from Github" |
7行目の[ "$USER" = "root" ] は実行するユーザがrootかをチェックしています。
もし、ルートユーザではなかった場合は、エラーステータス1を返して、そこでプログラムがストップします。
rsyncコマンド
rsyncは第一引数のディレクトリを第二引数のディレクトリ配下に同期するコマンドです。
-a で転送元のディレクトリの内容を可能限りコピーして
-v で転送量などの統計情報を表示します。
/dev/urandomとは
/dev/urandomはランダムなバイナリーデータを無限放出するプログラムです。
これと次のtrとheadコマンドで乱数を生成します。
trコマンド
trはテキストを置換するコマンドです。
-cd xxx と指定するとxxxのパターンだけを取ってきてくれます。
headコマンド
headとは文字列を文字数や行数で区切って表示するコマンドです。
-c xxx でxxx文字分だけ取得します。
コマンドを実行してみる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
shiro@shiro-mmm:~/shiro-mmm$ sudo ./deploy.sh ++ dirname ./deploy.sh + source ./bin/conf.sh ++ contents=shiro-mmm_contents ++ contents_owner=smithshiro ++ wwwdir=/var/www ++ contentsdir=/var/www/shiro-mmm_contents ++ appdir=/var/www/shiro-mmm + '[' root = root ']' ++ dirname ./deploy.sh + rsync -av --delete ./bin/ /var/www/shiro-mmm/ sending incremental file list deleting fetch_Ux0cQ6tq96hlqpfzSxBsuNpBPrtoZJHV.cgi ./ fetch.sh sent 334 bytes received 87 bytes 842.00 bytes/sec total size is 326 speedup is 0.77 + chown www-data:www-data /var/www/shiro-mmm -R + cd /var/www/shiro-mmm ++ cat /dev/urandom ++ tr -cd 0-9a-zA-Z ++ head -c 32 + rnd=L4FZXmV57NtX7q7MnNbxfGq4dRUrYmgs + mv fetch.sh fetch_L4FZXmV57NtX7q7MnNbxfGq4dRUrYmgs.cgi + rm -rf /var/www/shiro-mmm_contents + cd /var/www + git clone https://github.com/smithshiro/shiro-mmm_contents Cloning into 'shiro-mmm_contents'... remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (2/2), done. remote: Total 4 (delta 0), reused 4 (delta 0), pack-reused 0 Unpacking objects: 100% (4/4), done. + chown www-data:www-data /var/www/shiro-mmm_contents -R + echo 'call fetch_L4FZXmV57NtX7q7MnNbxfGq4dRUrYmgs.cgi from Github' call fetch_L4FZXmV57NtX7q7MnNbxfGq4dRUrYmgs.cgi from Github |
/var/www/shiro-mmm配下にfetch_(乱数).cgiのファイルが作成されました。
1 2 |
shiro@shiro-mmm:/var/www/shiro-mmm$ ls conf.sh fetch_L4FZXmV57NtX7q7MnNbxfGq4dRUrYmgs.cgi |
CGIプログラムをGithubから実行できるようにapacheの設定を変更
先ほど作られたfetch_(乱数).cgiをGithub側から実行できるようにapache設定ファイルを変更します。
/etc/apache2/site-available配下にlet's encriptを導入した時に作成されたconfファイルがあると思うのでそれを編集します。
(筆者の環境ではshiro-mmm-le-ssl.confという名前)
/etc/apaches/site-available/shiro-mmm-le-ssl.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<IfModule mod_ssl.c> <VirtualHost shiro-mmm.work:443> # The ServerName directive sets the request scheme, hostname and port that # the server uses to identify itself. This is used when creating # redirection URLs. In the context of virtual hosts, the ServerName # specifies what hostname must appear in the request's Host: header to # match this virtual host. For the default virtual host (this file) this # value is not decisive as it is used as a last resort host regardless. # However, you must set it for any further virtual host explicitly. #ServerName www.example.com DocumentRoot /var/www/shiro-mmm <Directory /var/www/shiro-mmm> Options -Indexes -FollowSymLinks +MultiViews +ExecCGI AllowOverride None # .htaccessは無効になる Order allow,deny # Deny => Allowの順に評価する Allow from all # どこからでもアクセスできる # この設定でCGIが動作 AddHandler cgi-script .cgi </Directory> # 記事のディレクトリを閲覧できるようにする設定 Alias /pages /var/www/shiro-mmm_contents/pages Alias /posts /var/www/shiro-mmm_contents/posts # ディレクトリの中身が丸見えにならないようにする設定 <Directory /var/www/shiro-mmm_contents> Options -Indexes -FollowSymLinks AllowOverride None Order allow,deny Allow from all </Directory> # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, # error, crit, alert, emerg. # It is also possible to configure the loglevel for particular # modules, e.g. #LogLevel info ssl:warn ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined # For most configuration files from conf-available/, which are # enabled or disabled at a global level, it is possible to # include a line for only one particular virtual host. For example the # following line enables the CGI configuration for this host only # after it has been globally disabled with "a2disconf". #Include conf-available/serve-cgi-bin.conf ServerName shiro-mmm.work SSLCertificateFile /etc/letsencrypt/live/shiro-mmm.work/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/shiro-mmm.work/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf </VirtualHost> </IfModule> |
14 ~ 21行にcgi実行許可に関する処理が記述されています。
15行目のOptions
Optionsディレクティブはディレクトリ制御に関する値を持ちます。
+をつけると、それを適用して、-をつけるとそれを外すことができます。
All | すべてアクセスできる |
None | すべてアクセスできない |
FollowSymLinks | シンポジックリンクへのアクセスができる |
MultiViews | 複数の拡張子のファイルにアクセスできる(index.html, index.phpなど) |
ExecCGI | CGIを実行できる |
20行目のAddHandler
AddHandlerでアクセスされたファイルのハンドラを指定することができます。
ハンドラ(handle = 扱う)とはファイルをどのように実行するかを意味します。
cgi-scriptと指定することで、cgiとしてアクセスしたファイルを実行します。後ろに.cgiと指定することで
「.cgiファイルにアクセスするとcgiとして実行する」という意味になります。
修正したら、apacheを再起動します。
1 |
shiro@shiro-mmm:/etc/apache2/sites-available$ sudo service apache2 restart |
curlコマンドで実行してみる
1 2 3 |
shiro@shiro-mmm:/var/www/shiro-mmm$ curl https://shiro-mmm.work/fetch_YzAKOInshTDUycKUPry4zbpLoH2UaRty.cgi Already up to date. |
完璧や・・
GithubでWebフックの設定をしよう
先ほどのデプロイプログラムをGithubから実行できるように、Githubの管理画面での設定を行います。
まずは、リポジトリのSettings画面にいきます。
そして、左側のWebhooksボタンを押して、Webフック設定画面に遷移して。
Add webhookボタンを押して、Webフックを作成します。
Webフック画面ではPayload URLに、先ほどcurlで実行したURLを入力します。
また、Which events would you like to trigger this webhook? では、Just the push event. を選択します。
これで、コンテンツリポジトリにpushされれば、勝手にコンテンツをデプロイしてくれます。
これで、おしまいです。
次は、記事の描画プログラムを作成していきます。