LoginSignup
11
8

More than 5 years have passed since last update.

Docker Composeを使ってClojure開発環境を作る

Last updated at Posted at 2015-05-16

前回Docker ComposeでSailsの開発環境を用意しました。Clojureの勉強用環境もDocker Composeで作ってみます。開発用のJavaはDockerコンテナを使いながら、ホストマシンのEmacsを使ってコードを編集できるようにします。

プロジェクト

プロジェクトのディレクトリを作成します。Dockerfile、docker-compose.yml、m2ディレクトリを作成します。

$ cd ~/clojure_apps
$ tree .
.
├── Dockerfile
├── docker-compose.yml
└── m2

DockerとDocker Composeのバージョンを確認しておきます。

$ docker version
...
Server version: 1.6.0
$ docker-compose --version
docker-compose 1.2.0

Dockerfile

ベースイメージはオフィシャルのclojureを使います。Dockerホストの作業ユーザーと同じuidでユーザーを作成して、ボリューム内に作成されたファイルを編集できるようにします。

~/clojure_apps/Dockerfile
FROM clojure
MAINTAINER Masato Shimizu <ma6ato@gmail.com>

WORKDIR /usr/src/app

RUN apt-get update && apt-get install sudo net-tools && \
  rm -rf /var/lib/apt/lists/*

RUN adduser --disabled-password --gecos '' --uid 1000 docker && \
  adduser docker sudo && \
  echo 'docker ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
  mkdir /home/docker/.m2 && \
  chown -R docker:docker /usr/src/app /home/docker/.m2

VOLUME /home/docker/.m2
USER docker
RUN lein

ENTRYPOINT ["lein"]

Dockerイメージは開発中も変更がないのでローカルにビルドしておきます。

$ cd ~/clojure_apps
$ docker build -t clojure .

REPL

Clojure REPLを実行するための基本的なdocker-compose.ymlを用意します。WORKDIR/usr/src/appをカレントディレクトリにマップします。

~/clojure_apps/docker-compose.yml
lein: &defaults
  image: clojure
  volumes:
    - .:/usr/src/app
    - ./m2:/home/docker/.m2

Docker Composeのleinサービスをワンショットで実行します。初回実行時に/home/docker/.m2にMavenよりjarファイルがダウンロードされます。.m2ディレクトリはDockerホストにマップしているので2回目以降からはダウンロード済みのjarファイルを使います。

$ cd ~/clojure_apps
$ docker-compose run --rm lein repl
...
nREPL server started on port 54118 on host 127.0.0.1 - nrepl://127.0.0.1:54118
REPL-y 0.3.5, nREPL 0.2.6
Clojure 1.6.0
OpenJDK 64-Bit Server VM 1.7.0_79-b14
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=>

Compojure

WebフレームワークのCompojureを使ったプロジェクトを作成してみます。

$ cd ~/clojure_apps
$ docker-compose run --rm lein new compojure hello-world
Retrieving compojure/lein-template/0.4.2/lein-template-0.4.2.pom from clojars
Retrieving compojure/lein-template/0.4.2/lein-template-0.4.2.jar from clojars
Removing clojureapps_lein_run_1...

カレントディレクトリにCompojureのプロジェクトが作成されました。

$ tree hello-world/
hello-world/
├── README.md
├── project.clj
├── resources
│   └── public
├── src
│   └── hello_world
│       └── handler.clj
└── test
    └── hello_world
        └── handler_test.clj

Docker ComposeからCompojureを起動するためにdocker-compose.ymlを編集します。working_dirにComposeプロジェクトのディレクトリを指定します。

~/clojure_apps/docker-compose.yml
lein: &defaults
  image: clojure
  volumes:
    - .:/usr/src/app
    - ./m2:/home/docker/.m2
  working_dir: /usr/src/app/hello-world
  ports:
    - "3000:3000"

Ringサーバーを起動します。lein ring serverで起動するとNo X11 DISPLAY variable was setとエラーがでてしまいます。ヘッドレスなDockerなのでlein ring server-headlessで起動します。また--service-portsフラグを指定してDockerホストにポートをマップします。

$ docker-compose run --rm --service-ports lein ring server-headless
...
2015-05-16 09:42:00.573:INFO:oejs.Server:jetty-7.6.8.v20121106
2015-05-16 09:42:00.608:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:3000
Started server on port 3000

初回起動時にはjarファイルをダウンロードするためすこし時間がかかります。Dockerホストで別のシェルを起動してサーバーの起動を確認します。

$ curl -s localhost:3000
Hello World

Clojure Script REPL

CompojureプロジェクトでClojure Script REPLを使ってみます。project.clj:plugin:cljsbuildディレクティブを追加します。Clojureは1.6を使っているのでClojure Scriptは1.6系の0.0-3126を指定します。

~/clojure_apps/hello-world/project.clj
(defproject hello-world "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :min-lein-version "2.0.0"
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [compojure "1.3.1"]
                 [ring/ring-defaults "0.1.2"]
                 [org.clojure/clojurescript "0.0-3126"]]
  :plugins [[lein-ring "0.8.13"]
            [lein-cljsbuild "1.0.6"]]
  :ring {:handler hello-world.handler/app}
  :profiles
  {:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
                        [ring-mock "0.1.5"]]}}
  :cljsbuild {
              :builds [{
                        :source-paths ["src-cljs"]
                        :compiler {
                                   :output-to "resources/public/main.js"
                                   :optimizations :whitespace
                                   :pretty-print true}}]}))

docker-compose.ymlはClojure Script用のサービスをcljsleinとしてleinサービスをマージして用意します。

~/clojure_apps/docker-compose.yml
lein: &defaults
  image: clojure
  volumes:
    - .:/usr/src/app
    - ./m2:/home/docker/.m2
  working_dir: /usr/src/app/hello-world
  ports:
    - "3000:3000"
cljslein:
  <<: *defaults
  ports:
    - "9000:9000"

Docker Composeからcljsleinサービスを実行します。

$ docker-compose run --rm --service-ports cljslein trampoline cljsbuild repl-rhino
Running Rhino-based ClojureScript REPL.
...
Retrieving org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar from central
Retrieving org/clojure/tools.reader/0.8.16/tools.reader-0.8.16.jar from central
To quit, type: :cljs/quit
ClojureScript:cljs.user>

Clojure Script REPLからJavaScriptのDate関数を呼んでみます。

ClojureScript:cljs.user> (js/Date)
#inst "2015-05-16T10:17:55.200-00:00"
11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8