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サポートとかも今後進んでいくのではないかと個人的には期待。