Dockerとは
導入するメリット
- アプリを簡単に開発・デプロイできる仕組み
- OS、ライブラリ、アプリケーションをひとまとめのパッケージにして配布できるため、開発環境を簡単に用意できる。
- メンバー間の開発環境を統一できる。
- テスト環境・本番環境の統一ができる。
Linuxについておさらい
- LinuxはOSの一種。(OSはコンピュータを動かすための基本ソフト)
-
シェル:Linuxコマンドを受け取って結果を出力するためのソフトウェア。ユーザーとLinuxの仲介役。
- コマンド入力→シェルが命令を解釈→Linuxに伝わって、コマンド実行→シェルがコマンドの実行結果をユーザーへ伝える 流れ
- ターミナル:入出力の画面を提供するソフトウェア。画面担当
基本のLinuxコマンド
コマンド | 説明 |
---|---|
ls | ディレクトリの中身を表示する |
pwd | カレントディレクトリを表示する |
cd | ディレクトリを移動する |
mkdir | ディレクトリを作成する |
rmdir | ディレクトリを削除する |
touch | ファイルを作成する |
echo | ファイルに書き込みする |
cat | ファイルの中身を表示する |
less | ファイルの中身をスクロール表示する |
mv | ファイルの移動、ファイル名を変更する |
rm | ファイルを削除する |
Dockerを使ってみる
まずは、
~ $ docker run hello-world
を実行すると、
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
起こっていること
-
コンテナ:Dockerの実行環境(OS、ライブラリ、アプリケーションのひとまとまり)。イメージは箱。
-
イメージ:コンテナに必要なものを記載した雛形。
-
クライアント:依頼主のこと。コマンドでタスクをデーモンに伝える。
-
デーモン:コマンドを受け取って、バックグラウンドでイメージやアプリケーションの操作を行うもので、今回はレジストリからイメージを取得する。
-
レジストリ:オンライン上にイメージを保存しておく場所。
アプリを作成・実行
Dockerのよく使うコマンド
こちらの記事がわかりやすくまとまっていた。
参考:Dockerコマンド
Dockerfile
- Docker imageの設計図 DockerfileからDocker imageを作る。
- Dockerfileという名のテキストファイル。
- INSTRACTION argument 形式で記載する。
- DockerfileはDockerfileという名前で必ず作る。
Dockerfileのinstruction
FROM
- ベースとなるイメージを決定する。
- DokerfileはFROMから書き始める。
- FROMの上にLayerが積み重なっていくイメージ。
- 指定するのは基本OSを指定することが多い。
FROM ruby:2.7
RUN
- Linux コマンドを実行してくれる。
- RUNを使うことで好きなようにカスタマイズできる。
- RUN毎にLayerができる。
FROM ruby:2.7
RUN touch test
RUN echo 'hello world' > test
Layerを最小限にするために
- DockerfileではRUN毎にimage Layerが作成されるので、RUNを連発するとdocker imageのサイズが大きくなってしまう。
- 解決策は、&&で繋げて1行にまとめる。バックスラッシュ( \ )で改行すると見やすくなる。
FROM ruby:2.7
RUN apt-get update && apt-get install\
xxx\
yyy\
apt-get update
: 新しいパッケージを取得。
apt-get install <package>
: をインストール。
cache
- RUNで一度インスールしたパッケージは、インストール後まとめておくことで後から他のパッケージをRUNで追加した時キャッシュを使ってくれる。
- キャッシュを使うことで再度実行することなく追加したパッケージ分だけRUNを実行してくれる。
この場合、新しくzzz
というパッケージを新しく追加。
※ -y
はインストール時インタラクティブな質問に対して全てyesで実行してくれる。
FROM ruby:2.7
RUN apt-get update && apt-get install -y \
xxx\
yyy\
RUN apt-get install -y zzz
インストール後1行にまとめることで次回からキャッシュを使ってくれる。
FROM ruby:2.7
RUN apt-get update && apt-get install -y \
xxx\
yyy\
zzz
CMD
- CMDはコンテナのデフォルトのコマンド。
- 原則Dockerfileの最後に記述。
CMD ["実行可能なコマンド", "コマンドの引数1", "コマンドの引数2"]
FROM ruby:2.7
RUN apt-get update && apt-get install -y \
xxx\
yyy\
zzz
CMD ["bundle", "exec", "ruby", "app.rb"]
RUNとCMDの違いは?
- RUNはimage Layerを作るがCMDは作らない
Dockerfileをbuildする
DockerfileをbuildしてDocker imageを作る。
$ docker bulid <directory>
buildするにはそのファイルまで移動してからbuildするのが一般的。
現在いる場所(current directory)の場合は.
$ docker bulid .
buildしたimageはdangling image(noneで表示されるタグのついていないimage)なので名前をつけることができる。
$ docker build -t <name> <directory>
Dockerfile詳細
$ docker buildの挙動
build
時に指定したbuild contextをDocker demonに渡している。
Docker demon
- コンテナやdocker imegeなどDockerオブジェクトと呼ばれるものを管理もの。
- クライアントはCLIツールを使ってDocker demonにコマンドを投げそれを解釈しDocker demonがイメージのビルドやコンテナの起動などを行っている。
build context
- Dokerfileが入ったフォルダのこと。
- Docker imageをbuildする時、build contextをDocker demonに渡し、build contextの内のDockerfileと他のファイルを使ってDocker imageを作成する。
- 基本buildに使わないファイルはbuild contextに入れない。
COPY
COPYはbuild context内のファイルをHostからDocker imageに組み込むことができる。
COPY <src> <コピー先>
COPYとADDの違い
ADD
はCOPY
と同様にbuild context内のファイルをHostからDocker imageに組み込むことができる。
どう使い分けるか?
- 単純にファイルやフォルダをコピーする場合はCOPYを使う
- tarの圧縮ファイル(階層、要領の多いものをまとめて圧縮)をコピーして解凍したいときはADDを使う。
- 圧縮することでbuild時に時間短縮。build後解凍されている。
-
ADD
は中上級者向け
Dockerfileがbuild contextにない場合
どういう時にそういう状況になるのか?
Dockerfileを複数用意する時。
例えば、開発環境とテスト環境で分けたい時など。その際ファイル名には、Dockerfile.dev、Dockerfile.testのように名前をつけるのが一般的。
$ docker build -f <dockerfilename> <build context>
例
dockerフォルダの中にsample_folderフォルダを作りそのsample_folderの中にDockerfileがある場合。
mkdir docker
cd docker
mkdir sample_folder
cd sample_folder
touch Dokerfile.dev
sample_folderの位置で以下を実行。
$ docker build -f ../Dockerfile.dev .
../Dockerfile.dev
はDockerfileの位置、.
はbuild contextの位置。
CMDとENTRYPOINT
CMD復習
CMDはDockerfileの最後に記述するコンテナのデフォルトのコマンド。
CMD ["実行可能なコマンド", "コマンドの引数1", "コマンドの引数2"]
CMD ["/bin/bash"]
$ docker container run -it -v ${PWD}/src:/var/www
ENTRYPOINT
ENTRYPOINTもCMDと同様にデフォルトのコマンドを指定することができる。
ENTRYPOINTはCMDと違いrun時に上書きできない。つまりrun時に上書きできるのはCMDのみ。
ENTRYPOINTがある場合CMDは以下のようなコマンドの引数のみの形をとる。
コンテナを1つのコマンドのようにして使いたい時に使うらしい。あんまり使うことはない感じかも。
ENTRYPOINT ["実行可能なコマンド"]
CMD ["コマンドの引数1", "コマンドの引数2"]
例
ENTRYPOINT ["ls"]
CMD ["--help"]
この場合runで上書きできるのはCMD--help
の部分だけ。
ENV
ENVは環境変数を設定する。
ENV key value1
ENV key=value2
書き方はどっちでも同じ。複数あるときは下の書き方の方が分かりやすい。
WORKDIR
WORKDIRはDocker instructionの実行ディレクトリを変更する。
FROM ruby:2.7
RUN mkdir sample_folder
RUN cd sample_folder
RUN touch sample_file
このDockerfileでやりたいのは、sample_folderを作りそのsample_folderに移動しsample_folder内でsample_fileを作りたい。
実際に実行してsample_folder内でsample_fileがあるか確認する。
$ docker build .
$ docker run -it 111b027b6948 bash
root@7636cb560dfc:/# ls
bin dev home lib32 libx32 mnt proc run sample_folder srv tmp var
boot etc lib lib64 media opt root sample_file sbin sys usr
sample_fileはsample_folder内ではなくroot直下に作られている。
そもそも、RUN
などのDockerのinstructionは全てroot直下で実行される。
どうするか?
RUNを&&で繋げて書けばsample_fileはsample_folderを作ることができる。
ただ毎回sample_folderに移動するのは手間。
FROM ruby:2.7
RUN mkdir sample_folder &&\
cd sample_folder &&\
touch sample_file
WORKDIRを使う。
FROM ruby:2.7
RUN mkdir sample_folder
WORKDIR /sample_folder
RUN touch sample_file
WORKDIRを使うことで実行するディレクトリを変更してくれる。
WORKDIRのパスは絶対パスで指定する。
ちなみに、WORKDIRではフォルダがない場合そのフォルダを作ってくれるので以下のような書き方も可能。
FROM ruby:2.7
WORKDIR /sample_folder
RUN touch sample_file
docker-composeについて
どんな時に使うのか?
-
$ docker run
のコマンドが長くなる時
今回もしこのまま$ docker run
をするならコマンドは、以下のように長くなるので使用。
$ docker run -it -v ~/Desktop/product-register:/product-register -p 3000:3000 <image> bash
- 複数のコンテナをまとめて起動する時。
docker-compose.ymlの使い方と書き方
-
docker-compose.yml
というファイルを作りそこに$ docker run
時のオプションコマンドなどを書いて設定しておく。
今からDocker compose書くよ宣言
service1:
service1のパラメータ
service1のパラメータ
service2
service2のパラメータ
service2のパラメータ
-
kye:value
の組み合わせで書く。 - value部分が複数ある場合は
-
を使ってリスト形式 - docker-composeでのパスの指定は相対パスで書く。
docker-compose.yml
version: "3"
services:
web:
build: .
ports:
- "3000:3000"
volumes:
- ".:/product-register"
tty: true
stdin_open: true
-
build
は$ docker build .
-
ports
は-p
オプション -
volumes
は-v
オプション -
tty
とstdin_open
は-it
オプション
Docker composeコマンド一覧
$ docker build <build context>
$ docker-compose build
$ docker run <image>
$ docker-compose up
$ docker-compose up --build
up
はimageが作られてない場合、build
も一緒にする。
Dockerfileを更新した場合は-- build
をつけることでbuild
してからrun
してくれるのでimageも更新される。
$ docker ps
$ docker-compose ps
$ docker exec <container> <command>
$ docker-compose exec <service> <command>
- 便利コマンド
$ docker-compose down
コンテナをstopしてから消してくれる。