動機
GitHubで管理、開発したコードを自動でレンタルサーバーにアップロードすると、かっこいい!(あと便利)
rsync叩くだけだから簡単やろ!w
→ 結果:数時間の沼にハマる(´;ω;`)
コピペできるような、ピンとくる記事がなかったので知見を共有します。
環境
レンタルサーバー:ColorfulBox(プランはBox1)
GitHub:適当なプライベートリポジトリ
免責
「日曜プログラマー」を自称している素人がゆるりと勉強した内容です。
内容を理解したうえで、自己責任でご使用ください。
記事中のコードはパブリックドメインとしてご自由にお使いください。
TL;DR
rsync --rsync-path=...
セットアップ
仕様
develop
ブランチにpushされたら、実行する
→ develop
ブランチの内容を取得する
→ サーバーへssh接続経由でrsyncコマンドを使い、/path/to/www-root/
の内容を更新
事前準備
今回使用したColorfulBoxにはrsyncコマンドがインストールされていなかったので、インストールします。
しかし、root権限は与えられていないのでsudo apt install rsync
など到底できません。かなしい。
そこで、
- サーバー上にソースコードを用意
- サーバー上でコンパイル
- コンパイル先にパスを通す
という作業を踏む必要があります。
依存関係の準備に手間取った気がしますが、基本的にはコマンドをたたくだけです。
こちらのサイトが新しくかつ詳しく、非常に参考になりました!
ColorfulBox に Rsync をインストールする - Atuweb
workflowを作成
以下のファイルをリポジトリの/.github/workflows/
に追加します。
name: deploy to development env.
on:
push:
branches:
- develop
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: develop
- name: prepare ssh
run: |
touch /tmp/key && echo "$SSH_KEY" > /tmp/key
chmod 700 /tmp/key
touch /tmp/known_hosts && echo "$KNOWN_HOSTS" > /tmp/known_hosts
env:
SSH_KEY: ${{ secrets.SSH_KEY }}
KNOWN_HOSTS: ${{ secrets.KNOWN_HOSTS }}
- name: rsync deploy
run: |
rsync -rptgDvz --delete \
-e "ssh -i /tmp/key -o UserKnownHostsFile=/tmp/known_hosts" \
--rsync-path=~/.local/bin/rsync \
--exclude='/.git/' --exclude='/.github/' \
$GITHUB_WORKSPACE/ $USERNAME@$SERVER_ADDRESS:$DEVELOP_SERVER_DESTINATION
env:
DEVELOP_SERVER_DESTINATION: ${{ secrets.DEVELOP_SERVER_DESTINATION }}
SERVER_ADDRESS: ${{ secrets.SERVER_ADDRESS }}
USERNAME: ${{ secrets.USERNAME }}
こちらにも上げています。
https://gist.github.com/kokko-san/836bd530dc17c886446d5b2f85714b9f
secretを用意
https://github.com/[user or org name]/[repo name]/settings/secrets/actions
に
- SSH_KEY
- SSH用の秘密鍵
- KNOWN_HOSTS
- 接続先の、想定されるknown host情報(詳しくは後述)
- DEVELOP_SERVER_DESTINATION
- デプロイ先のパス。e.g. /path/to/www-root/
- SERVER_ADDRESS
- SSH接続先のアドレス。e.g. example.com
- USERNAME
- SSHでログインするユーザー名
を用意します。
完了!
これで、あとはdevelop
ブランチにpushすれば自動的にアップロードが始まるはずです。
main
ブランチで動かしたいなどの応用も簡単に効くでしょう。
沼ポイントの解説
checkout
Git弱勢なのでcheckoutって何に使うねんという感じでしたが、これは「指定のリポジトリ(の指定のブランチ、コミットetc.)をcheckout(≒clone)してくれるaction」みたいです。
actionを実行し始めた段階では、新しくコンテナが展開されただけの状態なので、actionを登録しているリポジトリのファイルすら持っていません。
そこで、checkoutしてリポジトリの情報をとってきます。
(応用編として、他のリポジトリの情報もとってこれるようですが)
actionを登録しているリポジトリがプライベートリポジトリでも、checkoutするときに認可が必要ないのが今回の使用方法でのポイントでしょうか。
known_hosts
rsyncするときの-e
引数を、
-e "ssh -i /tmp/key -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
という風に-o StrictHostKeyChecking=no
を指定すれば、known_hostsを用意せずとも接続はできます。
ただ、デフォルトでaskなものをわざわざnoにするのは少し気持ちが悪いので、きちんと用意することにしました。
手元のbash環境で(今回はWSLのUbuntuを用いた)以下ようにssh-keyscan
をして、
username@COMPUTER-NAME:~# ssh-keyscan -H example.com
# example.com:22 SSH-*.*-OpenSSH_*.*
|1|***...
出てきた出力すべてをリポジトリのSecretとしてコピペすれば多分よいでしょう。
非常に参考になりました↓
--rsync-path
こいつです。今回の主役 兼 悪役 兼 ヒーローです。
そもそもですよ、世の中には煩雑なrsyncのオプションやssh鍵の準備を自動化してくれるactionのリポジトリがあります。
e.g. Rsync Deployments Action
これを使えばカンタンじゃん!!!
と思ったはいいものの、実際に使ってみるとなぜか
bash: rsync: command not found
とログに残して死んでいきます。
おっかしいなぁと、自分でrsyncをたたくworkflowを用意してもcommand not found
。
手元でサーバーにsshしてwhich rsync
はちゃんと動くのに!なんで!!
と悩み続け、きちんとrsyncのお勉強をしたら出てきました。--rsync-path
オプション。
このオプションは、 「rsyncへのパスがローカルとリモートで異なる場合、リモートでのパスを指定するオプション」 です。
サーバーでwhich rsync
をたたいて出たパスを、--rsync-path=
で指定するだけです。
正直、このオプションの存在を知らしめたいがためにこの記事を書いています。
改良できそうなポイント
--exclude
というか、--exclude-from
というか
rsyncの--exclude
に現在はどのリポジトリでもいらないであろう、/.git/
と/.github/
ディレクトリを指定していますが、実際にはさらにREADME.md
などもっといらないファイルがあると思います。
今回のようにwebサーバー上に置く場合は.htaccess
を使ってdeny from all
もいい気がしますが、リポジトリにrsync-excludes.txt
を用意してrsyncに--exclude-from
で指定するのもきれいな気がします。
--rsync-path
の自動設定
これってssh接続してwhich rsync
した内容を自動で設定すればもっとスマートなのでは?
未検証なので試してみたいと思います。
記事は以上です!
LGTMやコメント、編集リクエストなどお待ちしています!