サーバーにファイルをアップロードする基本として
っていう作業がありますよね?
私もつい最近までの数年間この作業をしておりました。
絶対自動化できることは分かっていたのですが、それを組むのが面倒でやってなかったんですよねー。
ということで今回重い腰を上げて自動化に踏み切ったので、その軌跡を残したいと思います。
sshでローカルとサーバーが接続できること。
MacにHomebrewが入っていることを前提としてお話していきますよー。
使用するのは以下のもの。
まずはこれら全てをbrewでインストールします。
rsyncはAディレクトリをBディレクトリに同期するコマンドです。
$ brew install rsync
実はmacには標準で入ってたりします。でも新しいバージョンの方が気持ちいいからHomebrewで改めて入れます。
sshで接続した先のディレクトリをローカルでマウントすることができるコマンドです。
これめちゃくちゃ便利なので是非入れてみてください。
sshfsはそれをインストールする前にosxfuseをインストールする必要があります。
$ brew cask install osxfuse
$ brew install sshfs
ディレクトリを監視して変更されたファイルを都度、標準出力に吐き出すコマンドです。
$ brew install fswatch
これで必要なものは出揃いました!
それでは新しくインストールしたこのコマンドたちを少し紹介していきますね。
$ rsync <options> source dest
使い方はいたって簡単でsource(同期元)
をdest(同期先)
に同期します。
例えば~/dev/sourcedir(同期元)
を~/dev/destdir(同期先)
に同期する場合は以下のようにします。
$ rsync ~/dev/sourcedir/ ~/dev/destdir/
~/dev/sourcedir/
のように最後のスラッシュを入れないと~/dev/destdir/sourcedir
に同期されるので注意!
あと配下のディレクトリを再帰的に同期する場合には-r
のオプションが必要です!
そしてrsync
はリモートのディレクトリも同期元あるいは同期先に指定できるんです。
$ rsync ~/dev/sourcedir/ USER@HOST:/home/user/www/destdir/
そしてrsyncはオプションで結構細かく設定できます。
などなど。
$ sshfs USER@HOST:/path/to/remote /path/to/mountpoint
こちらも使い方がめちゃくちゃ簡単です。
リモートの/hoge/fooディレクトリ
をローカルの~/dev/mountpointにマウントしたい時は
$ sshfs USER@HOST:/hoge/foo ~/dev/mountpoint
でマウントできます!
Finderで確認すると
これが
こうなりました。
リモートのファイルをFinderで見られるのは非常にありがたいですよね!
もちろんターミナルでもアクセスできます。
ちなみにアンマウントは
$ umount ~/dev/mountpoint
# または
$ diskutil unmount ~/dev/mountpoint
# 最終手段は
$ killall sshfs
で行います。もしかしたらumount
に失敗するかもしれません。
$ fswatch <options> target
これだけでディレクトリの変更を検知できます。
ちょっと見てみましょう
$ fswatch ~/dev/targetdir
# test.htmlを作成
/Users/username/dev/targetdir/test.html
# test.htmlを更新
/Users/username/dev/targetdir/test.html
# style.cssを作成
/Users/username/dev/targetdir/style.css
# test.htmlを削除
/Users/username/dev/targetdir/test.html
# subdirディレクトリを作成
/Users/username/dev/targetdir/subdir
# subdirディレクトリにindex.htmlを作成
/Users/username/dev/targetdir/subdir/index.html
このように変更のあったファイルが標準入力で吐き出されます。
オプション次第で出力されるものが変わります。
このままだと全く使いようがありませんが、この出力をxargs
に渡すことで真価を発揮します。
$ fswatch ~/dev/targetdir | xargs -n1 -I{} program
これで変更があるたびにprogram
が起動されるようになります!
fswatchのオプションで監視除外のファイルを指定できたりするので.git
とか除外した方が良いかも?
以下の流れで行います。
リモートのディレクトリは「USER@HOST:/home/user/remote」
マウントポジションは「~/dev/mount/remote」
ローカルの作業ディレクトリは「~/dev/work」
と想定して説明します。
皆さんは適宜自分の環境に変換してくださいね!
最小規模での構築ならこれだけで自動同期です。
$ sshfs USER@HOST:/home/user/remote ~/dev/mount/remote
$ fswatch ~/dev/work | args -n1 -I{} rsync -rc --delete ~/dev/work/ ~/dev/mount/remote/
これで変更があるたびに
作業ディレクトリとマウントポジションがリアルタイム同期
つまりローカルとリモートがリアルタイム同期します。
実際には
.git系
を指定する.git系
を指定する.gitignore
を読み込んでrsyncの除外オプションにそれらを追加するとか色々組み込んだシェルスクリプトで同期のスタートストップを行なっています。
今までは別に苦じゃないしーって手動FTPアップロードしてたけど、自動同期の素晴らしさを知ってしまったらもう戻れないです!
どうか皆さんも素敵な自動化ライフを!
余談ですが、ただの自動同期ならsshfsは全く必要ありません。
rsyncでリモート同期できますからね。
でもマウントできた方が便利だし、確認をFinderでできるのはやっぱり楽ですよ!
CUIに凝ってる時は黒い画面いじってる俺カッケー。GUIで作業とか素人のやることですわって思うけど、やっぱGUIは見やすいですわ。
コータ=ザッカーバーグ
@kota_zuckerberg
バイクとプログラミングをこよなく愛する編集部の後方支援担当。 愛車はSUZUKI GSR250。 Illustratorの自動化からWEB制作、インフラの整備などをこなしていくうちに いつの間にかフルスタックエンジニアになっちゃった。 主な使用言語はphp, javascript, go, applescript。最近はjsに傾倒ぎみ。