RustとDockerでWEBサーバーを立ててみた

2021/09/12 2021/09/13 #Docker #Rust

RustとDockerでWEBサーバーを立ててみた

こんにちは。のんです。

今回は前回からやっている

の続編になります。

Rustを使うにしても、結局私はWEB屋なので組み込みとかにはあまり使わずWEBアプリの開発に利用するでしょう。

ということで、WEBアプリとして実行できる開発環境の構築をしつつ、WEBアプリとして基礎的な動作をするところまで進めたいと思います。

勉強用リポジトリ

バージョンの管理とか面倒。Dockerを使いたい。

こちらは前回触れていなかった内容です。

公式の推奨はRustupを利用することです。

しかし、正直複数人でプロダクトを管理するときにバージョン管理とか面倒。絶対Node.jsとかと同じ道を歩みそう。

ということでDockerを利用しています。

app:
  container_name: app
  ports:
    - 8080:8080
  build:
    context: ./
    dockerfile: Dockerfile
  volumes:
    - ./app:/app:cache
    - rust-target:/app/target
    - cargo-cache:/usr/local/cargo/registry
  working_dir: /app
  depends_on:
    - mysql
  command: /bin/sh -c "cargo watch -x run"

WEBアプリとしてポートを開放するときには8080番ポートを利用するようにしています。80番はよく使うし、他のアプリとも競合しそう。セキュリティ的にどうなんだというところも。

ports:
  - 8080:8080

と記載することで、http://localhost:8080 でアクセスすると出てくるようにします。

volumes:
  - ./app:/app:cache
  - rust-target:/app/target
  - cargo-cache:/usr/local/cargo/registry

rust-target:/app/targettarget内のものをボリュームに保存できるようにします。target内にはコンパイルした成果物が保存されます。

cargo-cache:/usr/local/cargo/registrycargoコマンドのキャッシュを保存しておきます。一応cargo run時に時間がかからないようにするために追加していますが、あまり...効果は無さそう。この辺は後で勉強し直しましょう。

command: /bin/sh -c "cargo watch -x run"

これはホットリロードのためにしています。詳細は後で。

actix-webを利用してWEBアプリとして起動する

Cargo.toml

[package]
name = "sample"
version = "0.1.0"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
actix-web = "3.3.2"

[[bin]]
name = "sample"
path = "main.rs"

に変更。
変更箇所は以下。

[dependencies]
actix-web = "3.3.2"

actix-webのライブラリをインストールするようにしています。今の所、このファイルの設定はPHPでいうcomposerという認識。多分合っているでしょう。

この状態でcargo runすると、ライブラリをインストールしてコンパイルしてくれます。

肝心のソースコードはこちら

use actix_web::{get, App, HttpResponse, HttpServer, Responder};

#[get("/")]
async fn index() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(index)
    })
    .bind("app:8080")?
    .run()
    .await
}

ほとんどはactix-webのサンプルの通り。

一点、他と違うのはこちら。

.bind("app:8080")?

127.0.0.1:8080としてはいけません。

頭がRustでいっぱいになっていて忘れがちです。私はここで1時間ハマりました。
ここではDockerを利用しているので、コンテナ間で共有されている仮想ホスト名である、コンテナ名を指定します。

ソースコードが書き終えたらコンテナを起動します。

docker compose run --rm app cargo run

このとき、コンパイルのためのモジュールが足りないとエラーが発生する場合があります。

FROM rust:1.53.0-alpine3.13

RUN apk update
RUN apk add alpine-sdk

COPY ./app /app

alpine-sdkが足りないので、Dockerfileに追記しておきます。

RUN apk update
RUN apk add alpine-sdk

実行結果:

スクリーンショット 2021-09-12 4.36.45.png

ここで気づいたのですが、WEBサーバーがありません。
調べてみると、どうやらactix-webがその辺もしてくれているようです。もちろんnginxを前に立ててプロキシ機能を利用すれば、Appサーバーのように振る舞うこともできます。

ホットリロードに対応する

ソースコードを変更するたびにコンテナを起動し直すのは面倒ですし、時間がかかります。
そこで、ReactやVueのようにホットリロードできるようにします。npm run watchですね。

このあたりの機能も用意されています。
今回利用するのはcargo-watchです。

Dockerfile

FROM rust:1.53.0-alpine3.13

RUN apk update
RUN apk add alpine-sdk
RUN cargo install cargo-watch

COPY ./app /app
RUN cargo install cargo-watch

を追記します。

docker compose run --rm app cargo run

を毎回打つのが面倒くさいです。

docker compose up -d

で全てを終わらせたいので、

docker-compose.ymlに下記を追記します。

command: /bin/sh -c "cargo watch -x run"
cargo watch -x run

でホットリロードできるようになります。この辺のコマンドは公式ページを見て変更しても良いかもしれません。

最後に

今回はRustの勉強の続きを記事にしてみました。

このブログはレスポンス遅いですし、処理も昔のコードのまま。
現在はPHPなのですぐに書き直してもいいのですが、せっかくなので高速と言われているRustで書き直そうかなと思っています。

フロントはNuxtかReactですかね。NextはReactの本格的な勉強をしてからにしたいので、候補外。

それかWebAssemblyでもいいかもと思っていますが、これだといつになるやら...という感じなので、、多分Nuxtかなと思います。

次回はHttpRequestやResponseを捌く箇所を勉強したいです。
また記事にしたいと思います。

その時はよしなに。

.

のん

所属 : 株式会社スマレジ 開発部

YouTube : のんラボ

Twitter : @nonz250

Github : nonz250

Qiita : @nonz250

My Qiita posts My Qiita contributions My Qiita followers

主にPHPを使用し、サーバーサイドを担当。最近はフロントにも興味津々。

なにかを作ったりいじったりするのが好きで、個人開発なども行っている。

趣味はバイクアイコン画像は大抵愛車の「Z250」である。友達にアイコン描いてもらえて嬉しい。

PHP / Laravel / CakePHP2 / CakePHP3 / Vue / Nuxt / C# / etc...

Tags

#のんラボ #Laravel #Vue #個人開発 #ブログ #プログラミング #javascript #Html5 #WEBサービス #Twitter #今年の抱負メーカー #勉強方法 #PWA #モバイルアプリ #Android #ツーリング #バイクに乗るエンジニア #Z250 #秋吉台 #能登半島 #バイク #冒険 #東尋坊 #Squid #リバースプロキシ #hosts #axios #cropper #AdSense #Bootstrap #MySQL #高速化 #トドTask #Telescope #デバッグ #composer #テスト #セキュリティ #POSレジ #スマレジ #本部機能 #バリデーション #入力チェック #Mac #Chrome #テスト駆動開発 #開発手法 #UI #デザイン #WEBサイト #機能美 #PHP #Laravel 6 #コメント #バージョンアップ #vue-cli #localhost #BIツール #売上分析 #TANAX #MFK250 #ツアーシェルケース2 #RESTful #API #REST API #実務的 #PHP Tech Tutor #Smaregi Tech Talk #勉強会 # ブログ #CakePHP3 #CSRF #VSCode #開発環境 #CakePHP3.0 #さくらのレンタルサーバー #モジュールモード #シェル #メール #Gmail #relay #OGP #エラーページ #抱負 #家庭教師 #ドメイン駆動設計 #DDD #読書会 #那智の滝 #伊勢志摩 #伊勢志摩スカイライン #フロント #三方五湖 #レインボーライン #ボーイスカウト・ルール #プログラマが知るべき97のこと #リファクタリング #ユビキタス言語 #車輪の再発明 #マイクロサービス #デプロイ #QA #laravel-mix #Tips #storybook #@storybook/addon-actions #昇降デスク #コードレス #書斎 #オフィス #リモートワーク #働き方 #エラーハンドリング #スマレジ4 #pixel 5 #レビュー #スマレコ #TDD #RSS #404 #高山ダム #ラーツー #React #Nuxt #node_modules #エラー #インポート #設定方法 #環境構築 #Docker #フォレストパーク神野山 #学生向け #PR #採用 #Node.js #npm #しまなみ海道 #youtube #CSS #IE #SLA #Rust #千里浜なぎさドライブウェイ #千里浜 #インサイドセールス #曽爾高原 #無線LAN