act-act about projects rss

Development Environment For Rails4 With Docker And Ansible

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

Environment

  • ruby2.1.0
  • rails4
  • emacs24
    • ruby-mode
    • rinari
    • rhtml

Docker

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

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM ubuntu

ADD sources.list /etc/apt/
RUN apt-get update
RUN apt-get install -y vim
RUN apt-get install -y openssh-server
RUN apt-get install -y sudo
RUN echo "masayuki    ALL=(ALL)       NOPASSWD:ALL" >> /etc/sudoers
RUN mkdir /var/run/sshd
RUN /usr/sbin/sshd
RUN echo " IdentityFile ~/.ssh/id_rsa" >> /etc/ssh/ssh_config
RUN groupadd dev
RUN useradd -g dev -m -s /bin/bash masayuki
ADD .ssh /home/masayuki/.ssh
1
2
3
4
$ sudo docker build .
$ sudo docker ps -a
(Check your CONTAINER ID)
$ sudo docker commit 87ba0c2400d4 base/sshd
1
2
$ sudo docker run -d -p 127.0.0.1:8024:22 base/sshd /usr/sbin/sshd -D
aa1f9a2f8b12258ef825566fb8c904053f4fa060dc816cff7bceae8f3eca604f

Ansible

Basis

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

/etc/hosts

1
127.0.0.1       rails4-dev

rails4-dev_hosts

1
2
[rails4-dev]
rails4-dev ansible_ssh_port=8024
1
2
3
4
5
- hosts: rails4-dev
  sudo: yes
  roles:
    - common
    - rails4-dev

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

roles/common/tasks/main.yml

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

Files

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

for github

fils/ssh_configはsshの設定です。

roles/rails4-dev/files/ssh_config

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

Host bitbucket.org
 StrictHostKeyChecking no
 User git
 Hostname bitbucket.org
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/github_id_rsa

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

1
2
3
masayuki@www2267uo:~/work/sites/wrap-trap.net/ansible$ tar tvfz roles/rails4-dev/files/ssh_github.tar.gz
drwxrwxr-x masayuki/masayuki 0 2013-12-03 21:49 .ssh_github/
-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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
;; ruby-mode

(add-to-list 'load-path "~/.emacs.d/ruby-mode")
(autoload 'ruby-mode "ruby-mode" "Mode for editing ruby source files" t)
(setq auto-mode-alist (cons '("\\.rb$" . ruby-mode) auto-mode-alist))
(setq interpreter-mode-alist (append '(("ruby" . ruby-mode)) interpreter-mode-alist))
(autoload 'run-ruby "inf-ruby" "Run an inferior Ruby process")
(autoload 'inf-ruby-keys "inf-ruby" "Set local key defs for inf-ruby in ruby-mode")
(add-hook 'ruby-mode-hook '(lambda () (inf-ruby-keys)))

;; ruby-electric.el --- electric editing commands for ruby files
(require 'ruby-electric)
(add-hook 'ruby-mode-hook '(lambda () (ruby-electric-mode t)))

;; set ruby-mode indent
(setq ruby-indent-level 2)
(setq ruby-indent-tabs-mode nil)

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

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

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

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

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

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

Tasks

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

roles/rails4-dev/tasks/main.yml

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

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

roles/rails4-dev/tasks/github.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- name: be sure .ssh/config installed
  copy: src=roles/octopress/files/ssh_config dest=/home/masayuki/.ssh/config

- name: be sure .ssh_github installed
  copy: src=roles/octopress/files/ssh_github.tar.gz dest=/home/masayuki/

- name: unarchive .ssh_config
  shell: tar xvfz /home/masayuki/ssh_github.tar.gz -C /home/masayuki creates=/home/masayuki/.ssh_github

- name: chmod 400 .ssh_github/github_id_rsa
  shell: chmod 400 /home/masayuki/.ssh_github/github_id_rsa

- name: be sure git is installed
  apt: pkg=git state=installed

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

roles/rails4-dev/tasks/rail.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
- name: be sure ja_JP.UTF-8 enabled
  shell: locale-gen ja_JP.UTF-8

- name: be sure locale updated
  shell: update-locale LANG=ja_JP.UTF-8

- name: be sure python-sofrware-properties is installed
  apt: pkg=python-software-properties state=installed

- name: add repository for ruby2.1
  apt_repository: repo='ppa:brightbox/ruby-ng'

- name: be sure ruby-2.1 is installed
  apt: update_cache=yes pkg=ruby2.1 state=installed

- name: be sure ruby-2.1-dev is installed
  apt: pkg=ruby2.1-dev state=installed

- name: be sure gcc is installed
  apt: pkg=gcc state=installed

- name: be sure make is installed
  apt: pkg=make state=installed

- name: be sure bundler is installed
  gem: name=bundler user_install=no state=present

- name: be sure tmp dir is created
  shell: mkdir rails

- name: be sure 'bundle init' is executed
  shell: bundle init chdir="rails"

- name: be sure gem repos is added in Gemfile
  shell: echo 'source "https://rubygems.org"' > Gemfile chdir="rails"

- name: be sure gem "rails" is added in Gemfile
  shell: echo 'gem "rails", ">= 4.0.0"' >> Gemfile chdir="rails"

- name: be sure rails4 is installed
  shell: bundle install --path=vendor/bundle chdir="rails"

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

roles/rails4-dev/tasks/emacs.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
- name: be sure python-software-properties is installed
  apt: pkg=python-software-properties state=installed
  tags: emacs

- name: add repository for emacs24
  apt_repository: repo='ppa:cassou/emacs'
  tags: emacs

- name: be sure emacs installed
  apt: update-cache=true pkg=$item state=installed
  with_items:
    - emacs24
    - emacs24-el
  tags: emacs

- name: be sure tmp dir is removed if exists
  shell: rm -rf /home//tmp removes="/home//tmp"
  tags: emacs

- name: be sure dot.file cloned
  git: repo=https://github.com/038/dotfiles.git dest=/home//tmp
  tags: emacs

- name: be sure moved from /home//tmp/.emacs.d to /home//.emacs.d
  shell: mv /home//tmp/.emacs.d /home// creates=/home//.emacs.d
  tags: emacs

- name: be sure /home//tmp removed
  shell: rm -rf /home//tmp
  tags: emacs

- name: be sure init-loader is cloned
  git: repo=https://github.com/emacs-jp/init-loader.git dest=/home//tmp
  tags: emacs

- name: be sure moved from /home//tmp/init-loader.el to /home//.emacs.d/init
  shell: mv /home//tmp/init-loader.el /usr/share/emacs24/site-lisp/ creates=/usr/share/emacs24/site-lisp/init-loader.el
  tags: emacs

- name: be sure /home//tmp removed
  shell: rm -rf /home//tmp
  tags: emacs

- name: be sure 80-ruby.el copied
  copy: src=roles/rails4-dev/files/emacs/inits/80-ruby.el dest=/home//.emacs.d/inits
  tags: emacs

- name: be sure 90-rinari.el copied
  copy: src=roles/rails4-dev/files/emacs/inits/90-rinari.el dest=/home//.emacs.d/inits
  tags: emacs

- name: be sure 90-rhtml.el copied
  copy: src=roles/rails4-dev/files/emacs/inits/90-rhtml.el dest=/home//.emacs.d/inits
  tags: emacs

- name: be sure ruby-2.1.0 source code is downloaded
  get_url: url='' dest=/usr/local/src
  tags: emacs

- name: be sure ruby-2.1.0
  shell: tar xvfz /usr/local/src/ruby-.tar.gz -C /usr/local/src creates=/usr/local/arc/ruby-
  tags: emacs

- name: be sure ruby-mode.el is copied
  shell: find /usr/local/src/ruby- -name '*.el' -exec cp {} /usr/share/emacs/site-lisp \;
  tags: emacs

- name: be sure rinari is cloned
  git: repo=https://github.com/eschulte/rinari.git dest=/home//.emacs.d/rinari
  tags: emacs

- name: be sure 'git submodule init' is executed
  shell: git submodule init chdir=/home//.emacs.d/rinari
  tags: emacs

- name: be sure 'git submodule update' is executed
  shell: git submodule update chdir=/home//.emacs.d/rinari
  tags: emacs

- name: be sure rhtml is cloned
  git: repo=https://github.com/eschulte/rhtml.git dest=/home//.emacs.d/rhtml
  tags: emacs

- name: be sure an owner of /home/masayuki/.emacs.d is user.group
  shell: chown -R : /home//.emacs.d
  tags: emacs

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

Vars

roles/rails4-dev/vars/main.yml

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

Execution

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

Conclusion

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

Update

  • bundle installするrailsのフォルダ名をtmp→railsに変更
  • bundle installする際に–path=vendor/bundleを指定するようにした