Scala on docker (ubuntu)
動機
scala
の動く環境が欲しかった。
localにdmg
ファイルとかをダウンロードしてもよかったのだが、
localの環境を汚すのが好ましくないと思ったので、docker
で作ろうと思った。
「人類、dockerという技術がありながら、なぜlocalの環境を汚してしまうのか」というツイートをどこかで見たような...
状況として、「新しい言語が動く環境をdocker
を用いて作る」というケースとして、応用できるのではないかと思ったので、エントリとして書いておく。
ubuntu containers 作る
$ docker run -it --name {container_name} -v /abs/path/to/mount/directory:/root/ ubuntu:latest /bin/bash
docker run の option に関して
option | 意味 |
---|---|
-i | intaractive (attach しなくても標準入力を受け付ける状態に保つ) |
-t | tty (超雑に言うとterminal ) を割り当てる |
-v | ホストPCのディレクトリを、container 内のディレクトリにマウントする。 |
option に関する追記:
-
-it
は-i
と-t
の合わせ技。 -
-v
オプションでは、[host_dir]:[container_dir]
で指定する。
注意: どちらも絶対パスで指定する必要がある。
今回、dockerでは~/
が/root/
になるので、そこにマウントをしている。
以下、コンテナ内での履歴
apt update など
# apt update; apt upgrade -y;
scala をインストールするだけ
# apt install scala
とりあえず REPL を起動
# scala
scala>
動作確認 (ちょっと遊んでみる)
val (value): 定数
scala> val x = 10
x: Int = 10
scala> print(x)
10
val (value) はイミュータブル (再代入/変更不可能)
scala> val x = 10
x: Int = 10
scala> x = 20
<console>:12: error: reassignment to val
x = 20
^
ただし、新しい定数として定義し直すことは可能
コンパイル時はエラーになるらしい。
scala> val x = 10
x: Int = 10
scala> val x = 20
x: Int = 20
scala> print(x)
20
var (variable): 変数
scala> var a = 10
a: Int = 10
scala> print(a)
10
var (variable) はミュータブル (再代入/変更可能)
scala> var a = 10
a: Int = 10
scala> a = 20
a: Int = 20
scala> print(a)
20
もちろん、定義し直しも OK
scala> var a = 10
a: Int = 10
scala> var a = 20
a: Int = 20
scala> print(a)
20
ただし、変数の型を変えての再代入は不可
scala> var a = 10
a: Int = 10
scala> print(a)
10
scala> a = "hoge"
<console>:12: error: type mismatch;
found : String("hoge")
required: Int
a = "hoge"
^
// 例2
scala> var s = "this is string"
s: String = this is string
scala> print(s)
this is string
scala> s = 0.1
<console>:12: error: type mismatch;
found : Double(0.1)
required: String
s = 0.1
^
最後に動作確認のお決まり
scala> print("Hello World")
Hello World
scala> print("Hello World", "!")
(Hello World,!)
終了
scala> :quit // もしくは [Ctrl-c] でも抜けられる。
Play FrameWork
Scala
には Play Framework
という web アプリケーション用のフレームワークがある。
(Scala に限らず、Java や Python, Go, Rust などを使って web アプリケーションを作りたい利用ケースはあるだろう)
Scala 環境を Docker container 内で立てて、container でアプリケーションを実行したら、サービスは container で動いており、「container のポートで」サービスの待ち受けがされている。
コンテナと ip address
を用いた通信ができる ( network に docker とのブリッジを持っている ) 場合は問題ないのだが、私の Mac 環境では Host と Docker container の間で (なぜか) ip address でやりとりできない ... 超不便である。
こういったときは下記の様に、ホストの空いているポートと、Docker container (アプリケーション側) の待ち受けポートをマッピングすれば良い。
$ docker run -it -p 8081:9000 --rm hseeberger/scala-sbt:scala-2.12.2-sbt-0.13.15 bash
-p [Host のポート番号]:[container の待ち受けポート番号]
すると、Host の 8081 番ポートにアクセス ( http://localhost:8081 ) することで、
Docker の 9000 番ポートにアクセスしたことになり、サービスを受けることができる。
ここで hseeberger/scala-sbt
は hseeberger さんが公開してくださっている Docker image である。 scala と sbt の両方が使える状態になっており、便利である。
Docker Hub: hseeberger/scala-sbt
もしすでに Host にソースファイルがあったり、Host とソースファイルを同期したい場合は
container のどこか適切なディレクトリを、ホストとマッピングすれば良い。
$ docker run -it -p 8081:9000 -v $PWD/src:/root/src --rm hseeberger/scala-sbt:scala-2.12.2-sbt-0.13.15 bash
sbt を使って Play Framework の雛形を得るには次の様にすれば良い。
sbt new playframework/play-scala-seed.g8
他の言語に関しても、 {言語} docker
で検索したりすると、公開 image などが出てくるので、同様の方法により web サービスを container 環境で実行、利用できるだろう。