DockerとAnsibleを使ってRails4の開発環境を作ってみました。

Environment

Docker

Dockerfileにはsshdでログインできる程度の下地を作るところまでを書いています。

Dockerfile:

 1FROM ubuntu
 2
 3ADD sources.list /etc/apt/
 4RUN apt-get update
 5RUN apt-get install -y vim
 6RUN apt-get install -y openssh-server
 7RUN apt-get install -y sudo
 8RUN echo "masayuki    ALL=(ALL)       NOPASSWD:ALL" >> /etc/sudoers
 9RUN mkdir /var/run/sshd
10RUN /usr/sbin/sshd
11RUN echo " IdentityFile ~/.ssh/id_rsa" >> /etc/ssh/ssh_config
12RUN groupadd dev
13RUN useradd -g dev -m -s /bin/bash masayuki
14ADD .ssh /home/masayuki/.ssh

1$ sudo docker build .
2$ sudo docker ps -a
3(Check your CONTAINER ID)
4$ sudo docker commit 87ba0c2400d4 base/sshd
1$ sudo docker run -d -p 127.0.0.1:8024:22 base/sshd /usr/sbin/sshd -D
2aa1f9a2f8b12258ef825566fb8c904053f4fa060dc816cff7bceae8f3eca604f

Ansible

Basis

まず、作成したDockerコンテナに対してプロビジョニングする為の準備を行います。

/etc/hosts:

1127.0.0.1       rails4-dev

rails4-dev_hosts:

1[rails4-dev]
2rails4-dev ansible_ssh_port=8024

1- hosts: rails4-dev
2  sudo: yes
3  roles:
4    - common
5    - rails4-dev

aptモジュールが使えるように、roles/common/tasks/main.ymlでpython-aptをインストールします。

roles/common/tasks/main.yml:

1- name: be sure python-apt is installed
2  shell: apt-get install python-apt -y
3  tags: ansible

Files

アップロードするファイルは以下の5点です。

for github

fils/ssh_configはsshの設定です。

roles/rails4-dev/files/ssh_config:

 1Host github.com
 2 StrictHostKeyChecking no
 3 User git
 4 HostName       github.com
 5 IdentityFile   ~/.ssh_github/github_id_rsa
 6 StrictHostKeyChecking no
 7
 8Host bitbucket.org
 9 StrictHostKeyChecking no
10 User git
11 Hostname bitbucket.org
12 PreferredAuthentications publickey
13 IdentityFile ~/.ssh/github_id_rsa

sshの鍵もアップしておきます。

1masayuki@www2267uo:~/work/sites/wrap-trap.net/ansible$ tar tvfz roles/rails4-dev/files/ssh_github.tar.gz
2drwxrwxr-x masayuki/masayuki 0 2013-12-03 21:49 .ssh_github/
3-rw-rw-r-- masayuki/masayuki 606 2012-04-04 23:33 .ssh_github/github_id_rsa

for .el files

.emacs.d/initsの下に置く.elファイルです。まずはruby-modeの.elファイル。

roles/rails4-dev/files/emacs/inits/80-ruby.el:

 1;; ruby-mode
 2
 3(add-to-list 'load-path "~/.emacs.d/ruby-mode")
 4(autoload 'ruby-mode "ruby-mode" "Mode for editing ruby source files" t)
 5(setq auto-mode-alist (cons '("\\.rb$" . ruby-mode) auto-mode-alist))
 6(setq interpreter-mode-alist (append '(("ruby" . ruby-mode)) interpreter-mode-alist))
 7(autoload 'run-ruby "inf-ruby" "Run an inferior Ruby process")
 8(autoload 'inf-ruby-keys "inf-ruby" "Set local key defs for inf-ruby in ruby-mode")
 9(add-hook 'ruby-mode-hook '(lambda () (inf-ruby-keys)))
10
11;; ruby-electric.el --- electric editing commands for ruby files
12(require 'ruby-electric)
13(add-hook 'ruby-mode-hook '(lambda () (ruby-electric-mode t)))
14
15;; set ruby-mode indent
16(setq ruby-indent-level 2)
17(setq ruby-indent-tabs-mode nil)

今回はrinariを使ってみることにしました。

roles/rails4-dev/files/emacs/inits/90-rinari.el:

1;; Interactively Do Things (highly recommended, but not strictly required)
2(require 'ido)
3(ido-mode t)
4;; Rinari
5(add-to-list 'load-path "~/.emacs.d/rinari")
6(require 'rinari)

そしてrhtmlの.elファイル。

roles/rails4-dev/files/emacs/inits/90-rhtml.el:

1;;; rhtml-mode
2(add-to-list 'load-path "~/.emacs.d/rhtml")
3(require 'rhtml-mode)
4(add-hook 'rhtml-mode-hook
5    (lambda () (rinari-launch)))

Tasks

タスクファイルは以下のようになっています。

roles/rails4-dev/tasks/main.yml:

1- include: github.yml
2- include: rails4.yml
3- include: emacs.yml

tasks/github.ymlは、githubへアクセスする為の設定です。

roles/rails4-dev/tasks/github.yml:

 1- name: be sure .ssh/config installed
 2  copy: src=roles/octopress/files/ssh_config dest=/home/masayuki/.ssh/config
 3
 4- name: be sure .ssh_github installed
 5  copy: src=roles/octopress/files/ssh_github.tar.gz dest=/home/masayuki/
 6
 7- name: unarchive .ssh_config
 8  shell: tar xvfz /home/masayuki/ssh_github.tar.gz -C /home/masayuki creates=/home/masayuki/.ssh_github
 9
10- name: chmod 400 .ssh_github/github_id_rsa
11  shell: chmod 400 /home/masayuki/.ssh_github/github_id_rsa
12
13- name: be sure git is installed
14  apt: pkg=git state=installed

tasks/rails.ymlは、ruby2.1とrails4をインストールします。

roles/rails4-dev/tasks/rail.yml:

 1- name: be sure ja_JP.UTF-8 enabled
 2  shell: locale-gen ja_JP.UTF-8
 3
 4- name: be sure locale updated
 5  shell: update-locale LANG=ja_JP.UTF-8
 6
 7- name: be sure python-sofrware-properties is installed
 8  apt: pkg=python-software-properties state=installed
 9
10- name: add repository for ruby2.1
11  apt_repository: repo='ppa:brightbox/ruby-ng'
12
13- name: be sure ruby-2.1 is installed
14  apt: update_cache=yes pkg=ruby2.1 state=installed
15
16- name: be sure ruby-2.1-dev is installed
17  apt: pkg=ruby2.1-dev state=installed
18
19- name: be sure gcc is installed
20  apt: pkg=gcc state=installed
21
22- name: be sure make is installed
23  apt: pkg=make state=installed
24
25- name: be sure bundler is installed
26  gem: name=bundler user_install=no state=present
27
28- name: be sure tmp dir is created
29  shell: mkdir rails
30
31- name: be sure 'bundle init' is executed
32  shell: bundle init chdir="rails"
33
34- name: be sure gem repos is added in Gemfile
35  shell: echo 'source "https://rubygems.org"' > Gemfile chdir="rails"
36
37- name: be sure gem "rails" is added in Gemfile
38  shell: echo 'gem "rails", ">= 4.0.0"' >> Gemfile chdir="rails"
39
40- name: be sure rails4 is installed
41  shell: bundle install --path=vendor/bundle chdir="rails"

tasks/emacs.ymlはEmacsやRuby/Railsまわりの.elファイルをインストールします。

roles/rails4-dev/tasks/emacs.yml:

 1- name: be sure python-software-properties is installed
 2  apt: pkg=python-software-properties state=installed
 3  tags: emacs
 4
 5- name: add repository for emacs24
 6  apt_repository: repo='ppa:cassou/emacs'
 7  tags: emacs
 8
 9- name: be sure emacs installed
10  apt: update-cache=true pkg=$item state=installed
11  with_items:
12    - emacs24
13    - emacs24-el
14  tags: emacs
15
16- name: be sure tmp dir is removed if exists
17  shell: rm -rf /home/{{user}}/tmp removes="/home/{{user}}/tmp"
18  tags: emacs
19
20- name: be sure dot.file cloned
21  git: repo=https://github.com/{{user}}038/dotfiles.git dest=/home/{{user}}/tmp
22  tags: emacs
23
24- name: be sure moved from /home/{{user}}/tmp/.emacs.d to /home/{{user}}/.emacs.d
25  shell: mv /home/{{user}}/tmp/.emacs.d /home/{{user}}/ creates=/home/{{user}}/.emacs.d
26  tags: emacs
27
28- name: be sure /home/{{user}}/tmp removed
29  shell: rm -rf /home/{{user}}/tmp
30  tags: emacs
31
32- name: be sure init-loader is cloned
33  git: repo=https://github.com/emacs-jp/init-loader.git dest=/home/{{user}}/tmp
34  tags: emacs
35
36- name: be sure moved from /home/{{user}}/tmp/init-loader.el to /home/{{user}}/.emacs.d/init
37  shell: mv /home/{{user}}/tmp/init-loader.el /usr/share/emacs24/site-lisp/ creates=/usr/share/emacs24/site-lisp/init-loader.el
38  tags: emacs
39
40- name: be sure /home/{{user}}/tmp removed
41  shell: rm -rf /home/{{user}}/tmp
42  tags: emacs
43
44- name: be sure 80-ruby.el copied
45  copy: src=roles/rails4-dev/files/emacs/inits/80-ruby.el dest=/home/{{user}}/.emacs.d/inits
46  tags: emacs
47
48- name: be sure 90-rinari.el copied
49  copy: src=roles/rails4-dev/files/emacs/inits/90-rinari.el dest=/home/{{user}}/.emacs.d/inits
50  tags: emacs
51
52- name: be sure 90-rhtml.el copied
53  copy: src=roles/rails4-dev/files/emacs/inits/90-rhtml.el dest=/home/{{user}}/.emacs.d/inits
54  tags: emacs
55
56- name: be sure ruby-2.1.0 source code is downloaded
57  get_url: url='{{ruby_url}}' dest=/usr/local/src
58  tags: emacs
59
60- name: be sure ruby-2.1.0
61  shell: tar xvfz /usr/local/src/ruby-{{ruby_version}}.tar.gz -C /usr/local/src creates=/usr/local/arc/ruby-{{ruby_version}}
62  tags: emacs
63
64- name: be sure ruby-mode.el is copied
65  shell: find /usr/local/src/ruby-{{ruby_version}} -name '*.el' -exec cp {} /usr/share/emacs/site-lisp \;
66  tags: emacs
67
68- name: be sure rinari is cloned
69  git: repo=https://github.com/eschulte/rinari.git dest=/home/{{user}}/.emacs.d/rinari
70  tags: emacs
71
72- name: be sure 'git submodule init' is executed
73  shell: git submodule init chdir=/home/{{user}}/.emacs.d/rinari
74  tags: emacs
75
76- name: be sure 'git submodule update' is executed
77  shell: git submodule update chdir=/home/{{user}}/.emacs.d/rinari
78  tags: emacs
79
80- name: be sure rhtml is cloned
81  git: repo=https://github.com/eschulte/rhtml.git dest=/home/{{user}}/.emacs.d/rhtml
82  tags: emacs
83
84- name: be sure an owner of /home/masayuki/.emacs.d is user.group
85  shell: chown -R {{user}}:{{group}} /home/{{user}}/.emacs.d
86  tags: emacs

emacsだけtagsが付いているのは、一番最後に調整した為です。

Vars

roles/rails4-dev/vars/main.yml:

1ruby_version: '2.1.0'
2ruby_url: 'http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.0.tar.gz'
3user: masayuki
4group: dev

Execution

1$ ansible-playbook -i rails4-dev_hosts rails4-dev.yml

Conclusion

DockerとAnsibleを使ってRails4の環境を作ってみました。これでまた環境を間違って壊しても大丈夫。

Update