【assets-syncer】個人開発で使える最強の画像サーバを作りたい話
【assets-syncer】個人開発で使える最強の画像サーバを作りたい話
個人的にいい感じの画像サーバを作ったのでブログとして書き留めておく。
2022/03 追記) 今回は楽しくなって Ruby + Docker で実装したが、macOS なら fswatch を使ってファイル監視時の処理を作っていく方が多分良い。(gulp とか使うのもあり?)
作ったもの
-
画像サーバ
- 画像例 https://images.igsr5.com/l/sample.png
- ただの s3 + CloudFront 構成の静的ファイルサーバ
-
assets-syncer
https://github.com/igsr5/assets-syncer/開発用便利ツール。指定のローカルディレクトリに画像を置くだけで
https://images.igsr5.com/l/
から配信できる。
→ https://images.igsr5.com/l/profile.png で公開
モチベーション
自分でサービスを作る際の画像に関する仕組みを整えたい
普段プライベートでサービスを作る際に「画像をどこから配信しよう」と考えることが多く、それを考えなくていいような仕組みを作りたかった。最近だとポートフォリオ制作の際にプロフィール画像や制作実績の画像をどこから配信するかで少し考えた。
具体的には
- 各制作物ごとに画像配信元がバラバラ
- 毎回ドメインやキャッシュのことを考えるのが面倒
- 開発時にローカルリポジトリに画像ファイルを置いて開発するのが面倒
- 気軽に画像を差し替えたい
などの悩みがあった。
デザイン
汎用画像サーバと開発用の便利ツールを作った。
汎用画像サーバ
画像配信は s3 + CloudFront のとてもシンプルな構成になっている。ドメインは images.igsr5.com
。
画像例 https://images.igsr5.com/l/sample.png
インフラ構成図
ref. https://carefree-se.hatenablog.com/entry/2019/10/16/094940
ちなみに個人開発で用いる全てのインフラリソースは https://github.com/igsr5/igsr5-terraform で terraform + GitHub Action を用いて管理している。
assets-syncer
開発用に簡単に画像をアップロード、配信できる便利ツール。
→ https://images.igsr5.com/l/profile.png で公開
上のように特定のディレクトリにファイルを配置すると s3 バケットの /l/
ネームスペース配下に同期される。(開発用に配信URLのネームスペースを分けている)
設計
aws s3 sync
を実行するスクリプトを docker コンテナ内で定期実行している。
# /job/sync_s3.rb 一部抜粋
# ジョブ開始時にs3 オブジェクトをローカルにコピーする。
system('./pull_images.sh')
loop do
system('./sync_images.sh')
rescue StandardError => e
logger.error(e)
break
end
# /sync_images.sh 一部抜粋
#!bin/bash
aws s3 sync ./images $AWS_S3_BUCKET_PATH --delete
(ログ周りの処理は省略)
docker コンテナは restart: always
オプションを指定し、常に起動するようにしている。
リポジトリ内の /images
配下が s3 バケットと同期されることになるので、 images
ディレクトリを Finder のスライドバーに置いて開きやすいように運用している。
より詳しい設計、実装はGitHubリポジトリを見るとわかる。
作った感想
全体的にとても単純に設計になっているが、assets-syncer はとても便利なものとなった。
具体的にはサービスを作る際、ちゃんとした画像アップロードの仕組みが整うまでの画像配信の仕組みを整えることができた。
また、今回シェルスクリプト等のコマンド処理をローカルで定期実行する仕組みに初めは cron や launched を検討したが、ruby でデーモンを実装し、それを docker コンテナ内に常駐させるという方法をとった。
これは思いつきであったが、リポジトリ内で仕組みを完結させることができたり、ログ管理などを追加する際に柔軟性があったり、とても良かった。
今回は開発用途に特化して画像配信の仕組みを作ったが、本番用途でも使えるように画像加工やs3 クライアントをラップした便利ライプラリなどの仕組みも整えていきたい。
Discussion