18
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

dockerにvolumeでソースコードを共有しつつcomposerでパッケージをインストールしたときの話 on OSX

Posted at

OSXでdocker使おうと思うと、現状だとVagrantのProviderでdocker使うかboot2docker使うかの2択だと思います。
今回はboot2dockerを利用している前提で、いろいろやってみました。

背景

dockerも1.0になったので、ちょっと本格的に利用してみようかとあっちこっちググりつつコンテナ作りに邁進してました。
この辺はちょっと省略しますけど、以下のような構成で 実行環境 on dockerを実現しています。
かなり簡略化してますけど、イメージは伝わると思います。

+application
 +Dockerfile
 +src
  +...
  +composer.json
Dockerfile
FROM agen/appbase
VOLUME ["/app"]
$ docker build -t agen/app .
$ docker run -i -t -P -v `pwd`/src:/app agen/app /bin/bash

ここで、agen/appbaseではnginxやPHP-FPMなどの準備がすべて済んでいて、 アプリケーション専用のユーザー が用意されていて、ドキュメントルートである/appにアプリケーションが配置されていればアプリケーションが動く、というところまで準備が済んでいるとします。
なお、実行環境と書いた通り、このコンテナの上で開発する気はさらさらありません。ホストでsrc以下をごちゃごちゃします。

多分agen/appbaseでEXPOSEされてる80にアクセスすると、アプリケーションが動く様が観察できるでしょう。

・・・ネイティブでdockerを動かしているUbuntuならば。

boot2dockerの場合

MacはネイティブでDockerを動かすことはできないので、上述したboot2dockerを利用します。
で、boot2dockerの仕組み上、VOLUMEを素直に利用できません。

Ubuntuの場合
HOST <=> Container

なので、ちゃんとVOLUME張れるんですけど、

boot2dockerの場合
HOST <=> VirtualBox <=> Container

なので、Hostから直接Containerに張れません。
この辺りの問題はissueにも上がってますし、解決方法はないこともないです。

boot2dockerに共有フォルダを張るまで

HOSTから直接張れないので、現状での当然の帰結として、VirtualBoxに共有フォルダ張ってContainerに伝播させます。
ところが、VirtualBoxで共有フォルダを使うためにはゲストOS(ここではCoreOS)にGuest Additionsを入れておく必要があります。
boot2dockerが標準で提供しているCoreOSにはGuest Additionsが含まれていないので、まずこれを準備しなければなりません。

ここで、boot2docker でボリュームの共有を行うを参考に、Guest Additions入りboot2dockerを入れることにします。

・・・はい、詳しくは上記リンクを参考で。

これで伝播までは完了。ちゃんと張れてることを確認できると思います。

本題

長かったんですけど、ここからが本題です。
上記までで共有フォルダのマウントまでできました。
コンテナにアプリ専用ユーザーでSSHでログインしてcomposerで依存ライブラリをインストールしてみます。

$ ssh webapp@localhost -p 40153
webapp$ cd /app
webapp$ composer install
  [RuntimeException]
  vendor does not exist and could not be created. 

インストールできません。

webapp$ pwd
/home/webapp
webapp$ ls -al
drwxr-xr-x 1 root   root    442 Jun 29 10:31 app

はい、rootユーザーです。
実はVirtualBoxにrootで共有フォルダが張られているために、書き込み権限がないのです。

アプローチ

ここで解決方法は2種類あると思ってて、

  1. webappユーザーをrootに属させる
  2. webappユーザーでも書き込みできるよう共有フォルダの権限を変える

1は論外。何のためにユーザーを用意したのかわかりませんし、何よりこの問題はboo2dockerを利用する場合のみ発生します。
とすれば、選択肢は2のみ。幸いこれはVirtualBoxの問題なので、ググればいくらでも対応策は出てきます。

共有フォルダの権限を変える

自動化はあとで考えるとして、このアプローチで問題ないかを直接確かめていくことにします。

$ boot2docker ssh
docker$ id
uid=1000(docker) gid=50(staff) groups=50(staff),100(docker)
docker$ sudo mount -t vboxsf -o uid=1000,gid=1000,dmode=0755,fmode=0755 home /Users
docker$ ls -al /Users
drwxr-xr-x    1 docker   1000           374 Jun 17 13:17 Guest/
drwxr-xr-x    1 docker   1000           170 Jun 17 13:28 Shared/
drwxr-xr-x    1 docker   1000          1360 Jun 30 05:54 agen/

権限が変わっていることが確認できます。

続いて、コンテナから確認します。

$ ssh webapp@localhost -p 40153
webapp$ pwd
/home/webapp
webapp$ ls -al
drwxr-xr-x 1 webapp webapp  510 Jun 30 05:52 app

こちらも意図通りです。
ですので、これでcomposer installが通るはず。

webapp$ cd app
webapp$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev)
...
Writing lock file
Generating autoload files
Generating optimized class loader
Compiling common
webapp$ ls -al
drwxr-xr-x 1 webapp webapp   782 Jun 30 05:53 vendor
webapp$ exit
$ pwd
/Users/agen/application
$ ls -al src
...
drwxr-xr-x  23 agen  staff    782  6 30 14:53 vendor

通りました。無事にインストールもできていて、かつ権限も問題なさそうに見えます。

自動化

この設定は、boot2docker restartしちゃうと当然のように消えちゃいます。
なので、できればboot2docker起動時に自動的に走るようにしたいんですけど。。。
あんまり手間かけたくない(正直言ってわからない)ので、今は暫定的に以下のようにしてます。

$ boot2docker up
$ boot2docker ssh "sudo mount -t vboxsf -o uid=1000,gid=1000,dmode=0755,fmode=0755 home /Users"

boot2dockerをラップして、勝手にこれを実行するようにはしてますけど、なんかほかにいい方法ないですか?

18
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?