はじめに
- Rustでわざわざ公式のイメージを使わないで環境を構築してみる。
- Dockerが必ず使える環境とは限らない。あとどのようなライブラリが必要か勉強になる
- いろいろとトライアンドエラーで3~4日構築に時間がかかった。
- alpineを選択している理由は自分が動かしているサーバーが600円ぐらいのLinuxサーバーのため、重たいOSは厳しいため。 hub.docker.com
Dockerfile
- rustのインストールが対話形式のため、rust_install.shを利用して
expect
を利用している。 - developerユーザーを作成しているのはRustのプロジェクトを作成するときにrootユーザーでは作成できないため、作成している。 ※ユーザー名は何でもよい。
FROM alpine:latest RUN apk update RUN apk add --no-cache curl openssl ncurses-libs libgcc gcc expect sudo musl-dev make g++ WORKDIR /srv RUN echo 'root:root' |chpasswd RUN adduser -S developer \ && echo "developer ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers \ && echo 'developer:developer' | chpasswd RUN su -s /bin/ash developer RUN curl -f -L https://static.rust-lang.org/rustup.sh -O USER developer ADD rust_install.sh ./ RUN sh rust_install.sh ENV PATH="/home/developer/.cargo/bin:$PATH"
Rustインストール用シェルスクリプト
- Rustの対話式のインストールを自動化するためのシェルスクリプト
- sleepはインストールする環境のスペック次第で短くできるはず、
- sendの1は対話で聞かれるインストール形式の指定のため、自分はdefaultの1を指定している
1) Proceed with installation (default) 2) Customize installation 3) Cancel installation
シェルスクリプトのコード
#!/bin/sh expect -c " spawn sh /srv/rustup.sh expect \">\" send \"1\n\" sleep 10 expect"
Docker build
- Rustフォルダを作成して、Dockerfileとrust_install.shを同じディレクトに格納して、そのフォルダ内で下記のコマンドを実行する
docker build -t rust-rocket-api .
- 実行後下記のようにイメージが作成されている
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE rust-rocket-api latest b00d1cebd60c 15 minutes ago 521MB alpine latest a24bb4013296 4 weeks ago 5.57MB
Dockerコンテナ起動
- ユーザーとポート指定をして起動する。Rocketのアプリケーションサーバは8000ポートで起動するため
# docker run -e USER=developer -p 80:8000 -it rust-rocket-api /bin/ash
Rocketをインストールする
- developerのホームディレクトリに移動する
/srv $ cd ~ $ pwd /home/developer
リリースチャンネルを選択
- stable / beta / nightly の3 つのリリースチャンネルがあり。nightly は最新の開発版、stable がリリース版。beta では nightly でのテストが終わりリリースに向けた機能。
$ rustup install nightly $ rustup default nightly info: using existing install for 'nightly-x86_64-unknown-linux-musl' info: default toolchain set to 'nightly-x86_64-unknown-linux-musl' nightly-x86_64-unknown-linux-musl unchanged - rustc 1.46.0-nightly (394e1b40d 2020-06-27)
プロジェクトの作成
~ $ cargo new hello-rocket --bin Created binary (application) `hello-rocket` package ~ $ cd hello-rocket ~/hello-rocket $
Cargo.tomlファイル
vi Cargo.toml [package] name = "hello-rocket" version = "0.1.0" authors = ["developer"] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] rocket = "0.4.5" <- こちらを記述する
RocketでHello,word!
vi src/main.rs #![feature(proc_macro_hygiene, decl_macro)] #[macro_use] extern crate rocket; #[get("/")] fn index() -> &'static str { "Hello, world!" } fn main() { rocket::ignite().mount("/", routes![index]).launch(); }
Rustサーバーを起動する
- 作成したプロジェクトのルートディレクトリで実行する
cargo run ? Configured for development. => address: localhost => port: 8000 => log: normal => workers: 2 => secret key: generated => limits: forms = 32KiB => keep-alive: 5s => tls: disabled ? Mounting /: => GET / (index) ? Rocket has launched from http://localhost:8000
リクエストを投げる
- Hello,World!と表示されていることを確認する
$ curl localhost:8000 Hello, world!
- アプリケーションサーバーのログにもリクエストがきていることを確認する
GET /: => Matched: GET / (index) => Outcome: Success => Response succeeded.
まとめ
- 現時点のファイルはコマンド一発ですべて動く環境が整っていないので、近いうちにdokcer-compose化を目指します。
- サーバーはメモリは最低1GBはほしい。500MBだとしんどかった。
- curlでリクエストが通りましたがブラウザからのアクセスができなかったので調査をする
環境構築時にやくにたった情報
https://github.com/SergioBenitez/Rocket/issues/735 https://github.com/rust-lang/rust/issues/60149