ソモサン

私rohkiによる活動や読書の記録をつらつらと書くページです

Rust で書いた HTTP サーバーを Github 経由で Zeit へデプロイした

成果物

github.com

でけたー。面白い。

Zeit

zeit.co

クラウドベンダーの模様。
CDN やら DNS やらがある。
今回はインスタンスを作るタイプ。

Docker でデプロイ

zeit.co

Docker image でデプロイできるすごいやつです。 僕にとっては、デプロイ先のサーバーがない状態になります。
CLI 上で操作ができるよう、バイナリも用意されています。

Github との統合

zeit.co

が、今回は Github との統合を行いました。
Pull Request を送ると、すぐにデプロイが始まる感じです。

f:id:rohki:20180916111037p:plain

実際の Pull Request

こんな感じ。

ぶつかったこと

100 MB 制限

Docker image の上限が 100 MB まででした。

f:id:rohki:20180916111402p:plain

実際のログ

適当に書いた Dockerfile ではあったものの、400 MB…
ちょっと根本的に考えを変えないといけない感じです。

解決: Multi stage build

FROM ekidd/rust-musl-builder:stable AS rust-builder
ADD . .
RUN cargo build --release --target x86_64-unknown-linux-musl

FROM alpine:3.8
COPY --from=rust-builder /home/rust/src/target/x86_64-unknown-linux-musl/release/zeit-sample /usr/local/bin
RUN apk add --no-cache ca-certificates && update-ca-certificates
ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
ENV SSL_CERT_DIR=/etc/ssl/certs
CMD ["zeit-sample"]

以下 2 つを参考にしました。

こんなことできたんすねー。知らなかった…
Multi Stage Build という手法で、ドキュメント もあります。

ビルド環境と実行環境を明確に分けることで、デプロイに使用する Docker image の内容物を最小限にできます。
上記で最終的には、6.6 MB になりました。

やってみて

✅ ポートを自動検索してくれる

最初 EXPOSE 書いてたんですが、自動で見つけてくれるらしくいらなかったです。

✅ Cold 状態からの起動が早い

5 分(だったかな?) で環境が Cold 状態に移行するのですが、そこからの起動が早いです。
Cold 状態からの起動だった場合は、上記したポートの自動検索の結果がログにでます。
でも、その差がわかりづらいです。

Github との連携が楽

自動でやってくれるのはよいですねー。
Dockerfile 書いて now.json 書いたらデプロイまでやってくれるってのはありがたい。

❌ 100 MB 制限がキツい?

環境や言語によっては、100 MB の制限は厳しい、のでしょうか? Runtime やバイナリの大きさ次第では、この制限を通過するために、あれこれと努力する必要が出てくるかも。
Golang の 1 バイナリで済むというデプロイしそうがここでも聞いてくるのかなーとか思いました。
先ほどのビルド環境と実行環境を分けることで、純粋な Linux 環境にバイナリをコピーすればおしまい的な。

おわりに

で、この文章を書いてるときに関連文書を見直してるとサンプルを見つけて、かつ Rust もあるという…

now-examples/rust-rocket at master · zeit/now-examples · GitHub

おんなじじゃん!!!
ちゃんとドキュメントというかリリースノートというか、そのあたりは読みましょう…

それはさておき、デプロイの方法とか環境情報の持たせ方とか、パフォーマンスの考え方、そして実装方法。
特に初期起動コストを支払う回数が増えるってのが違うかも。