はじめに
この記事はSplashをHerokuにデプロイする手順の解説記事です。
SplashはJavaScriptレンダリングが可能な、スクレイピングに特化したPython製のヘッドレスブラウザです。
ローカル環境では公式のDockerイメージで起動することができます。docker run -it -p 8050:8050 --rm scrapinghub/splash
このSplashをHeroku上で動かそうと試したときの手順をまとめます。
Splashのイメージ
前提
- Herokuアカウント作成済み
- Heroku CLI インストール済み
- Docker インストール済み
手順
Heroku Container Registry を使用するとDockerイメージをHerokuにデプロイできます。
ただし、いくつか制約があり元のSplashイメージをそのまま使うことはできないので、修正したイメージをリリースします。
1. Dockerイメージを作成する
Dockerfileを作成
# 公式のイメージをベースにする
FROM scrapinghub/splash
# ベースのENTRYPOINTを上書きする
ENTRYPOINT [""]
# 環境変数のポート番号で起動する
CMD python3 /app/bin/splash --port $PORT
Dockerイメージをビルド
ここではmy-splashというイメージ名を付けてビルドします。
$ docker build -t my-splash .
docker inspectコマンドでEntrypoint
とCmd
を確認できます。
$ docker inspect my-splash
〜〜略~~~
"Cmd": [
"/bin/sh",
"-c",
"python3 /app/bin/splash --port $PORT"
],
〜〜略~~~
"Entrypoint": [
""
],
〜〜略~~~
2. Herokuアプリを作成する
Herokuにログインし、新しいアプリを作成します。
$ heroku login
$ heroku create
Creating app... done, ⬢ <アプリ名>
3. Dockerイメージにプッシュ用の名前を付ける
命名規則に従って先ほど作成したイメージに別名をつけます。
<アプリ名>
の箇所はheroku create
時に作成されたアプリ名です。
$ docker tag my-splash registry.heroku.com/<アプリ名>/web
4. Herokuにイメージをプッシュする
Herokuのコンテナレジストリにログインします。
$ heroku container:login
DockerイメージをHerokuにプッシュします。
$ docker push registry.heroku.com/<アプリ名>/web
5. リリースする
$ heroku container:release web -a <アプリ名>
動作確認
ページを開くと、無事Splashの画面が表示されました。
$ heroku open -a <アプリ名>
render.htmlエンドポイント
curl "https://<アプリ名>.herokuapp.com/render.html?url=http://google.com&wait=0.5" -o test.html
- test.html
<!DOCTYPE html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en"><head>
〜略〜
render.pngエンドポイント
$ curl "https://<アプリ名>.herokuapp.com/render.png?url=http://google.com&wait=0.5" -o test.png
説明
公式イメージのDockerfile
Splashの公式イメージDockerfileの最後あたりは以下のようになっています。
〜〜略〜〜
VOLUME [ \
"/etc/splash/proxy-profiles", \
"/etc/splash/js-profiles", \
"/etc/splash/filters", \
"/etc/splash/lua_modules" \
]
EXPOSE 8050
ENTRYPOINT [ \
"python3", \
"/app/bin/splash", \
"--proxy-profiles-path", "/etc/splash/proxy-profiles", \
"--js-profiles-path", "/etc/splash/js-profiles", \
"--filters-path", "/etc/splash/filters", \
"--lua-package-path", "/etc/splash/lua_modules/?.lua" \
]
このうち Heroku Container RegistryではVOLUME
とEXPOSE
コマンドをサポートしていません。
また、ポートはHerokuで指定される$PORT
環境変数の番号でリッスンする必要があります。
VOLUME - ボリュームマウンティングはサポートされていません。 dyno のファイルシステムは一時的です。
EXPOSE - EXPOSE はローカルテストに使用できますが、Heroku のコンテナランタイムではサポートされていません。 代わりに、> > Web プロセス/コードで $PORT 環境変数を取得する必要があります。
ですので、コンテナ起動時のコマンドを変更することでHerokuで動くように対応させます。
- Splashのデフォルトのポート番号は8050ですが
--port
オプションで変更できます。 - プロファイルのディレクトリを指定している
--proxy-profiles-path
などはVOLUME
が使えないので除外することにします。
修正は公式GitHubのソースを変更してビルドし直す方法も可能ですが、
公式イメージをベースにDockerfileを作るほうが簡単ですのでその手順で行いました。
参考