NetlifyでRustを使う
May 5th, 2020
Introduction
Why Rust?
最近Rustを勉強し始めて、ゴールデンウィーク中にRustのThe Bookを一通りやって、最終的にyewというRust版React(どっちかというとElm?)を試そうと決めました。
一通りThe Bookは終えたのですが、Rustいいですね。 「安全性」「速度」「可読性」どれをとっても文句なし。 HaskellやScalaでよく聞くコンパイル時間や実行速度の問題もないし、C++などでよく聞くメモリ系の脆弱性に対してもコンパイラがかなり堅牢なので意図せずにはメモリ脆弱にはなりにくい。 もともとFirefoxがCSSエンジンをRustにしたらメモリ脆弱性が何十個も減った、とか言ってた理由もわかるしブラウザのような高い性能が求められるシステムを対象にしても十分やっていけるのも頷ける。
フロントエンド界隈でもwasmで注目されてるし、AmazonやMSが去年採用決めたりして盛り上がってきてるので、サーバーサイド・フロントエンド問わず興味があるならぜひThe Bookのチュートリアルを始めることを進めます!(宣伝?)
Netlify+Rust
とまぁ、順調にThe Bookは進められたのですが、せっかくなので後々ブログのネタにしようと思い、作成物をNetlifyにあげようと思ってたのですが、NetlifyってそもそもRustサポートしてなかったんじゃなかったっけな・・・と思ったら案の定未サポート。
yewやwasmのサンプル見てると結構Netlifyにあげてる人多いのにやり方どこにも書いてないなぁ、、、 ということで、備忘録もかねてNetlifyでRustでビルドしたサイトを運用する方法を書き残していきたいと思います。
作成物
今回はRust(wasm、もっと言えばyew)をビルドしてホスティングすることが目標です。
wasmのビルドには元のコンパイル環境とwebpackが必要になりますが、yewにはもろもろ設定したテンプレートがあるのでこれを使うと便利かと思います。 (Rustやwasmの環境構築手順は割愛します)
まずは↓のテンプレートの「Use this template」をクリックして自分のリポジトリを作成しておきましょう。
https://github.com/pvcresin/yew-markdown-preview
ちなみにyewの話はしないので、yewじゃなくても全然いいですが、↑のテンプレートだとNetlifyへのデプロイ設定ファイルが用意されてたりするので今回はこのテンプレートで進めたいと思います。
Netlifyのホスティング方法
先述の通り、NetlifyはRust未サポートです。 なので、NetlifyでRustのビルド成果物をホスティングするなら以下の方法が考えられます。
- 毎回ビルドした結果をコミットする
- 成果物をドラックアンドドロップでNetlifyにあげる
- 別なビルドサーバーでビルドして、Netlifyへ自動であげる
理想は最後の方法ですが、ビルドサーバーを毎回どっかに立てて消すなんて辛いですよね、、、 ですがこのテンプレートだとそれに近しいやり方をすでに用意してくれてます。 Github Actionsを利用した方法です。
Github Actions
恥ずかしながらあんまりGitbhub Actionsをあまり分かっておらず、プルリクフック的な何かくらいしか知りませんでしたが、Github ActionsはGithubに紐づく何かしらのイベント(PushとかPull Requestとか)ごとに行いたいことをやってくれる環境を提供してくれます。 よくあるのはLintやformatなどですね。
もちろん、ビルドすることも可能なのでwasmをビルドすることも可能です。 Github ActionsではDockerのイメージ取得のようにして、簡単に一時的作業環境を構築してくれます。
yewのテンプレートリポジトリの/.github/workflows/deploy.ymlをみてみましょう。 これはNetlifyへ自動デプロイする設定です。
name: Deploy to Netlify
on:
push:
branches: [master]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: wasm32-unknown-unknown
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 14
- name: Install
run: npm install
- name: Build
run: npm run build
- name: Publish
uses: netlify/actions/cli@master
with:
args: deploy --dir=dist --prod
env:
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
secrets.NETLIFY_SITE_IDとsecrets.NETLIFY_AUTH_TOKENはNetlifyのactionsのREADMEから設定方法がかいてあるので、その通りにやると無事NetlifyへPOSTすることができます。 これらの設定にはあらかじめサイトをNetlifyへ構築しておく必要があるので、netlify配下を丸ごとドラッグ&ドロップなどで1個サイトを作っておくとスムーズです。
今回Rustのビルドは、webpackのwasmプラグイン経由でwasmにビルドするようになっているので、Rust環境さえあれば十分なので、Rustのsetupのみでcargo buildなどは行なっていません。 yewやwasmではなく、ここでcargo buildしたいなどの場合はrunをするstepを追加すればいいだけです。
これで無事、Rustをビルドしホスティングすることが可能になりました。
NetlifyではなくGithub Pagesを使う
今回僕がやりたかったのはただの成果物の確認環境なので、Netlifyまで使わずとも、Github Pagesで事足ります。 ということで先ほどビルドした結果をNetlifyへPOSTしていたのをちょっと変えるだけでGithub Pagesにデプロイすることができます。
name: Deploy to Github pages
on:
push:
branches: [master]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: wasm32-unknown-unknown
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 14
- name: Install
run: npm install
- name: Build
run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
secrets.GITHUB_TOKENは毎回Github Actionsから自動で発行されるものなので設定は不要ですが、コミットするブランチが必要になるのでSettingからGithub Pagesの対象ブランチをgh-pagesにする必要があります。
github https://github.com/AkifumiSato/yew-markdown-demo
demo https://akifumisato.github.io/yew-markdown-demo/
※yewのお試しに内容は変動するかもしれません。
まとめ
NetlifyがRustサポートしてないことがちょっと悲しかったですが、ビルド成果物をNetlifyにPOSTなんてできるんですね。 ビルドサーバーの制約を外に逃す方法もちゃんと用意してるなんてさすが(信者)。
そしてGithub Actionsが便利すぎて、、、 これ使えばlintとかformatとか、テストすらJenkinsとかコミットフック用意する必要ないんですねー。 自動化にかけるコストの問題って仕事である以上どうしてもバランス感難しいなといつも思うんですが、これだけローコストで色々自動化できるのは素晴らしいですね。 「自動化して楽しよう」を目指すのがちょい前のいけてる考え方だった感ありますが、最近は「自動化も楽しよう」みたいな感じがしますね。
GithubとNetlifyは共謀してWebの未来を企んでるらしいので、今後さらにこの辺の連携が進化していきそうで楽しみ。 Netlifyのwasmサポートとかも今後進んでいくのではないかと個人的には期待。