手っ取り早くリモートのLinuxマシン(私の場合はVMwareの仮想マシン)からDockerイメージを作りたくなったのでその手順です。
最低限の手順なのでサービス(nginxやhttpd)を動かしたい場合はカスタマイズが必要です。不必要なファイルもコンテナに入るので、サイズを小さくする場合は適当にファイルを削除してください。
きっちり作るにはベースOSに必要最低限のパッケージだけ入れたコンテナを作り、そのコンテナに必要なパッケージを入れて作ります。しかし、コンテナが大きくても構わない、アップデートをベースのコンテナとDockerfileのビルドで行わなくても構わない、といった際にサクっと作るには便利です。
必要な物
ローカル、リモートともにLinuxであることを前提にしています。
- rsync – リモートとローカル両方
- ssh – リモートにsshdとローカルにssh
- docker – ローカル
作る手順
以下のシェルスクリプトを実行し、Docker Imageの元になるディレクトリを作成します。カレントディレクトリにファイルが保存されるので、適当なディレクトリで実行します。
#!/usr/bin/env bash # Set remote linux host name here target="remote.example.com" # Add more --exclude if you have more directories aren't needed rsync -avz \ --exclude '/backup' \ --exclude '/boot' \ --exclude '/dev' \ --exclude '/proc' \ --exclude '/sys' \ --exclude '/run' \ --exclude '/selinux' \ --exclude '/tmp' \ --exclude '/cgroup' \ --exclude '/mnt' \ --exclude '/media' \ --delete -e ssh \ "$target":/ "$target" # Make directories needed mkdir -p "$target"/{dev,tmp,run} chmod 1777 "$target"/tmp chmod 755 "$target"/{dev,run} # Create basic devices mknod -m 600 "$target"/dev/console c 5 1 mknod -m 600 "$target"/dev/initctl p mknod -m 666 "$target"/dev/full c 1 7 mknod -m 666 "$target"/dev/null c 1 3 mknod -m 666 "$target"/dev/ptmx c 5 2 mknod -m 666 "$target"/dev/random c 1 8 mknod -m 666 "$target"/dev/tty c 5 0 mknod -m 666 "$target"/dev/tty0 c 4 0 mknod -m 666 "$target"/dev/urandom c 1 9 mknod -m 666 "$target"/dev/zero c 1 5
$targetディレクトリの中にリモートファイルが保存されます。
ファイルのコピーが完了したら、次のコマンドでイメージを作ります。
# tar -c -C "remote.example.com" . | docker import - my-image:version
remote.example.com は上のシェルスクリプトで設定した$targetと同じにします。
作ったイメージのbashを起動してコンテナが動作することを確認します。
# docker run -it --rm my-image:version bash
イメージ作成後の作業
前提として以下を知っているとします。
- Dockerfile の書き方とdockerの使い方
- docker-compose.ymlの書き方とdocker-composeの使い方
rsyncでコピーしたファイル全てがイメージの中に入ってしまいます。普通は
- /homeの中のデータ
- /varの中のwwwやpgsql、mysqlといったデータ
- /etcの中の一部の設定ファイル
をdocker-compose.ymlのボリュームにして、変更を恒久的に保存したいファイル類を定義します。rsyncでコピーしたファイル/ディレクトリを丸ごとローカルファイルシステムボリュームにするだけです。
これらはイメージの中に入れる必要がないので別のディレクトリに移動します。
manファイルなどのドキュメント、rpmのキャッシュデータなど、色々と不必要な物があるハズなので要らない物は消します。
この作業を終わらせたら、もう一度 docker import コマンドを実行して小さくしたイメージを作ります。
後はDockerfileでコンテナに保存しない設定ファイルをコピー、起動したいサービスを定義し、docker-compose.ymlを作って必要なディレクトリをボリュームとしてマウントする定義を書きます。
必要な設定/定義を作った後は docker-compose up -d でコンテナを起動すればリモートマシンと同じ環境のコンテナが起動します。
Dockerを知らない方向け
コンテナは仮想マシンではありません。必要な「コマンド」だけを起動します。dnf/yum/aptなどは動作しますが、基本的にsystemdやjournaldやfirewalldは使いません。
例えば、httpdを起動したい場合はsystemctlを使わずに
httpd -D FOREGROUND
などとして起動します。他のサービスも同様です。複数のサービスをコンテナの立ち上げと同時に起動したい場合、色々方法がありますが、エントリポイントとなるシェルスクリプトを作って起動します。
詳しくはDockerfile、docker-compose.ymlの書き方のマニュアルを参照してください。