はじめに
本記事は、Qiita上で2018/3/14に初公開した記事を転記したものです。
概要
社内向けにさくらのVPS上での、下記構成のリポジトリサーバ構築メモ
前回の続き
作成したスクリプトはGitHubからどうぞ
- さくらのVPS使用(RAM 2GB, HDD 200GB)
- CentOS 6.9 (Final)
- GitLab CE Omnibus ver.10.5.2
- 通知用メールはGMailを使用
- リポジトリおよびデータのバックアップはGoogle Driveを使用
- SSLに対応するため、Let's Encryptのサーバ証明書を使用
GitLabバックアップ設定
GitLab用に作成したアカウントのGoogle Driveにそのままバックアップすることにする
gdriveのダウンロード
gdriveを導入する
ここでは、/usr/local/bin/gdriveに配置
wget対象のURLはちょいちょい変わるので、開発者のprasmussenさんのリポジトリで確認すること
sudo wget -O gdrive https://docs.google.com/uc?id=0B3X9GlR6EmbnQ0FtZmJJUXEyRTA&export=download
sudo mv gdrive /usr/local/bin/
sudo chmod +x /usr/local/bin
Google Driveでの認証
sudo /usr/local/bin/gdrive list
コマンドをたたくとブラウザでURLにアクセスして認証キーを入れろ、と言われるので、その通りにする
バックアップ用スクリプトを作成
gdriveコマンドの使用方法自体は、aviscaeruleaさんが解説しているが、gdriveがちょっと古いせいか、いくつかコマンドラインオプションが古くなっていた
参照URLにあったスクリプトではうまく動作しなかったので、実験しながら似たようなスクリプトを作成
(bashのスクリプトを初めて書いたのでコマンドフルパスで埋まってたりするけど、ご愛敬。)
#!/bin/bash -eu
readonly TARGET=$1
readonly TARGET_FILENAME=$(basename $TARGET)
readonly TARGET_BASENAME="${TARGET_FILENAME%.<em>}"
readonly TARGET_BASEEXT="${TARGET_FILENAME##</em>.}"
readonly GDRIVE_DIR=$2
readonly KEEP_DAYS=10
if [ ! -e $TARGET ]
then
echo "File not found: $TARGET" >&2
exit 1
fi
renice -n 10 -p $$ > /dev/null
### Find/Create Backup folder
GDRIVE_DIR_ID=$(/usr/local/bin/gdrive list --no-header --query "trashed=false and mimeType='application/vnd.google-apps.folder' and name='$GDRIVE_DIR'" | awk '{print $1}')
echo "$GDRIVE_DIR -> $GDRIVE_DIR_ID"
if [ -z "$GDRIVE_DIR_ID" ]
then
echo "Try to create folder: $GDRIVE_DIR"
GDRIVE_DIR_ID=$(/usr/local/bin/gdrive mkdir "$GDRIVE_DIR" | awk '{print $2}')
echo "$GDRIVE_DIR -> $GDRIVE_DIR_ID"
if [ -z "$GDRIVE_DIR_ID" ]
then
echo "Folder not created: $GDRIVE_DIR" >&2
fi
fi
### Upload Encrypted file
/usr/local/bin/gdrive upload --parent $GDRIVE_DIR_ID --name ${TARGET_BASENAME}_`date +%Y%m%d-%H%M%S`.${TARGET_BASEEXT} $TARGET
### House Keeping
LIMIT_TIMESTAMP=$(date -d "$KEEP_DAYS days ago" +%Y-%m-%dT%H:%M:%S)
/usr/local/bin/gdrive list --no-header --query "'$GDRIVE_DIR_ID' in parents and modifiedTime < '$LIMIT_TIMESTAMP'" | while read ln
do
ITR_ID=$(echo $ln | awk '{print $1}')
ITR_DATE=$(echo $ln | awk '{print $(NF-1),$NF}')
echo "ID: $ITR_ID, DATE: $ITR_DATE"
/usr/local/bin/gdrive delete $ITR_ID
done
使用法は下記
bkup_gdrive.sh <バックアップするファイルパス> <Googleドライブ上のフォルダ名>
- バックアップするファイルパス
- Googleドライブにアップロードするファイルのパス
- Googleドライブ上のフォルダ名
- アップロード先のGoogleドライブのフォルダ名。
ルート直下の1階層のみサポート
下記制限がある
- 引数は省略できない
- Google Driveのルート直下のフォルダにしか保存できない
GitLabのバックアップ設定
GitLabでバックアップが必要なのは、設定とデータ部分
作成したスクリプトを使用して、両方をGoogle Driveにバックアップする
GitLabの設定のバックアップ
面倒なので、/etc/gitlab配下をzip圧縮
本当は暗号化とかした方がいいのかもだけど、ここではひとまずおいておく
先ほど作成したbkup_gdrive.shを使用して、Google Driveにアップロードするスクリプトを作成
#!/bin/bash -eu
echo "$(date "+%Y-%m-%d %H:%M:%S") ---------- START backup gitlab config ----------"
readonly TARGET_FILENAME=$(date "+etc-gitlab-%s.tgz")
# Backup GitLab config folder
tar czf $TARGET_FILENAME -C / etc/gitlab
# Upload Backup file to Google drive
/usr/local/bin/bkup_gdrive.sh $TARGET_FILENAME bk_gitlab_config
# Delete Backup file
rm $TARGET_FILENAME
echo "$(date "+%Y-%m-%d %H:%M:%S") ---------- END backup gitlab config ----------"
crontabを使用して、毎日午前2時に上記スクリプトを実行するように設定
標準出力は動作ログとして、/var/log/backups/bkup_gitlab_config.logに出力する。
sudo crontab -e -u root
0 2 * * * /usr/local/bin/bkup_gitlab_config.sh >> /var/log/backups/bkup_gitlab_config.log
GitLabのデータのバックアップ
設定と同様、GitLabのデータをバックアップするスクリプトを作成
#!/bin/bash -eu
echo "$(date "+%Y-%m-%d %H:%M:%S") ---------- START backup gitlab data ----------"
# Create GitLab Backup file
gitlab-rake gitlab:backup:create
# Get target file name
readonly TARGET_FILENAME=`ls -lt /backups/gitlab/app/* | head -n 1 | awk '{print $NF}'`
# Upload Backup file to Google drive
/usr/local/bin/bkup_gdrive.sh $TARGET_FILENAME bk_gitlab_data
echo "$(date "+%Y-%m-%d %H:%M:%S") ---------- END backup gitlab data ----------"
crontabを使用して、毎日午前2時10分に上記スクリプトを実行するように設定。
標準出力は動作ログとして、/var/log/backups/bkup_gitlab_data.logに出力する。
sudo crontab -e -u root
10 2 * * * /usr/local/bin/bkup_gitlab_data.sh >> /var/log/backups/bkup_gitlab_data.log
SSL対応
Let's Encryptの証明書取得用のコマンドを導入
さくらインターネットのナレッジに解説があったので、参考にしてコマンドを導入する
sudo curl https://dl.eff.org/certbot-auto -o /usr/bin/certbot-auto
sudo chmod 700 /usr/bin/certbot-auto
webrootで証明書を取得するための準備
GitLabの設定ファイルを編集し、nginxの特殊設定を埋め込む
nginx['custom_gitlab_server_config'] = "include /etc/letsencrypt/nginx.conf;"
埋め込んだnginx用の特殊設定ファイルを作成
sudo mkdir /etc/letsencrypt
sudo vim /etc/letsencrypt/nginx.conf
location ^~ /.well-known {
alias /var/letsencrypt/.well-known;
}
Let's Ecryptのwebroot認証に必要なフォルダの作成
sudo mkdir /var/letsencrypt
GitLabを再起動
sudo gitlab-ctl reconfigure
証明書の取得
certbot-autoを使用して証明書を取得
sudo certbot-auto certonly --webroot -w /var/letsencrypt -d gitlab.example.com
gitlab.example.comの部分を自身のドメイン名に変更するのを忘れずに
GitLabに証明書を設定
GitLabの設定ファイルを修正
3箇所ある、gitlab.example.comの部分を自分のドメインに変更するのを忘れないように注意!
external_url 'https://gitlab.example.com'
nginx['redirect_http_to_https'] = true
nginx['ssl_certificate'] = "/etc/letsencrypt/live/gitlab.example.com/fullchain.pem"
nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/gitlab.example.com/privkey.pem"
httpsを通すように設定
sudo lokkit -s https
GitLabを再起動
sudo gitlab-ctl reconfigure
ブラウザで下記の確認を行う
- httpsでアクセス可能なこと
- httpでアクセスするとhttpsにリダイレクトされること
証明書の自動更新を設定
crontabにて定期的に証明書を更新するように設定する
sudo crontab -e -u root
0 3 1 * * /usr/bin/certbot-auto renew --force-renew && gitlab-ctl restart
この設定だと、毎月1日の午前3時0分に証明書を更新する
適宜変更