55
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

actix-webのホットリロードされるDocker開発環境を作る

Last updated at Posted at 2020-05-27

編集履歴

日付 内容
2021/05/10 actix-webのドキュメントに記載のAuto-Relodingの手順が変わった旨を追記

はじめに

本記事では表題の通り、actix-webの開発環境について検討します。
actix-webはRust製のweb frameworkで、LL製の有名フレームワークより高速に動作することで知られています。
https://www.techempower.com/benchmarks/

一方で、修正を確認するためには都度コンパイルをする必要があり、RubyやPythonのような軽量言語に比べると開発効率が下がるのでは、という懸念があるかと思います。
(実際には型安全でコンパイラのチェックが優秀なRustは結果として開発効率が良い可能性もありますが。)

そこで、本記事ではLL製の有名フレームワークと同等の効率でRust製のAPI Serverを開発するための環境を構築する方法を検討します。

理想の開発環境

現代のWebアプリ開発はコンテナベースで行われることが多いかと思います。
そこで、本記事では

  • docker-compose upとか打ったら開発環境が動く
  • 開発用と本番用のDockerfileが共通になっており、本番用のイメージが小さい
  • 修正がすぐに確認できる

のような条件を満たす開発環境を目指します。

想定する構成

本記事では、Vue.jsで作られたSPAのフロントエンドからactix-webで作られたAPI Serverへリクエストする構成を考えます。
本記事の主な対象ではないのですが、DBにはPostgreSQLを想定しています。

  • フロントエンド:Vue.js
  • バックエンド:actix-web
  • DB:PostgreSQL

image.png

本題

本記事ではRustに関係する部分のみを紹介します。
上記構成を作る全体像が必要であれば、成果物のリポジトリをご参照ください。

Dockerfile

Dockerfileの作成にはDockerfileを改善するためのBest Practice 2019年版を非常に参考にしています。

まず、マルチステージビルド機能を使用して開発用のステージとビルド用、本番用のステージを分けています。本番用には開発用に比べて軽量なベースイメージを使用しており、例えばFargateなどにデプロイする際にかかる時間を減らしています。

なお、今回は本番用のベースイメージにrust:1.43.1-slim-stretchを使用していますが、開発環境は不要なのでもっと小さなイメージを使用することが可能です。
ベースイメージについては以下のリンクが参考になります。
参考:RustのLinux muslターゲット (その2:極小Dockerイメージを実現)

Dockerfile
# 開発環境
FROM rust:1.43.1 as develop-stage
WORKDIR /app
RUN cargo install cargo-watch
COPY . .

# ビルド環境
FROM develop-stage as build-stage
RUN cargo build --release

# 本番環境
FROM rust:1.43.1-slim-stretch
COPY --from=build-stage /app/target/release/api .
EXPOSE 8088
CMD ["/usr/local/bin/api"]

ちなみに、このDockerfileと同じパスに

.dockerignore
target

というファイルを置いています。
これは本番用のイメージをビルドする際に、COPY . .で時間をかけないようにする意図があります。

docker-compose.yml

以下のyamlはRust部分のみを抽出したdocker-compose.ymlです。
buildには先ほどのDockerfileを指定し、targetには開発用のステージを指定します。

また、中間ファイルのディレクトリをキャッシュすることでdocker-compose upするたびに不要なビルドが実行されることを回避しています。

commandにはcargo watch -x runを指定しており、これによってホットリローディングを実現しています。
なお、actix-webのドキュメントにはAuto-Reloading Development Serverという項目が存在するのですが、ここで紹介されているsystemfdsystemdを必要としており、docker上で動かすのが難しいと思い断念しています。
(2021/05/10追記:現在はactix-webのドキュメントでも cargo watch を使用する手順となっています)

cargo watchでは修正するたびにプロセスを再実行するのだと思いますが、ステートレスなAPI Serverを開発する分には影響が少ないと判断しています。

docker-compose.yml
version: '3.7'

services:
  backend:
    build:
      context: ./backend
      target: 'develop-stage'
    ports:
      - "8088:8088"
    depends_on:
      - db
    volumes:
      - ./backend:/app
      - cargo-cache:/usr/local/cargo/registry
      - target-cache:/app/target
    command: /bin/sh -c "cargo watch -x run"

volumes:
  cargo-cache:
  target-cache:

成果物

上記構成で作られた開発環境のサンプルは以下の通りです。
本記事では紹介しなかったフロントエンドのDockerfileなども含まれます。

まとめ

API Serverの開発には十分なactix-webの開発環境を構築することが出来ました。
修正するたびにコンパイルする状況に比べれば良い環境ではないかと思います。

今回は開発時の構成にのみ着目しましたが、実際の開発ではユニットテストの実行やCI/CDの考慮が必要だと思います。
その場合には、本記事で紹介したDockerfileに適切にステージを追加することで必要なイメージを効率よく作ることができると思います。

将来的には開発の全体をカバーしたサンプルプロジェクトを作れたらと考えています。

55
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
55
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?