0%

DockerのWordPressコンテナをcommitしてもvolumeがimageに含まれなくて困った

Dockerで構築したWordPressの2-Container-Appを複製してステージング環境を作ろうとしました。
commitしてイメージを作成してからコンテナを起動したのですがvolumeに指定したディレクトリの中身がありません。

Data Container volumes can’t be saved as images #7583にもissueがありますが現状のデザインのようです。

Right, so volumes are not part of the container’s fs, they are on the host’s fs.
In most cases people don’t want data in volumes to be in an image, either because it’s huge, sensitive information, etc.

Flockerみたいな仕組みはあらためて便利に思います。

volumeバックアップの参考資料

StackOverflowから参考になりそうなポストを探します。

nsenter

nsenterはnsenterコマンドをDockerコンテナからホストにマウントして使うでインストールして、nseのラッパーを作成しておきます。

~/bin/nse
#!/usr/bin/env bash
[ -n "$1" ] && sudo nsenter --pid --uts --mount --ipc --net --target $(docker inspect --format="{{ .State.Pid }}" $1)

コンテナのcommit

複製元になるコンテナをcommitします。ただしvolumeのディレクトリはimageに含まれません。

$ docker stop wp
$ docker stop wp-db
$ docker commit wp masato/blog
$ docker commit wp-db masato/blog-db

DBデータコンテナの作成

DBコンテナをinspectしてvolumeを確認します。

$ docker inspect --format="{{ .Volumes }}" wp-db
map[/etc/mysql:/var/lib/docker/vfs/dir/1d16ed7c668257f65419afec072519ac7d477fa4c0145e134e079ef71fdd7815 /var/lib/mysql:/var/lib/docker/vfs/dir/b4de8453c779df2f69fbe15b77f1adc553e7ef8c087b0b318c2b029f8a668b66]

DBコンテナの/var/lib/mysqlと/etc/mysqlをバックアップをします。

$ docker run --rm --volumes-from wp-db -v $(pwd):/backup busybox tar cvf /backup/var_lib_mysql.tar /var/lib/mysql
$ docker run --rm --volumes-from wp-db -v $(pwd):/backup busybox tar cvf /backup/etc_mysql.tar /etc/mysql

nsenterで接続したいのでbusyboxでなくubuntuでデータコンテナを作成します。
作成したデータコンテナにDockerホストのローカルにバックアップしたtarをuntarします。

$ docker run -i -t -d -v /var/lib/mysql -v /etc/mysql --name db-stg-vol ubuntu /bin/bash
$ docker run --rm --volumes-from db-stg-vol -v $(pwd):/backup busybox tar xvf /backup/var_lib_mysql.tar
...
var/lib/mysql/performance_schema/events_waits_history_long.frm
var/lib/mysql/performance_schema/file_summary_by_instance.frm
var/lib/mysql/ibdata1
$ docker run --rm --volumes-from db-stg-vol -v $(pwd):/backup busybox tar xvf /backup/etc_mysql.tar
...
etc/mysql/conf.d/my.cnf
etc/mysql/conf.d/mysqld_safe_syslog.cnf
etc/mysql/debian-start

db-stg-volコンテナをマウントしてdb-stgコンテナを起動します。

$ docker run --name db-stg -d --volumes-from db-stg-vol masato/blog-db

nsenterでdb-stgに接続して、DBコンテナが正常に複製できたかmysqlの確認をします

$ nse db-stg
$ mysql -uadmin -ppassword wordpress
mysql>

WordPressデータコンテナの作成

wpコンテナのボリューム(/app/wp-content)をバックアップして、wp-stg-volにリストアします。

$ docker run --rm --volumes-from wp -v $(pwd):/backup busybox tar cvf /backup/app_wp_content.tar /app/wp-content
$ docker run -i -t -d -v /app/wp-content --name wp-stg-vol ubuntu /bin/bash
$ docker run --rm --volumes-from wp-stg-vol -v $(pwd):/backup busybox tar xvf /backup/app_wp_content.tar
...
app/wp-content/themes/responsive.orig/search.php
app/wp-content/themes/responsive.orig/sidebar-right.php
app/wp-content/themes/responsive.orig/404.php

db-stgコンテナのIPアドレスの確認をします。

$ docker inspect --format="{{ .NetworkSettings.IPAddress }}" db-stg
172.17.0.128

wp-stgコンテナを起動します。

$ docker run -d --link db-stg:db -e DB_HOST="172.17.0.128" -e DB_PORT="3306" -e DB_PASS="password" --name wp-stg --volumes-from wp-stg-vol -p 8091:80 masato/blog

このイメージは一度DBを作成した状態から作成しています。すでに/.mysql_db_createdが存在しているので/run.shを実行後にexitしてしまいます。そのためDB_HOSTとDB_HOSTの環境変数がlinkingから取得して設定できないため、上記のrunでは明示的に環境変数をしていしています。

run-wordpress.sh
#!/bin/bash
if [ -f /.mysql_db_created ]; then
exec /run.sh
exit 1
fi

DB_HOST=${DB_PORT_3306_TCP_ADDR:-${DB_HOST}}
DB_HOST=${DB_1_PORT_3306_TCP_ADDR:-${DB_HOST}}
DB_PORT=${DB_PORT_3306_TCP_PORT:-${DB_PORT}}
DB_PORT=${DB_1_PORT_3306_TCP_PORT:-${DB_PORT}}

使い捨てのコンテナで、どのような環境変数が設定される確認します

$ docker run --rm -i -t  --link db-stg:db -e DB_HOST="172.17.0.128" -e DB_PORT="3306" -e DB_PASS="password"  --volumes-from wp-stg-vol  idcf/engineer-blog env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=f7f9091680dd
TERM=xterm
DB_PORT=3306
DB_PORT_3306_TCP=tcp://172.17.0.128:3306
DB_PORT_3306_TCP_ADDR=172.17.0.128
DB_PORT_3306_TCP_PORT=3306
DB_PORT_3306_TCP_PROTO=tcp
DB_NAME=wordpress
DB_ENV_MYSQL_PASS=password
DB_ENV_DEBIAN_FRONTEND=noninteractive
DB_ENV_MYSQL_USER=admin
DB_HOST=172.17.0.128
DB_PASS=password
HOME=/
DEBIAN_FRONTEND=noninteractive
DB_USER=admin

wp-stgコンテナにnsenterで接続してリバースプロキシ用に、これから作成するxipのドメインを指定します。

$ nse wp-stg
$ vi /app/wp-config.php
define('WP_SITEURL', 'http://p8091.210.140.17.194.xip.io/blog');
define('WP_HOME', 'http://p8091.210.140.17.194.xip.io/blog/');
define('WP_CONTENT_URL', 'http://p8091.210.140.17.194.xip.io/blog/wp-content');

OpenRestyでリバースプロキシのHTTPルーティングを指定します。

$ docker restart wp-stg
$ docker inspect --format="{{ .NetworkSettings.IPAddress }}" wp-stg
172.17.0.141
$ docker run -it --rm --link openresty:redis dockerfile/redis bash -c 'redis-cli -h $REDIS_PORT_6379_TCP_ADDR set p8091.210.140.17.194.xip.io 172.17.0.141:80'
  • xipのドメインで複製したコンテナの起動を確認します。

http://p8091.210.140.17.194.xip.io/blog