Heroku のファイル永続化用に Nginx nginx-upload-module でアップローダーを用意する
おはようございます。
先週末にはじめて Heroku にデプロイして以来その便利さのとりこになってとにかく何でもつくってはあげつくってはあげしています。自前のサーバーにあげるとリソースを食いあって残念なことになりますが、これなら多くても安心で文明を感じました。
アップロードしたファイルを Nginx に投げて保存してリネームして名前を返してもらって Heroku 側で保持する
さて、Heroku のネックといえばファイルの永続化ですが、外部ストレージとして Amazon S3 という選択が一般的みたいです。しかし従量課金と聞くと「朝……テレホーダイ……ウッ」となるわたしはファイルのアップロードと配信だけを処理するサーバーを用意したらいいんじゃないのと思いついて試しました。
Heroku から外部の Nginx へ
https://outer-uploader.herokuapp.com/new
おもてむきは Heroku で全部終わってる感じにしたいので、RestClient gem などを使って Nginx になげます。ここらへん、一つ無駄なファイルの転送が生じるのでどうにかなるならどうにかしたいですね。
RestClient::Resource.new(Settings.outer.upload_path, @id, @password).post(upload_file: @file)
Nginx nginx-upload-module
Nginx は受け取ったファイルを upload_store に保存し、元のファイル名、一時ファイルパスなどを upload_pass に指定したなにかに multipart のフォームデータとして渡します。
下記は最初に書いた sinatra に渡した時のやつです。(あとになって sinatra たちあげなくても cgi でいいんじゃないのと 書きなおしました)
Sinatra とか cgi でファイルを移動してその場所を返す
upload_file[filename]
とか upload_file[tempfile]
が渡されるのでそれをもとにファイル移動、json で返して、
{:result=>"ok", :name=>"9addc65e-ddff-44a3-a875-da778f068ad0.png"}
Heroku の DB で保持して使いたいように使う感じです。
https://outer-uploader.herokuapp.com/
Heroku いい
ファイル永続化がいい感じに解決できるのなら開発にも使っていきたいですね。
弊社は給料遅延が生じる感じのアレなので開発においてもいろいろアレっぽくって共生しまくってる結果レスポンスがアレでアレなので Heroku をうまく使ってそこらへんどうにかしたいですね。
sinatra のやつ
cgi にしたやつ