はじめに
普段Dockerを使用して環境構築をしているのですが、学習を始めた当初、これで本当に開発ができるのか??と半信半疑でした。当時なぜそう思ったのか、そしてその疑問をどう払拭したのかを記事にまとめたいと思います。同じ境遇に陥っている人の助けに少しでもなりましたら嬉しいです。
Dockerとは
Dockerとはコンテナ型の仮想環境を作成、配布、実行するためのプラットフォームです。Linuxのコンテナ技術を使ったものであり、軽量で高速に起動、停止などが可能です。
クライアント(ターミナル操作)・Dockerホスト・レジストリ(DockerHub)の関係性は以下公式ドキュメントの画像がシンプルでわかりやすかったので引用させていただきました。適宜、ご参照いただければと思います。
引用元:https://docs.docker.jp/get-started/overview.html
DockerfileからDockerコンテナ起動まで
Dockerでの開発にはコンテナを作り、起動させる必要があります。今回はDockerfileを活用したコンテナの起動方法について以下のとおり簡単な図で説明させていただきます。
上図のDockerfileとはコンテナの設計書です。このDockerfileをもとにbuild(docker build
コマンド)すればImageができます。その後、Imageを指定してrun(docker run
コマンド)すればコンテナが起動するという順です。
簡単なコンテナ作ってみた
実際に上で説明したようにDockerfileからImageを作成し、コンテナを起動するまでをやってみたいと思います。
今回使用するDockerfileは以下の内容のものを使用し、出力結果を確認しながら少しずつ肉付けしていこうかと思います。Dockerfileの記述によって自分の作りたいコンテナが作れるというイメージを簡単に掴めたらと思います。
FROM ubuntu:latest
内容としてはubuntuをベースとしたイメージを作成したいと思います。
以下のとおりディレクトリにDockerfileのみ配置します。簡単な構造ですが、ディレクトリ構造書きました。
docker-practice
└ Dockerfile
docker-practice
ディレクトリ内で以下のコマンドを実行します。
-
docker build .
このコマンドによりDockerfileをもとにImageが作成されます。
一連のビルドがエラーなく完了すれば、ローカルにはubuntuのイメージが作成されているはずです。作成されたか確認するためにはdocker images
で確認できます。
以下、私の環境下で確認した結果です。(個人的なImageは削除させていただいています。)
※tagなど指定していないため、noneとなっている部分が多くなっていますが、そこはご容赦ください。terminaldocker-practice % docker images REPOSITORY TAG IMAGE ID CREATED SIZE 中略 中略 中略 中略 中略 <none> <none> 7825af3e6bb4 3 weeks ago 69.2MB
-
docker run -it <<イメージID>> bash
docker images
コマンドなどで確認したイメージIDをもとに上記コマンドを実行するとコンテナが起動し、同時にコンテナの中に入ることができます。コンテナ内で試しにls
コマンドを実行してみるとルートディレクトリでは以下の結果が出力されます。ooseyuuki@ooseyuukinoMacBook-Pro docker-practice % docker run -it 7825af3e6bb4 b ash root@8bf7b05a3f41:/# ls bin dev home media opt root sbin sys usr boot etc lib mnt proc run srv tmp var
例えば、以下のようにDockerfileを修正してみるとします。
FROM ubuntu:latest
RUN touch test.txt
RUNとはDockerコマンドの一つで、ビルド時にRUNの行にあるコマンドを実行するという意味合いを持ちます。(この場合で言うとtouch text.txt
をビルド時に実行します。)
このDockerfileも先ほどの1と2のコマンドを同様に実行して再度コンテナに入ると、コンテナ内にtext.txt
というファイルが新たに生成されていることがわかります。
ooseyuuki@ooseyuukinoMacBook-Pro docker-practice % docker run -it 243c26ce632e b
ash
root@176e5117eca8:/# ls
bin dev home media opt root sbin sys tmp var
boot etc lib mnt proc run srv test.txt usr
ここで終わるのも中途半端なのでdocker run
したと同時にテキストの内容を出力してくれるコンテナを作成したいと思います。
Dockerfileの中身は以下のとおり変更させていただきました。
FROM ubuntu:latest
RUN touch test.txt && echo 'Hello Docker!!' >> test.txt
CMD ["cat", "test.txt"]
こちらも同様にビルドしてイメージIDをもとにコンテナを起動(run)します。通常起動するだけではターミナルには何も表示されないのですが、今回CMDコマンドでコンテナ起動時にcat test.txt
を実行しているため、テキスト内の「Hello Docker!!」が出力されるはずです。
ooseyuuki@ooseyuukinoMacBook-Pro docker-practice % docker run 70a6c3d62a67
Hello Docker!!
ここまでやってきた通り、コンテナはDockerfileの記載を工夫することによりカスタマイズすることが可能です。
学習当時に抱いていた疑問
Dockerfileを使ってコンテナを作り、その中で作業することはわかったんですが、ただどうしても当時はDockerで開発するイメージが沸かなかったです。「Docker環境で開発とはローカルで作業するのか?」「それともコンテナ内に入って作業するのか?」なんて疑問を抱えてはもやもやしていました。
Dockerを使って少しだけ開発してみる
果たしてそんな疑問を抱えている人がどれくらいいらっしゃるかわかりませんが、今回はRails6のコンテナ環境を構築して、少しいじることでイメージをお伝えできたらと思っております。
使用するリポジトリ
以下URLにRails6の環境構築用に作成したリポジトリを用意いたしました。今回の記事ではDockerで開発するイメージをつかむことを主目的としているため、ファイルの詳細な説明はしません。ご了承いただけると幸いです
Railsを起動
こちら、リポジトリのREADMEどおりにコマンドを実行すればおそらく以下の画面になるかと思います。(port番号は3000
です)
volumesという技術
自分の抱いていた疑問(ローカルで作業するのか、コンテナで作業するのかと言う疑問)については、ローカルで作業するが結論になります。このことについて以下図にまとめてみました。
上図のうち、ローカルとコンテナのボックスを繋ぐvolumesという技術によりローカルのファイルとコンテナのファイルが常に最新状態で共有(同期)されるようになっています。
volumesとは
これ自体はdocker-compose.ymlで以下のように指定しています。右側がコンテナの、左側がローカルの作業ディレクトリを指定しています。
version: '3'
services:
app:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp # ここ!
ports:
- 3000:3000
depends_on:
- db
tty: true
stdin_open: true
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
ports:
- 3306:3306
volumes:
- ./tmp/db:/var/lib/mysql:delegated
- ./my.cnf:/etc/mysql/conf.d/my.cnf
cap_add:
- SYS_NICE
volumesを設定することで、dockerコンテナと自分のローカルが同じファイルを一緒に共有しているようなイメージで、ローカルのファイルを編集するとコンテナのファイルも編集が反映されるといった関係性が実現されます。
これにより、ローカルでは開発作業をし、コンテナはローカルの変更内容を反映し、Railsの実行環境として機能することが実現されます。
実際にvolumes(バインドマウント)を検証してみる。
ローカルでファイルを編集した場合、コンテナのファイルも同じく変更が反映されている確認しようと思います。今回はconfig/routes.rb
に以下のようなコメントを追加しようと思います。(ローカルで)
Rails.application.routes.draw do
# 今日はDockerの技術記事を書いています。
end
次に実際にコンテナの中に入って、変更が反映されているか確認してみます。
ooseyuuki@ooseyuukinoMacBook-Pro rails6_docker_sample % docker-compose exec app bash
root@f29f1556f46a:/myapp# cat config/routes.rb
Rails.application.routes.draw do
# 今日はDockerの技術記事を書いています。
end
コンテナ内のconfig/routes.rbにも同様のコメントが反映されていました。
docker-compose.ymlのvolumesでマウントするディレクトリを指定することでお互いが共有関係となり、コンテナ環境での開発を容易にしています。
最後に
Dockerを初めて学ぶ人にとってピンときづらいコンテナ環境での開発のイメージが少しでも湧けば嬉しいです。行ったり来たりな記事だったと思いますが、最後まで読んでいただき、本当にありがとうございます
定期的に記事を投稿しますので、引き続きよろしくお願いいたします