静的サイトジェネレーターでサイトを作ると当然のことながら静的ファイルが生成されます。WordPress とは異なり、記事公開までのステップはちょっと手間がかかります。
- 記事を書く
- ビルドしてサイトデータを生成
- レンタルサーバーにすべてのファイルをアップロード
だから、GitHub pages を使っている方もいらっしゃると思います。push とともにデプロイされるのは楽ですからね。
また、Vercel を使うのもありでしょう。push とともに専用サーバーにデプロイされますし、独自ドメインを持っていればリダイレクトもできるようです。
でも、僕はすでに持っている独自ドメインや WordPress で使っているレンタルサーバーがあるのでこれらを流用したい。それじゃあってことで、公開までさくっとやってくれるスクリプトを組みました。
Pyftpsync ライブラリを使い、前回と同じく、Automator を使ってアプリケーション化しています。
Pyftpsync とは
Martin Wendt さんがつくられている Python ライブラリで「ローカルとリモートを rsync コマンド風にやってくれるもの」と僕は理解しています。
▶︎ Pyftpsync
ただし、既知の制限があります。最たるものは 2 つ。
- 差分検知はファイルサイズと変更日から判断している
- ローカルフォルダ内に個別のメタデータファイルをつくり、最後の同期時刻とサイズを保存することで差分を検出する
このことから Gridsome を使っているとこうなります。
- static 配下の画像ファイルなど同一同名でも「差分あり」となる
- ビルドすると dist 配下のすべてのファイルが全削除&再生成されるため、上記 2 の効果がない
- 結果、ほとんどのファイルがアップロード対象となる
当初の僕の希望である「rsync コマンドのように差分だけがアップロードされればデプロイも短時間で済むじゃん」は達成できませんでした。
でもメリットもちゃんとあります。
手動でアップロードするよりだんぜん楽ということ。
Pyftpsync の使い方
公式のとおりに作ればとてもカンタン。使いやすい設計です。以下は同期モードの例で、他にアップロードモードがあります。
from ftpsync.ftp_target import FtpTarget
from ftpsync.targets import FsTarget
from ftpsync.synchronizers import BiDirSynchronizer
local = FsTarget("ローカルディレクトリパス")
remote = FtpTarget(
"リモートディレクトリパス",
"FTPサーバーアドレス",
username="FTPアカウント",
password="FTPパスワード",
tls=True # Trueの場合、FTPSが有効
)
# オプション設定例
opts = {
"resolve": "local" # コンフリクトした場合はローカルファイルを優先
}
# 同期の実行
sync = BiDirSynchronizer(local, remote, opts)
sync.run()
※デフォルトではコンソールにログ出力されますので、今何やっているかが分かります。
おわりに
WordPress や note を使ってきて、「公開までの仕組みがすべてつくられていること」ってすごいことだなと痛感しています。で、ここにきて SSG を使ってのサイト運営ですよ。
「手間かかることを楽しんでいる」感があります(笑)
でもね、その結果
- 楽するためにどうするか?
- 効率化するためできることはあるか?
という視点が磨かれてきましたし、なければつくってしまえ、という思考&行動パターンになってきました。エンジニアに復帰した僕としては、これはとても望ましい成長と思っています。
ひとつひとつ作っていく感覚は楽しいです。
最近はコロナのせいで自宅に籠る時間ができました。だからこそ、思いっきり勉強したり、思いっきり怠惰をむさぼったり、これまでの生活スタイルを進化させられるんじゃないか、と僕は思います。
たとえば、当たり前と言われているものの反対をやってみて、人間としての幅を広げられたらいいんじゃないかな。
「より良い未来のために、今できることをする」です。
参考: sync_gridsome.py
""" pyftpsyncライブラリを同期モードで使用し、Gridsomeでビルドしたデータ(dist/)をデプロイ先と同期する """
import configparser
import logging.handlers
from ftpsync.ftp_target import FtpTarget
from ftpsync.targets import FsTarget
from ftpsync.synchronizers import BiDirSynchronizer
from ftpsync.util import set_pyftpsync_logger
def sync_gridsome() -> None:
"""
指定のローカルとリモートディレクトリを同期する
"""
cfg = configparser.ConfigParser()
cfg.read("config.ini")
# ローカルとリモートの設定
local = FsTarget(cfg["PATH"]["LOCAL"])
user = cfg["FTPS"]["USER"]
passwd = cfg["FTPS"]["PASSWORD"]
remote = FtpTarget(
cfg["PATH"]["REMOTE"], # リモートディレクトリパス
cfg["FTPS"]["SERVER"], # FTPサーバ
username=user,
password=passwd,
tls=True, # FTPS有効
)
# オプション設定
# ローカル優先/--deleteオプション有効/指定ディレクトリは同期除外
# opts = {"resolve": "local", "delete": True, "force": True}
opts = {"resolve": "local"}
# 同期の実行
sync = BiDirSynchronizer(local, remote, opts)
sync.run()
if __name__ == "__main__":
# ロガーの設定
# pyftpsync.logにログを残す
logger = logging.getLogger("sync.gridsome")
log_path = "./pyftpsync.log"
handler = logging.handlers.WatchedFileHandler(log_path)
formatter = logging.Formatter(
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
handler.setFormatter(formatter)
logger.addHandler(handler)
set_pyftpsync_logger(logger)
# 同期
sync_gridsome()
▶ 最新版はGitHub