3
0

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 3 years have passed since last update.

DockerfileでのCOPYとbind mountの関係性

Last updated at Posted at 2020-05-05

最近ローカル開発環境はDocker composeで本番環境はGKEという環境でちょっと気になったことがありました。

本番環境のGKEにはGitHub Actionsを使ってイメージのビルド→ECRへのイメージアップロード→GKEへのデプロイを行っています。

ただこのGitHub Actionsの中でローカル開発環境のDocker composeで使っているDockerfileをsedやechoなどで一部変更しています。

もしくは環境によってDockerfileの名前を変えて使い分けてたりします。

これよくよく考えてみるとコンテナのポータビリティを損なっていませんかね?

個人的にはなるべく環境によってDockerfileを変えたくないなと思っています。

具体的にはどうことかいうと
※以下のファイルは説明のため簡略化しています

ローカル開発環境のDockerfile

FROM nginx
EXPOSE 80

ローカル開発環境のdocker-compose.yml

version: "3"
services:
  nginx:
    build:
      context: .
    ports:
      - "80:80"
    restart: always
    volumes:
      - ./src:/var/www

本番環境のDockerfile

FROM nginx
EXPOSE 80
COPY --chown=nginx:nginx ./src /var/www

ローカル開発環境はdocker-compose.ymlでbind mountしてるのでイメージに/src配下を含まないようにしている。

対して本番環境はイメージの/src配下を含まないといけないのでGitHub Actionsの中でCOPY --chown=nginx:nginx ./src /var/wwwを追記している状況です。

これってよくよく考えてみるとどっちも本番環境のDockerfileを使えばいいんじゃないですかね?

というのもDockerfileでCOPYしてビルドしたとしてもbind mountしたら/var/wwwの配下がビルドされた時点よりもbind mountが優先されるならばそれでいいんではないでしょうか?

ということでbind mountが必ず優先されるのか実験です。

実験環境

フォルダ構成

qiita
├── Dockerfile
├── docker-compose.yml
└── src
    └── copy.html

Dockerfileの内容

FROM nginx
EXPOSE 80
COPY --chown=nginx:nginx ./src /var/www

docker-compose.ymlの内容

version: "3"
services:
  nginx:
    build:
      context: .
    ports:
      - "80:80"
    restart: always
    volumes:
      - ./src:/var/www

この状態でビルドしてコンテナを立ち上げます。

$ docker-compose up -d

/var/www配下を確認します。

$ docker-compose exec nginx ls -hl /var/www
total 4.0K
-rw-r--r-- 1 root root 17 May  5 13:09 copy.html

この状態でsrc/copy.htmlを削除し、ビルドし直さずにコンテナを立ち上げなおしてsrc/copy.htmlがなくなっているか確認します。

$ rm -f src/copy.html
$ docker-compose stop
Stopping qiita_nginx_1 ... done
$ docker-compose up -d
Starting qiita_nginx_1 ... done
$ docker-compose exec nginx ls -hl /var/www
total 0

ではこの状態で今後はsrc/copy_2.htmlを作成し、ビルドし直さずにコンテナを立ち上げなおしてsrc/copy_2.htmlのみとなってるか確認します。

$ touch src/copy_2.html
$ docker-compose stop
Stopping qiita_nginx_1 ... done
$ docker-compose up -d
Starting qiita_nginx_1 ... done
$ docker-compose exec nginx ls -hl /var/www
total 0
-rw-r--r-- 1 root root 0 May  5 13:55 copy_2.html

想定通りsrc/copy_2.htmlのみが存在します。

ではこの状態でsrc/copy_2.htmlの中身を変更し、ビルドし直さずにコンテナを立ち上げなおしてsrc/copy_2.htmlの中身の変更が反映されているか確認します。

$ echo "qiita test" >> src/copy_2.html
$ docker-compose stop
Stopping qiita_nginx_1 ... done
$ docker-compose up -d
Starting qiita_nginx_1 ... done
$ docker-compose exec nginx ls -hl /var/www
total 4.0K
-rw-r--r-- 1 root root 11 May  5 14:00 copy_2.html
$ docker-compose exec nginx cat /var/www/copy_2.html
qiita test

こちらも想定通りsrc/copy_2.htmlの変更内容がコンテナから見たときに反映されています。

この実験からビルドした状態がどうであれbind mountしたらその時のマウント元の内容が反映されることがわかりました。

つまり最初に述べたように本番環境のDockerfileを使えばいいってことです!!

これで環境ごとのDockerfileの差分が1つ減りました!!
めでたし、めでたし...とはいきません

既に気付いてる方もいるかもしれませんがbind mountではファイルの権限がnginx:nginxになっていません。

この権限周りについては後日ちゃんと調べたいと思います。
※ちなみにdocker-compose.ymlのvolumesのオプションに権限を設定に関するものはありません

3
0
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
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?