ゴール
node ファイル名
とかnpm init
とかnpm install jquery --save
とかが実行できる。
今回作った環境は一応ここに上げておきました。こうしたほうがいいなどあればコメント残していただけると幸せです。
きっかけ
node.jsを勉強したいと思って環境作ろうとした時、nodeのバージョン管理ツール入れるべきと助言をもらい、勉強始めるまでの敷居の高さ(本質じゃないところに時間をとられる)を感じた。
rbenvを使ってたこともあり、新しい言語を勉強し始めるタイミングで、また別の管理ツールを入れるのは違うなと思い始めた。
dockerならば、imageのバージョンを書き換えるだけで、バージョンの切り替えが可能なので、docker+docker-composeによる開発環境を作れないかなと考えた。
今回作る環境
Windowsにvagrantを使ってVM(ubuntu/trusty64)を立ててその中にdockerとdocker-composeを導入してnode.jsの環境を作る。
おそらくWindows以外の環境でも同じような形で作れると思います。
バージョンは以下です。
- Vagrant
- 1.7.4
- VirtualBox
- 5.0.2
- Docker
- version 1.9.1, build a34a1d5
- docker-compose
- version 1.5.2, build 7240ff3
- node.js
- v4.2.3
- npm
- 2.14.7
ステップ1 VMを用意する
vagrantのインストール手順等は調べたらいっぱい出るので省きます。
boxも公式のものを使用します。
今回はubuntu/trusty64を使用するので下記コマンドでひな形を生成します。
$ vagrant init ubuntu/trusty64
雛形ができたらネットワークの設定とメモリの設定をしておきます。
メモリの設定をするのは初期で割り当てられてるメモリが512MBと少ないのでdocker build中に突然死したことがあるためです。
- # config.vm.network "private_network", ip: "192.168.33.10"
+ config.vm.network "private_network", ip: "192.168.33.10"
- # config.vm.provider "virtualbox" do |vb|
+ config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
#
# # Customize the amount of memory on the VM:
- # vb.memory = "1024"
- # end
+ vb.memory = "1024"
+ end
# documentation for more information about their specific syntax and use.
- # config.vm.provision "shell", inline: <<-SHELL
- # sudo apt-get update
- # sudo apt-get install -y apache2
- # SHELL
+ config.vm.provision "shell", inline: <<-SHELL
+ wget -qO- https://get.docker.com/ | sh
+ apt-get -y install python-pip
+ pip install docker-compose
+ SHELL
end
Vagrantfileの準備ができたらVMを起動します。
$ vagrant up
.vagrantが生成されるので.gitignoreでgit管理から外しておきます。
.vagrant/
ステップ2 docker-composeを使ってコンテナを作る
docker-composeを使うと構成管理がyamlに記載できるます。
複数コンテナのlinksとかvolumesとかdockerコマンドを叩くときに指定してたオプション等を記載できるので便利です。
node.jsには公式のイメージを使います。
※vagrantの共有ディレクトリ内にnode_modulesを直接置くとnpm ERR! ETXTBSY: text file is busy, renameなどと言って来たのでコンテナに押しこむことにしました。(--no-bin-linksもつけてもダメだったのでこうした方がいいという案があれば教えて下さい。)
というわけで、datastoreを用意しておきます。
FROM busybox:latest
VOLUME /usr/src/app/node_modules
CMD /bin/sh
node:
image: node:4.2.3
volumes:
- .:/usr/src/app
working_dir: /usr/src/app
volumes_from:
- datastore
datastore:
build: containers/datastore
buildします。
$ docker-compose build
コンテナを起動します。-dオプションはバックグラウンド起動です。
buildする必要のなかったnodeのイメージを初回にプルされるのでちょっと時間かかります(imageで指定したnode:4.2.3はすでにbuildされてるため)。
$ docker-compose up -d
コンテナの状態を確認します。
$ docker-compose ps
Name Command State Ports
---------------------------------------------------------
vagrant_datastore_1 /bin/sh -c /bin/sh Exit 0
vagrant_node_1 node Exit 0
node, datastoreともに終了してるはずです。フォアグランドでうごくコンテナを使う場合はCMDをdocker-compose.ymlに記述するといいです。
ステップ3 動かしてみる
サンプルを動かす
コンソールログを吐くだけですが、、、
console.log('hello world');
実行
$ docker-compose run node node hello.js
# hello world
npm initする
$ docker-compose run node npm init
npm install パッケージする
jquery入れたくなった気がするので導入します。
$ docker-compose run node npm install jquery --save
ローカルにあるpackage.jsonに追記されました。
"description": "",
"main": "main.js",
- "dependencies": {},
+ "dependencies": {
+ "jquery": "^2.1.4"
+ },
"devDependencies": {},
(書きたい人は)エイリアス書く
頭にdocker-compose run nodeをつければ基本的に大体のことができるようになりました。
これが長い嫌だって人は適当にbashrcとかにコマンドエイリアス書けばいいんじゃないですかね。開発ディレクトリ以外では実行できないですが。。。
# 最終行とかに
# --rm 実行後にコンテナ破棄
# --service-ports docker-compse.ymlに書いたポート設定使ってくれる
# (up時には必要ないがrunの時にportsの設定が消失したので入れてる←なぞ)
alias node='docker-compose run --rm --service-ports node node'
alias npm='docker-compose run --rm --service-ports node npm'
まとめ
ゴールに設定したところまでは行けた。これからnode.jsは勉強していくつもりなので問題が出てくることもあると思うが開発環境の作り方の一つの方法としてあり何じゃないかと思ってます。
あと、同じ要領で別言語の環境構築もできると思う。