はじめに
最近、開発用の環境として私はDockerを多用している。
開発マシンはmacだがDocker for Macではなく、仮想マシン(VirtualBox)上でDockerを起動させている。
最初の頃はDocker for Macを利用していたが、コンテナの管理のしやすさから仮想マシンを介して利用することに変化した。
仮想マシンは、ある程度の単位で分割して複数作成している。
これにより管理のしやすさを向上している。
例えば実験的に何かのプロジェクトを始めるときには新たな仮想マシンを作成して、そこにDocker環境を構築する。プロジェクトが終了すれば、何も考えずに該当の仮想マシンを削除するだけで良い。
これであれば既存のプロジェクトで使用している重要なコンテナやボリューム(永続化されたデータなど)を削除する危険性をかなり低減できる。
Dockerホスト用OS: Barge
DockerホストにCentOSを利用すると、DockerホストOSの起動や終了に時間が結構かかってしまう。常時起動しておくのはリソースの無駄だし。
このような用途のために、軽量なDockerホスト用のOSがある。
私がよく使用しているのがBargeというOSだ。
下記の記事が参考になる(恐らくBargeの作者の方が記載していると思われる)。
Bargeは起動や終了などかなり高速に動作するので満足している。容量が小さいのも良い。
新しいDockerホストを作成するスクリプト
後述するスクリプトを作って、Vagrantを利用して新しいDockerホストを簡単に生成できるようにしている。
実行したディレクトリに以下の構成でファイルが生成される。
1
2
3
.
├── Vagrantfile
└── export
Vagrantfile
は80→10080, 3306→13306のポートがデフォルトで設定されているが、スクリプトのオプションで変更可能にしている。
スクリプトのオプションの詳細は、 --help
を付与して実行すれば表示される。
例えばポート番号を変更したい場合は、 -p 80:20080,3306:23306
みたいにすればOK。
export
ディレクトリに置いてあるファイルがVagrantの /home/bargee/common
にマウントされる。この辺りもオプションで修正可能。
export
ディレクトリに docker-compose.yml
を置いてある状態であれば、このスクリプトを実行してローカルマシンで
1
2
vagrant up
vagrant ssh
を実行してvagrant内で、
1
2
cd common
docker-compose up
を実行すれば、Dokcerが起動できるようになる。
そしてこの環境が不要になれば vagrant destroy
でVM毎削除できるので管理が簡単で便利。
スクリプト
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#! /usr/bin/env ruby
# require {{{
require 'pp'
require 'pry'
require 'optparse'
require 'fileutils'
# }}}
# Options {{{
class Options
def initialize(argv)
@is_help = false
@options = self.class.default_options.merge(get_argument_options(argv))
end
public
class << self
def get_usages
results = []
results << "Usage: #{$0} [options]"
all_options.each do |key, value|
results << " -#{key} VAL : #{value}(default: #{default_options[key]})"
end
results
end
def all_options
{
d: 'docker version',
c: 'docker composer version',
e: 'host path',
v: 'guest path(vagrant)',
g: 'guest path(docker)',
p: 'Port forward settings(GUEST_PORT1:HOST_PORT1,GUEST_PORT2:HOST_PORT2,...)',
}
end
def default_options
{
d: "v18.03.0-ce", # DOCKER_VERSION
c: "1.20.0", # DOCKER_COMPOSER_VERSION
e: "./export", # HOST_COMMON_PATH
v: "/home/bargee/common", # VAGRANT_COMMON_PATH
g: "/app", # DOCKER_COMMON_PATH
p: "80:10080,3306:13306", # PORT_FORWARDS
}
end
end
def is_help?
@is_help
end
def docker_version
@options[:d]
end
def docker_composer_version
@options[:c]
end
def host_common_path
@options[:e]
end
def vagrant_common_path
@options[:v]
end
def docker_common_path
@options[:g]
end
def port_forwardings
@options[:p].split(',').map{|x| x.split(':')}
end
private
def getopts_parameters
results = []
results << 'h' + self.class.all_options.keys.map{|x| x.to_s.concat(':')}.join
results << 'help'
results
end
def get_argument_options(argv)
params = argv.getopts(*getopts_parameters)
@is_help = true if params['h'] || params['help']
results = {}
self.class.all_options.keys.each do |key|
value = params[key.to_s]
next if value.nil?
results[key] = value
end
results
end
end
# }}}
# FileMaker {{{
class FileMaker
def initialize(filename, options = nil)
@filename = filename
@options = options
end
def execute
open(@filename, 'w') do |fw|
fw.printf('%s', contents)
end
end
private
def contents
end
end
# }}}
# VagrantFileMaker {{{
class VagrantFileMaker < FileMaker
private
def make_setting_for_port_forward
results = []
@options.port_forwardings.each do |port_forwarding|
guest_port = port_forwarding[0]
host_port = port_forwarding[1]
results << " config.vm.network \"forwarded_port\", guest: #{guest_port}, host: #{host_port}"
end
results.join("\n")
end
def contents
results = <<"EOS"
Vagrant.configure("2") do |config|
config.vm.box = "ailispaw/barge"
#{make_setting_for_port_forward}
config.vm.synced_folder "#{@options.host_common_path}", "#{@options.vagrant_common_path}", mount_options: ['dmode=777', 'fmode=777']
latest_docker_install_script = <<SCRIPT
docker version
/etc/init.d/docker restart #{@options.docker_version}
wget -L https://github.com/docker/compose/releases/download/#{@options.docker_composer_version}/docker-compose-\`uname -s\`-\`uname -m\`
mv docker-compose-\`uname -s\`-\`uname -m\` /opt/bin/docker-compose
chmod +x /opt/bin/docker-compose
chown root:root /opt/bin/docker-compose
SCRIPT
ssh_setting_modify_script = <<SCRIPT
sed -ie 's/#PermitUserEnvironment no/PermitUserEnvironment yes/' /etc/ssh/sshd_config
sudo -i -u bargee echo 'PATH=/bin:/sbin:/usr/bin:/usr/sbin' > /home/bargee/.ssh/environment
/etc/init.d/S50sshd restart
SCRIPT
utility_install_script = <<SCRIPT
pkg install vim
SCRIPT
config.vm.provision :shell, :inline => latest_docker_install_script
config.vm.provision :shell, :inline => ssh_setting_modify_script
config.vm.provision :shell, :inline => utility_install_script
end
EOS
end
end
# }}}
# Main {{{
VAGRANT_FILE = 'Vagrantfile'
if File.exist?(VAGRANT_FILE)
$stderr.printf("#{VAGRANT_FILE} is Exist!\nSkipping.\n")
exit 1
end
options = Options.new(ARGV)
if (options.is_help?)
$stderr.printf(Options.get_usages.map{|x| x.concat("\n")}.join)
exit 1
end
sources = {
VagrantFileMaker: [VAGRANT_FILE, options]
}
system("mkdir -p #{options.host_common_path}")
sources.each do |key, source|
object = Object.const_get(key.to_s).new(source[0], source[1])
object.execute
end
# Get box
system('vagrant box add ailispaw/barge')
system('vagrant init -m ailispaw/barge')
$stderr.printf("\n")
$stderr.printf("Please confirm Vagrantfile : forwarded_port and other settings\n")
$stderr.printf("After that, you run 'vagrant up'\n")
# }}}
# vim: set ts=2 sw=2 ro fdm=marker:
生成されるVagrantfileのサンプル
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
Vagrant.configure("2") do |config|
config.vm.box = "ailispaw/barge"
config.vm.network "forwarded_port", guest: 80, host: 10080
config.vm.network "forwarded_port", guest: 3306, host: 13306
config.vm.synced_folder "./export", "/home/bargee/common", mount_options: ['dmode=777', 'fmode=777']
latest_docker_install_script = <<SCRIPT
docker version
/etc/init.d/docker restart v1.13.1
wget -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m`
mv docker-compose-`uname -s`-`uname -m` /opt/bin/docker-compose
chmod +x /opt/bin/docker-compose
chown root:root /opt/bin/docker-compose
SCRIPT
ssh_setting_modify_script = <<SCRIPT
sed -ie 's/#PermitUserEnvironment no/PermitUserEnvironment yes/' /etc/ssh/sshd_config
sudo -i -u bargee echo 'PATH=/opt/bin:/bin:/sbin:/usr/bin:/usr/sbin' > /home/bargee/.ssh/environment
/etc/init.d/S50sshd restart
SCRIPT
utility_install_script = <<SCRIPT
pkg install vim
SCRIPT
config.vm.provision :shell, :inline => latest_docker_install_script
config.vm.provision :shell, :inline => ssh_setting_modify_script
config.vm.provision :shell, :inline => utility_install_script
end