Rustのお勉強 - Dockerで環境構築

[プログラミングRust](https://www.oreilly.co.jp/books/9784873118550/)買いました。何やら難しそうですがやってみよう。

# 環境構築

本には[rustup](https://rustup.rs/)を使えと書いてあります。rustupはRustのバージョン管理をしてくれるもののようです。直接インストールしてもかまいませんがここはDockerでやってみます。

## Dockerfileを用意
`rust docker`でググるとDocker Hubの[Rust Official Repositry](https://hub.docker.com/_/rust/)が出てきました。どれがいいのかわからないので、とりあえず一番上の[Dockerfile](https://github.com/rust-lang-nursery/docker-rust/blob/da8bc5716ede5f18748e4daa92f85e9a9d9c1454/1.28.0/stretch/Dockerfile)をそのまま使います。
![スクリーンショット 2018-08-29 16.18.05.png](https://qiita-image-store.s3.amazonaws.com/0/96536/43a349da-c035-c62d-723e-796172394fc0.png)

```:Dockerfile
FROM buildpack-deps:stretch

ENV RUSTUP_HOME=/usr/local/rustup \
    CARGO_HOME=/usr/local/cargo \
    PATH=/usr/local/cargo/bin:$PATH \
    RUST_VERSION=1.28.0

RUN set -eux; \
    dpkgArch="$(dpkg --print-architecture)"; \
    case "${dpkgArch##*-}" in \
        amd64) rustArch='x86_64-unknown-linux-gnu'; rustupSha256='f69dafcca62fe70d7882113e21bb96a2cbdf4fc4636d25337d6de9191bdec8da' ;; \
        armhf) rustArch='armv7-unknown-linux-gnueabihf'; rustupSha256='eee969b9fd128e8dc9b4ec44acde46735cf8e612d06495e9d022517849aba2d6' ;; \
        arm64) rustArch='aarch64-unknown-linux-gnu'; rustupSha256='cdc48b7882582fd8475107a406dd86df85c7d72e5deea99ff8940c8e11531285' ;; \
        i386) rustArch='i686-unknown-linux-gnu'; rustupSha256='3bad3945452509ac28ba4113e198323daab57488d6885bb31ac30c9eecd88825' ;; \
        *) echo >&2 "unsupported architecture: ${dpkgArch}"; exit 1 ;; \
    esac; \
    url="https://static.rust-lang.org/rustup/archive/1.13.0/${rustArch}/rustup-init"; \
    wget "$url"; \
    echo "${rustupSha256} *rustup-init" | sha256sum -c -; \
    chmod +x rustup-init; \
    ./rustup-init -y --no-modify-path --default-toolchain $RUST_VERSION; \
    rm rustup-init; \
    chmod -R a+w $RUSTUP_HOME $CARGO_HOME; \
    rustup --version; \
    cargo --version; \
rustc --version;
```

## イメージをビルド

```
$ docker build -t rust-env .
...
...

Rust is installed now. Great!

To get started you need Cargo's bin directory (/usr/local/cargo/bin) in your
PATH environment variable.

To configure your current shell run source /usr/local/cargo/env
+ rm rustup-init
+ chmod -R a+w /usr/local/rustup /usr/local/cargo
+ rustup --version
rustup 1.13.0 (ea9259c1b 2018-07-16)
+ cargo --version
cargo 1.28.0 (96a2c7d16 2018-07-13)
+ rustc --version
rustc 1.28.0 (9634041f0 2018-07-30)
Removing intermediate container 048d99bf28a4
 ---> 9dd7ef4664f9
Successfully built 9dd7ef4664f9
Successfully tagged rust-env:latest
```

上手くいったようです。

## コンテナの中に入ってみる

```
$ docker run -it rust-env
root@e808e67f8d25:/#
```

rootで入れました。rust関係の諸々が入っていることを確認します。

```
root@e808e67f8d25:/# rustup --version
rustup 1.13.0 (ea9259c1b 2018-07-16)
root@e808e67f8d25:/# cargo --version
cargo 1.28.0 (96a2c7d16 2018-07-13)
root@e808e67f8d25:/# rustc --version
rustc 1.28.0 (9634041f0 2018-07-30)
```

## Hello World

Dockerfileの並びに`src`ディレクトリを作り、その中で[`main.rs`](https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/getting-started.html#hello-world)ファイルを作ります。RustはC、C++と同じシステムプログラミング言語に入るようです。main関数を書くところがそんな感じしますね。

```:main.rs
fn main() {
    println!("Hello, world!");
}
```

今この状態です。

```
$ tree
.
├── Dockerfile
└── src
    └── main.rs
```

`src`をマウントするようにコンテナを起動します。

```
$ docker run -itv /path/to/rust-projects/src:/project rust-env
root@eaac2d973657:/# ls
bin  boot  dev	etc  home  lib	lib64  media  mnt  opt	proc  project  root  run  sbin	srv  sys  tmp  usr  var
root@eaac2d973657:/# cd project/
root@eaac2d973657:/project# ls
main.rs
```

ちゃんとファイルありますね。では実行。

```
root@eaac2d973657:/project# rustc main.rs
root@eaac2d973657:/project# ls
main  main.rs
root@eaac2d973657:/project# ./main
Hello, world!
```

できました。mac側のvimでrustコード書いてDocker側でコンパイルして実行することができるようになりました。新しい言語やるときはローカルにインストールするのではなく、こういう風にDockerコンテナを介して始めるのが楽ですね。