DockerのUbuntuコンテナにScala開発環境を構築
この記事を書くに至った動機
エンジニアにはあるあるですが環境構築途中で失敗して、一度削除してまたいちから作成する時に調べ直さなくてもいいように手順を記録していきたいと思います。
(もうすでに1回やり直してます。。)
環境構築の手順
・ベースとなる Ubuntu コンテナの作成
・Redisサーバのインストール
・MySQLサーバのインストール
・JDK 8 のインストール
・Play Framework (Activator) のインストール
・新規プロジェクトの作成
・アプリケーションの起動
・ブラウザからアクセスして確認
・コンテナの保存
・ポートフォワード設定をして実行
・再度ブラウザからアクセスして確認
かなり長い道のりで、おそらくすんなりいかずに1日がかりの作業になると思いますが
頑張ってベースとなる開発環境構築の手順をお伝えできたらと思います。
Ubuntu コンテナの作成
まずは空の Ubuntu コンテナを作成します。
タグは「Trusty」を使います。
$ docker run -it --name develop ubuntu:trusty /bin/bash
すぐに exit してコンテナが正しく作成されたかを確認してみます。
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0309d0f2f1bd ubuntu:trusty "/bin/bash" 5 minutes ago Up 5 minutes develop
正常にコンテナが作成されていることを確認したら再度コンテナに入ります。
$ docker exec -it develop /bin/bash
Redisサーバのインストール
とりあえずホームディレクトリに移動したのち、「redis-server」をインストールしたいと思います。
$ cd ~ $ apt-get update $ apt-get install -y redis-server
少し待つとインストールが完了します。
早速Redisサーバを起動しておきしょう。
正しく起動したかどうかの確認も忘れずに。
$ service redis-server start Starting redis-server: redis-server. $ps -ef | grep redis redis 209 1 0 05:45 ? 00:00:00 /usr/bin/redis-server 127.0.0.1:6379 root 213 46 0 05:45 ? 00:00:00 grep --color=auto redis
MySQLサーバのインストール
次はMySQLのインストールです。
インストール時に root ユーザのパスワード入力を求められるので入力します。
$ apt-get install -y mysql-server
少し待つとインストールが完了します。
こちらも忘れずにMySQLサーバを起動しておきましょう。
$ service mysql start * Starting MySQL database server mysqld [ OK ] * Checking for tables which need an upgrade, are corrupt or were not closed cleanly. $ps -ef | grep redis root 754 1 0 05:48 ? 00:00:00 /bin/sh /usr/bin/mysqld_safe mysql 1101 754 0 05:48 ? 00:00:00 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib/mysql/plugin --user=mysql --log-error=/var/log/mysql/error.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306 root 1265 46 0 05:49 ? 00:00:00 grep --color=auto mysql
JDK 8 のインストール
次はJavaをインストールします。
Play Framework を利用するにはJDK8以上が必要なようです。
Ubuntu 14.04 では公式リポジトリに JDK8 が用意されていないとのこと。
サードパーティ製のリポジトリを追加してインストール必要があります。
そこで登場するのが「add-apt-repository」ですが、空のUbuntuにはこれすらもありません。
まずは使えるように設定をします。
$ apt-get install -y apt-file $ apt-file update $ apt-file search add-apt-repository
検索して見つかったリポジトリをインストールします。
$ apt-get install software-properties-common
ここまでやるとやっと「add-apt-repository」が使えるようになります。
アップデートを忘れずに実行し、続けて JDK8 をインストールします。
$ apt-add-repository ppa:openjdk-r/ppa $ apt-get update $ apt-get install -y openjdk-8-jdk
しばらく待つとインストールが完了するので、バージョンを確認してみます。
$ java -version openjdk version "1.8.0_72-internal" OpenJDK Runtime Environment (build 1.8.0_72-internal-b15) OpenJDK 64-Bit Server VM (build 25.72-b15, mixed mode) $javac -version javac 1.8.0_72-internal
Play Framework (Activator) のインストール
最後に Scala の Framework である、Play Framework をインストールします。
まずは下記のサイトで配布されている Activator という zip ファイルを wget で取得します。
2016年2月25日時点での最新版は Play 2.4.6 / Activator 1.3.7 のようです。
https://www.playframework.com/download
wget が使えない場合は、wget を先にインストールします。
$ apt-get install -y wget
適当なフォルダ(今回はActivator)を作成し、先ほどの zip ファイルをダウンロードします。
$ mkdir Activator $ cd Activator $ wget https://downloads.typesafe.com/typesafe-activator/1.3.7/typesafe-activator-1.3.7-minimal.zip
ダウンロードが完了したら zip ファイルを解凍します。
解凍するには unzip コマンドを使いますが、例に漏れずこれもインストールが必要です。
$ apt-get install -y unzip
unzip のインストールができたら早速ダウンロードした zip ファイルを解凍します。
$ unzip typesafe-activator-1.3.7-minimal.zip
一瞬で解凍が終わりますが、解凍した後はフォルダが1つ作成されていると思います。
$ ls -al drwxr-xr-x 3 root root 4096 Feb 25 06:18 ./ drwx------ 3 root root 4096 Feb 25 06:13 ../ drwxr-xr-x 2 root root 4096 Dec 2 20:27 activator-1.3.7-minimal/ -rw-r--r-- 1 root root 1056830 Dec 3 01:28 typesafe-activator-1.3.7-minimal.zip
中に入って内容を確認してみます。
$ cd activator-1.3.7-minimal $ ls -al drwxr-xr-x 2 root root 4096 Dec 2 20:27 . drwxr-xr-x 3 root root 4096 Feb 25 06:18 .. -rwxr--r-- 1 root root 9507 Dec 2 20:27 activator -rw-r--r-- 1 root root 1213545 Dec 2 20:27 activator-launch-1.3.7.jar -rwxr--r-- 1 root root 7342 Dec 2 20:27 activator.bat
この activator というファイルは今後よく使うことになるためパスを通しておきます。
$ pwd /root/Activator/activator-1.3.7-minimal $ env | grep PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin $ export PATH=$PATH:/root/Activator/activator-1.3.7-minimal $ env | grep PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/Activator/activator-1.3.7-minimal
こんな感じになったかと思います。
これでいつでもどこでも activator コマンドが利用できます。
新規プロジェクトの作成
新しくプロジェクトを作成するのはコマンドひとつで行えます。
まずはプロジェクト用のフォルダを作成して、その中で「activator new」コマンドを実行します。
※初回実行時のみいろいろインストールされるので非常に時間がかかります。コーヒーでも飲みながら気長に待ちましょう。
$ mkdir sampleapp $ cd sampleapp $ activator new <appname(省略可)> <apptype(省略可)> # ひとまずは「activator new」のみで実行してみてください
事前ダウンロードなどが終わると以下のような画面が出てくると思います。
Browse the list of templates: http://typesafe.com/activator/templates Choose from these featured templates or enter a template name: 1) minimal-akka-java-seed 2) minimal-akka-scala-seed 3) minimal-java 4) minimal-scala 5) play-java 6) play-scala (hit tab to see a list of all templates)
今回は Scala を利用するので「play-scala」と入力してリターンキーを押します。
するとさらに今度はアプリケーションの名前の入力を求められます。
好きな名前を入力しましょう。未入力時は「play-scala」が設定されるようです。
> play-scala Enter a name for your application (just press enter for 'play-scala') > sampleapp OK, application "sampleapp" is being created using the "play-scala" template. To run "sampleapp" from the command line, "cd sampleapp" then: /root/Activator/sampleapp/sampleapp/activator run To run the test for "sampleapp" from the command line, "cd sampleapp" then: /root/Activator/sampleapp/sampleapp/activator test To run the Activator UI for "sampleapp" from the command line, "cd sampleapp" then: /root/Activator/sampleapp/sampleapp/activator ui
こんなメッセージが表示されたらプロジェクトファイル群がすでに作成されています。
アプリケーション名で新たにフォルダが作成されているので、構成を見てみましょう。
$ cd sampleapp $ ls -al -rw-r--r-- 1 root root 591 Feb 25 06:34 LICENSE -rw-r--r-- 1 root root 148 Feb 25 06:34 README -rwxr--r-- 1 root root 9507 Feb 25 06:34 activator -rw-r--r-- 1 root root 1213545 Feb 25 06:34 activator-launch-1.3.7.jar -rwxr--r-- 1 root root 7342 Feb 25 06:34 activator.bat drwxr-xr-x 4 root root 4096 Feb 25 06:34 app -rw-r--r-- 1 root root 472 Feb 25 06:34 build.sbt drwxr-xr-x 2 root root 4096 Feb 25 06:34 conf drwxr-xr-x 2 root root 4096 Feb 25 06:34 project drwxr-xr-x 5 root root 4096 Feb 25 06:34 public drwxr-xr-x 2 root root 4096 Feb 25 06:34 test
これがデフォルト状態(空状態)のプロジェクトファイル構成になります。
ここら辺については Play Framework のチュートリアルやドキュメントで詳しく書かれていますのでそちらを参照してみてください。
アプリケーションの起動
作成した空のアプリケーションを実行してみたいと思います。
実行時にも「activator run」コマンドを利用します。
アプリケーション作成時同様、初回のみいろいろダウンロードしたりチェックが行われたりして非常に時間がかかりますので大人しく待ちましょう。
$ activator run ・ ・ ・ --- (Running the application, auto-reloading is enabled) --- [info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000 (Server started, use Ctrl+D to stop and go back to the console...)
こんな表示が出たら見事アプリケーションの起動に成功です!!
おめでとうございます!!
ブラウザからアクセスして確認
アプリケーションが起動したら、実際に見てみたいですよね?
というわけで、早速ブラウザからアクセスしてページを表示してみましょう!
VM環境のIPアドレスとポート番号9000を入力してリターン!
残念つながりませんでした・・・。
でもこれ、当然繋がらなくて当たり前ですよね。
最初にコンテナを起動するときにポートフォワード設定をせずに起動していますから。
コンテナの9000番ポートに対してアクセスするには一度コンテナから抜けて、コンテナ起動時に9000番ポートに対してポートフォワード設定を指定する必要があります。
が、ここで問題が・・・。
ポートフォワード指定は「docker run」コマンド実行時しかできないため、一度コンテナを削除する必要があります。
ここまで数時間かけて作ってきたコンテナを破棄するなんて…。
ということでコンテナを削除する前にここまで設定したコンテナを保存したいと思います。
コンテナの保存
一度コンテナから抜けるために exit して、以下のコマンドを実行します。
$ docker commit -m "ここにコメントが書けます" <Image Id> <Image Name> $ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE develop latest 8c7f1c246564 26 seconds ago 1.192 GB
無事にイメージとして保存することができました。
ポートフォワード設定をして実行
develop コンテナを本当に削除して作り直してもいいんですが、ビビリな僕は残したまま別コンテナとして立ち上げることにします。
コンテナ名を「develop9000」、イメージはさっき自分で作成した「develop」イメージを利用します。
$ docker run -it -p 9000:9000 --name develop9000 develop /bin/bash $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9ca7253918d2 develop:latest "/bin/bash" About a minute ago Exited (0) 3 seconds ago develop9000 0309d0f2f1bd ubuntu:trusty "/bin/bash" 4 hours ago Exited (0) 2 hours ago develop
無事に起動されました。
それでは、前の手順に合わせて sampleapp を実行してブラウザで確認してみたいと思います。
まずは作成したコンテナへ入ります。
$ docker start develop9000 $ docker exec -it develop9000 /bin/bash
プロジェクトがあるフォルダへ移動して「activator run」コマンドを実行します。
コンテナを一度抜けるとパス設定が元に戻っていたようなので再度設定しておきます。
$ export PATH=$PATH:/root/Activator/activator-1.3.7-minimal $ cd /root/Activator/sampleapp/sampleapp $ activator run [info] Loading project definition from /root/Activator/sampleapp/sampleapp/project [info] Set current project to sampleapp (in build file:/root/Activator/sampleapp/sampleapp/) --- (Running the application, auto-reloading is enabled) --- [info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000 (Server started, use Ctrl+D to stop and go back to the console...)
今回は2回目の実行なので初回に比べたらはるかに早く起動しました。