{
    "componentChunkName": "component---src-templates-blog-post-jsx",
    "path": "/post/how-to-mount-data-volume-to-local-with-docker-compose/",
    "result": {"data":{"site":{"siteMetadata":{"title":"WEB EGG","author":"Leko - CTO at Yuimedi"}},"markdownRemark":{"id":"85f35f28-5fe1-5745-a2e5-243515914880","excerpt":"この記事は12/1のDocker2 Advent Calendar, 12/3のHamee Advent Calendarの記事です。 こんにちは。 docker composeめちゃくちゃ便利ですよね。 Chef, Vagrant, Puppet, Ansible, Fabric…","html":"<p>この記事は<a href=\"http://qiita.com/advent-calendar/2016/docker2\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">12/1のDocker2 Advent Calendar</a>, <a href=\"http://qiita.com/advent-calendar/2016/hamee\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">12/3のHamee Advent Calendar</a>の記事です。</p>\n<p>こんにちは。<br>\ndocker composeめちゃくちゃ便利ですよね。<br>\nChef, Vagrant, Puppet, Ansible, Fabric…とプロビジョニングツールとか仮想化ツールを色々触ってきましたが、<br>\nそれらよりずば抜けて扱いやすいと思っているツールです。</p>\n<p>で、ローカルで開発している時に困るのが、 <strong>MySQLをはじめDBにデータを持ってもコンテナを破棄するとデータがすっ飛ぶ</strong> 問題です。<br>\n軽量なアプリの場合ならDB破棄してシード流して、、、という構成でもイケるかも知れませんが、多くの場合オーバーヘッドが大きすぎてまともに開発できなくなると思います。</p>\n<p>Docker for Macを使用している場合はこの問題は難なく解消できるのですが、<br>\ndocker-machineを使用している場合に恐らくドハマリするので、備忘録として残しておきます。</p>\n<!--more-->\n<h2 id=\"まえおき\" style=\"position:relative;\"><a href=\"#%E3%81%BE%E3%81%88%E3%81%8A%E3%81%8D\" aria-label=\"まえおき permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>まえおき</h2>\n<p>冒頭にも書きましたが、docker-compose + docker-machineでの話です。<br>\nただ、互換性のためにDocker for Macでも動作確認はしております。</p>\n<h2 id=\"基本戦術\" style=\"position:relative;\"><a href=\"#%E5%9F%BA%E6%9C%AC%E6%88%A6%E8%A1%93\" aria-label=\"基本戦術 permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>基本戦術</h2>\n<div class=\"gatsby-highlight\" data-language=\"yaml\"><pre class=\"language-yaml\"><code class=\"language-yaml\"><span class=\"token key atrule\">version</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'2'</span>\n<span class=\"token key atrule\">services</span><span class=\"token punctuation\">:</span>\n  <span class=\"token key atrule\">db</span><span class=\"token punctuation\">:</span>\n    <span class=\"token key atrule\">image</span><span class=\"token punctuation\">:</span> mysql<span class=\"token punctuation\">:</span><span class=\"token number\">5.6</span>\n    <span class=\"token key atrule\">volumes</span><span class=\"token punctuation\">:</span>\n      <span class=\"token punctuation\">-</span> ./db/mysql_data<span class=\"token punctuation\">:</span>/var/lib/mysql\n    <span class=\"token key atrule\">environment</span><span class=\"token punctuation\">:</span>\n      <span class=\"token punctuation\">-</span> MYSQL_ROOT_PASSWORD=root\n      <span class=\"token punctuation\">-</span> MYSQL_DATABASE=app</code></pre></div>\n<p>大枠このような感じになると思います。<br>\nvolumesでローカルのディレクトリとMySQLコンテナのデータ領域をマウントしています。<br>\nこれで、何かデータが書き込まれればローカルのファイルとして残るので、コンテナが消えてもデータが永続化されそうです。</p>\n<p>何度でも書きますが、Docker for Macならこの書き方で問題になりません。意図したとおり動きます。 ですが、docker-machine環境においては、以下の問題が発生します。</p>\n<h2 id=\"問題コンテナ内のパーミッションオーナー\" style=\"position:relative;\"><a href=\"#%E5%95%8F%E9%A1%8C%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E5%86%85%E3%81%AE%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%AA%E3%83%BC%E3%83%8A%E3%83%BC\" aria-label=\"問題コンテナ内のパーミッションオーナー permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>問題：コンテナ内のパーミッション・オーナー</h2>\n<p>docker-machineでvolumesを利用すると、</p>\n<ul>\n<li>ローカルのパーミッション・オーナー・グループが無視される\n<ul>\n<li>uid=1000のユーザがオーナーになる。上記Yamlの場合はftpユーザがオーナーになってました</li>\n</ul>\n</li>\n<li>MySQLの実行ユーザでは権限が足りず、Permission deniedや…not writable的なエラーが起きる</li>\n<li>マウントした時に発生するので、Dockerfile内でごにょっておく等の事前準備は不可能</li>\n<li>MySQLの実行ユーザを無理やりuid=1000にすることでも解消できそうですが、MySQLと関係のないユーザでMySQLを操作するのはキモい…</li>\n</ul>\n<p>という感じです。<br>\nかなりのゴリ押しで、自分でも汚いと思っているハックですが、こんな解消方法で突破できました。</p>\n<div class=\"gatsby-highlight\" data-language=\"yaml\"><pre class=\"language-yaml\"><code class=\"language-yaml\"><span class=\"token key atrule\">version</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'2'</span>\n<span class=\"token key atrule\">services</span><span class=\"token punctuation\">:</span>\n  <span class=\"token key atrule\">db</span><span class=\"token punctuation\">:</span>\n    <span class=\"token key atrule\">image</span><span class=\"token punctuation\">:</span> mysql<span class=\"token punctuation\">:</span><span class=\"token number\">5.6</span>\n    <span class=\"token key atrule\">command</span><span class=\"token punctuation\">:</span> bash <span class=\"token punctuation\">-</span>c 'usermod <span class=\"token punctuation\">-</span>o <span class=\"token punctuation\">-</span>u 1000 mysql; groupmod <span class=\"token punctuation\">-</span>o <span class=\"token punctuation\">-</span>g 500 mysql; chown <span class=\"token punctuation\">-</span>R mysql<span class=\"token punctuation\">:</span>root /var/run/mysqld/; /entrypoint.sh mysqld <span class=\"token punctuation\">-</span><span class=\"token punctuation\">-</span>user=mysql <span class=\"token punctuation\">-</span><span class=\"token punctuation\">-</span>console'\n    <span class=\"token key atrule\">volumes</span><span class=\"token punctuation\">:</span>\n      <span class=\"token punctuation\">-</span> ./db/mysql_data<span class=\"token punctuation\">:</span>/var/lib/mysql\n    <span class=\"token key atrule\">environment</span><span class=\"token punctuation\">:</span>\n      <span class=\"token punctuation\">-</span> MYSQL_ROOT_PASSWORD=root\n      <span class=\"token punctuation\">-</span> MYSQL_DATABASE=app</code></pre></div>\n<p><code>command: ...</code>の行を足しました。<br>\nコンテナ起動時にデータ領域のパーミッション・オーナー・グループを書き換えてからmysqldを起動しています。</p>\n<p><code>command</code>セクションに指定できる値はシェルではなく、<br>\n実行可能ファイルが1つめ、それ以降は全て引数という形式にエスケープされてしまいます。<br>\n単純に複数コマンドを書くことができません。なので<code>bash -c ...</code>と書いて複数行のシェルを実行しています。</p>\n<p>Docker for Macでも動作確認しましたが、この構成で動いてくれました。</p>\n<h2 id=\"まとめ\" style=\"position:relative;\"><a href=\"#%E3%81%BE%E3%81%A8%E3%82%81\" aria-label=\"まとめ permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>まとめ</h2>\n<p><strong>docker-compose使うならDocker for Mac使いましょう。色々つらくない。圧倒的に楽</strong><br>\nもしチーム内に１人でもdocker-machineの人が居たら、上記のハックを使ったら良いと思います。</p>\n<p>ベンチマーク取ってないので分かりませんが、<br>\nDocker for Macの方が主にマウント・ファイルI/O周りの速度が向上しているように感じます。<br>\nまだdocker-machineとDocker for Macの違いを体系的に理解できていないので、また別途記事を書きます。</p>\n<h2 id=\"おまけエンコーディング問題\" style=\"position:relative;\"><a href=\"#%E3%81%8A%E3%81%BE%E3%81%91%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E5%95%8F%E9%A1%8C\" aria-label=\"おまけエンコーディング問題 permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>おまけ：エンコーディング問題</h2>\n<p>上記の対応だけでは、エンコーディングの問題が解消していないので、マルチバイト周りでハマります。<br>\nこちらの記事も併せてご参照ください。</p>\n<blockquote>\n<p><a href=\"/post/how-to-use-redmine-with-docker-in-japanese/\">RedmineのDockerコンテナとMySQLで日本語を使えるようにするまで | WEB EGG</a></p>\n</blockquote>","timeToRead":4,"frontmatter":{"title":"docker composeでMySQLのデータ領域をローカルにマウントする","tags":["Docker","Docker compose","MySQL"],"date":"November 30, 2016","featuredImage":null}}},"pageContext":{"slug":"/how-to-mount-data-volume-to-local-with-docker-compose/","previous":{"fields":{"slug":"/achieve-1000-yen-per-month/"},"frontmatter":{"title":"初めてブログの広告収益が月1000円を超えた","tags":["Google Adsense"]}},"next":{"fields":{"slug":"/how-to-use-mmdjs/"},"frontmatter":{"title":"MMDのモデルにブラウザで踊って頂いた","tags":["JavaScript","MikuMikuDance","Three.js"]}}}},
    "staticQueryHashes": ["2585454260","2954598359"]}