Vagrant + CentOS7 で、RustのWebフレームワークRocketを発射する
Linuxとか環境面詳しくないのでメモ。
Rocketは最近出たRustのWebフレームワーク。
https://rocket.rs
環境
VirtualBox: 5.0.30
Vagrant: 1.9.1
CentOS: 7.1
Rust: 1.16.0-nightly
Rocket: 0.1.2
ちなみにこれを書いている時点で最新のCentOSは7.3だったけれど、vagrant up
で立ち上げたら途中で止まってしまったので断念。
VagrantでCentOS7を立ち上げる
まずは発射台を準備。
$ mkdir launch-pad $ cd launch-pad
Boxイメージは、Chef社がOSSとして公開してる「Bento」を使う。
(弁当箱とは誰がうまいことを)
https://atlas.hashicorp.com/bento
$ vagrant init bento/centos-7.1 A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on `vagrantup.com` for more information on using Vagrant.
Vagrantfileは以下のようにしてプライベートネットワークとして接続できるようにしておく。
Vagrant.configure("2") do |config| config.vm.box = "bento/centos-7.1" config.vm.network "private_network", ip: "192.168.33.11", auto_config: false end
原因はよく分かっていないのだけれど、auto_config: false
を設定しておかないと、立ち上げたVM上で正しくIPアドレスが振り当てられなかった。
VMイメージを起動。(Boxの取得から始まるので時間かかるよ!)
$ vagrant up Bringing machine 'default' up with 'virtualbox' provider... ...
SSHで接続。
$ vagrant ssh -bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory [vagrant@localhost ~]$
基本設定
ファイアウォールを切ってしまう。(仮想環境なので)
$ sudo systemctl stop firewalld
$ sudo systemctl disable firewalld
SELinuxが無効か確認。今回は無効になっているのでそのまま。
$ getenforce Permissive
Rustのインストール
Rocketでは構文拡張を利用するため、NigthlyなRustが必須。(2016/12/30時点)
Rust1.14.0で公式ツールとなったrustup
をインストールする。
https://rustup.rs
$ curl https://sh.rustup.rs -sSf | sh
info: downloading installer
...
選択肢が表示されるが、とりあえずデフォルトの1)を選択。
Current installation options: default host triple: x86_64-unknown-linux-gnu default toolchain: stable modify PATH variable: yes 1) Proceed with installation (default) 2) Customize installation 3) Cancel installation
Rust is installed now. Great!
To get started you need Cargo's bin directory in your PATH environment variable. Next time you log in this will be done automatically.
To configure your current shell run source $HOME/.cargo/env
パスを設定してくださいと言われるので、.bash_profile に記述しておく。
# Rust source $HOME/.cargo/env
再読込して現在のシェルに反映させておく。これでRustが使えるようになった。
$ source ~/.bash_profile $ rustc --version rustc 1.14.0 (e8a012324 2016-12-16)
そしてRustを最新版(Nightly)に変更。
$ rustup default nightly $ rustc --version rustc 1.16.0-nightly (4ecc85beb 2016-12-28)
Hello, world
Rocket用のプロジェクトを作成して、そこに移動。
$ cargo new hello-rocket --bin Created binary (application) `hello-rocket` project $ cd hello-rocket
Cargo.toml の依存ライブラリに以下を追加。
[dependencies] rocket = "0.1.2" rocket_codegen = "0.1.2"
src/main.rs を以下のように編集。このあたりは公式ドキュメントどおり。
#![feature(plugin)] #![plugin(rocket_codegen)] extern crate rocket; #[get("/")] fn index() -> &'static str { "Hello, world!" } fn main() { rocket::ignite().mount("/", routes![index]).launch(); }
そしてビルド・実行・・・するがエラーになる。
$ cargo run ... error: aborting due to previous error error: Could not compile `unicase`. To learn more, run the command again with --verbose.
どうやらgccが入っていないのが原因らしいのでインストール。
$ sudo yum -y install gcc
...
今度こそロケットを打ち上げられた。
$ cargo run Finished debug [unoptimized + debuginfo] target(s) in 79.19 secs Running `target/debug/hello-rocket` 🔧 Configured for development. => listening: localhost:8000 => logging: Normal 🛰 Mounting '/': => GET / 🚀 Rocket has launched from http://localhost:8000...
$ curl localhost:8000
Hello, world!
80ポートで起動する
ここからはあんまり正攻法じゃない。 ので、とりあえずこの方法でうまくいった程度の話。
Rocketのドキュメントを見ると、Productionで実行するには以下のようにすればよいと書いてある。
$ sudo ROCKET_ENV=staging cargo run sudo: cargo: command not found
が、エラーとなる。
これは環境変数PATHがsudo時に引き継がれないのが問題らしい。
$ env | grep PATH PATH=/home/vagrant/.cargo/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/vagrant/.local/bin:/home/vagrant/bin $ sudo env | grep PATH PATH=/sbin:/bin:/usr/sbin:/usr/bin
で、調べるといろいろと情報が出てくる。
CentOS で sudo 時に実行ユーザーのPATHを引き継ぐ http://qiita.com/ogwmtnr/items/3ec2fab50d069a3cf335
sudoで環境変数を引き継ぎたい http://mikio.github.io/article/2012/03/10_sudo.html
が、何を試しても一向にcargoのパスが引き継がれない。
仕方ないのでルートユーザーでもrustupを入れてしまう。(同様なので方法は割愛)
$ su -
# rustupのインストールと設定
ちなみにパスワードは「vagrant」。
そしてそのままルートユーザーで以下を実行すると、80ポートで起動する。
# ROCKET_ENV=staging cargo run 🔧 Configured for staging. => listening: 0.0.0.0:80 => logging: Normal 🛰 Mounting '/': => GET / 🚀 Rocket has launched from http://0.0.0.0:80...
ホストマシンからブラウザでアクセスしてみるとちゃんと動いている。 http://192.168.33.13
GET /: => Matched: GET / => Outcome: Succcess => Response succeeded. GET /favicon.ico: => Error: No matching routes for GET /favicon.ico. => Warning: Responding with 404 Not Found catcher. => Response succeeded.
ちなみにデフォルトの8000ポートだと以下のように指定してもアクセスできなかった。
http://192.168.33.13:8000/
ファイアウォールを切ったので問題ないと思ったのだが、何か設定がマズイのかもしれない。
終わり
Linuxとか環境構築とかあんまり経験ないので思ったよりもずっとしんどかった。 まぁしかしVagrantとか楽でいいなと思った。
とりあえず以下は解決したい課題。
- ルートユーザで実行しちゃってる。(本番環境なら大問題)
- 8000ポートでホストマシンから接続できるように。
- Linuxとか詳しくなる。