✨
GitLabのCIを使用したサーバーにあるファイルの自動バックアップ
はじめに
ふつうは逆だと思いますけど、
非エンジニアも更新するWebページなのでGitを使ってデプロイとかできなかったので、苦肉の策でlftpコマンドを使って自動バックアップの仕組みを作りました。
(何かあってもバックアップから戻せるように...)
ちょっとコマンド変えればデプロイできるようになると思います。
Project Access Tokenの作成
Project Access Tokenを使用するのはユーザーに依存せず実行できるようにしたかったから。
ほかにもDeploy KeyやPersonal Access Tokenを使用してGitの認証を行う方法があるが、ユーザーの権限や存在に依存する部分が出てくるので今回は使用していない。
- 特定のプロジェクト>Settings>Access TokensページでAccess Tokenを作成する。
- それぞれの設定値
- Token name:任意
- Expiration date:任意
- Select a role:CIを実行するブランチに直pushできる権限(今回はMaintainer)
- Select scopes:read_repository, write_repository
- 作成したらAccess Tokenの値はコピーしておく。
CIの環境変数を登録
- 特定のプロジェクト>Settings>CI/CD>VariablesでExpandを押下して独自環境変数を登録する。
Key | Value |
---|---|
HOST | lftpで接続するときのホスト名 |
PASSWORD | lftpで接続するときのパスワード |
USERNAME | lftpで接続するときのユーザー名 |
PROJECT_ACCESS_TOKEN | 作成したProject Access Tokenの値 |
- 上記以外のgitlab-ci.ymlで使用している環境変数はもともと定義されている環境変数。
gitlab-ci.yml
- バックアップを保存したいプロジェクトに
gitlab-ci.yml
を作成する。 - おおまかなながれとしてはCIを実行するプロジェクトをCIを実行中にクローン、lftpコマンドでサーバーに保存されているファイルをダウンロード、差分があればpushする。
gitlab-ci.yml
stages:
- writeback-gitrepo
.git:push:
after_script:
# Go to the new directory
- cd "${CI_COMMIT_SHA}"
# Add all generated files to Git
- git add .
- |-
# Check if we have modifications to commit
ret=$(git status| sed -ne 's|.*\(clean\)|\1|p')
if [ -z $ret ];then
# Show the status of files that are about to be created, updated or deleted
git status
export TIME=$(date +%Y%m%d)
echo ${TIME}
# Commit all changes
git commit -m "${TIME} Push by GitLab runner"
# Update the repository and make sure to skip the pipeline create for this commit
git push origin "${CI_COMMIT_REF_NAME}" -o ci.skip
fi
before_script:
- apt-get update && apt-get install -y git lftp language-pack-ja-base language-pack-ja
# Set Character code
- locale-gen ja_JP.UTF-8
- echo export LANG=ja_JP.UTF-8 >> ~/.profile
- source ~/.profile
# Clone the repository via HTTPS inside a new directory
- git clone "https://gitlab-ci-token:${PROJECT_ACCESS_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" "${CI_COMMIT_SHA}"
# Set the displayed user with the commits that are about to be made
- git config --global user.email "${GITLAB_USER_EMAIL}"
- git config --global user.name "${GITLAB_USER_NAME}"
image: ubuntu
stage: writeback-gitrepo
writeback-gitrepo:
extends: .git:push
script:
# Download files via lftp
- lftp -c "set ftp:ssl-allow no; open -u $USERNAME,$PASSWORD $HOST; mirror --verbose / ${CI_COMMIT_SHA}"
only:
- schedules
それぞれのポイント
-
language-pack-ja-base language-pack-ja
をインストールしているのはCIの中で言語をja_JP.UTF-8
にしないと、サーバーに保管されているファイル名が日本語の場合に文字化けしてしまいダウンロード時にエラーになってしまうから。 -
only
で指定している部分は、GitLabのGUIで設定するスケジュールの時のみ実行するようにするため。 -
${TIME}
は何も指定しないとタイムゾーンがutfになるので、jstにする場合は別途設定が必要。 -
git commit -m "${TIME} Push by GitLab runner"
いつpushされたのか分かるようにしたかったので、環境変数でyyyyMMddを表示させるようにしている。コミットメッセージをシングルクォーテーションで囲むと環境変数が表示されないので注意。 - その他のポイントは参考にあるサイトを参照していただければと思います。(ほとんどコードは参考にさせていただきましたm(__)m)
CIのスケジュールを設定する
- 任意のプロジェクト>CI/CD>SchedulesページでCIを定期実行できるようにする。
- それぞれの設定値
- Description:任意
- Interval Pattern:任意
- Cron Timezone:日本の時間にする場合はTokyoまたはOsaka
- Target branch or tag:任意
- Variables:特に設定必要なし
Discussion