当記事は随時更新していきます。
Dockerのインストール、起動
コマンド色々
runコマンド
実行時イメージ
- runコマンドは、下記3つのコマンドを同時に行う
- pull ・・・イメージの取得、ダウンロード
- create ・・・指定したイメージ上に書き込み可能なコンテナ・レイヤを作成
- start ・・・dockerコンテナを起動
オプション
-d:デタッチ
- 標準入出力をコンソールからデタッチする→
コンテナ起動後、そのままコンソールからコマンドが入力できる
※ログが見たい場合docker logs [CONTAINER ID]
-it:-i(interactive)と-t(tty)
- ざっくりと、docker runを実行したコンソールで、そのまま入出力ができる といった感じ
-p:ポートのマッピング
- -p [ホストのポート]:[コンテナのポート]
-p 1234:5678
ホストのポート1234とコンテナのポート5678を紐づける
--net:ネットワークの指定
- --net [ネットワーク名]
- ネットワークは下記コマンドで作成する
docker network create [ネットワーク名]
起動中のコンテナ内に入る
docker exec -it [コンテナ名またはコンテナID] bash
コンテナの停止
docker stop xxxxxx
イメージの作成 commit
- CONTAINER IDの確認
user01@DESKTOP-5FA6FSN:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf6d7ae93d7d ubuntu:20.04 "bash" 24 minutes ago Exited (0) 18 minutes ago ruby_bash
- イメージ作成
user01@DESKTOP-5FA6FSN:~$ docker commit cf ruby:tag1
sha256:45994187050fe27b914c4fc3fe89a613514efc073b3cddfb933b41e486aae013
docker commit [コンテナID] [コンテナ名]:[タグ名]
コンテナIDはフル桁じゃなくても、一意になる桁までの指定でOK
- 確認
user01@DESKTOP-5FA6FSN:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ruby tag1 45994187050f 2 minutes ago 156MB
ログ参照
docker logs [コンテナID、コンテナ名]
- 使用例
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8119a5ec7968 mysql:8.0.29 "docker-entrypoint.s…" 35 minutes ago Up 35 minutes 3306/tcp, 33060/tcp mydb
b2bb822da447 rubyimg:tag1 "bash" About an hour ago Up About an hour dreamy_payne
$ docker logs mydb
2023-06-05 01:42:08+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1.el8 started.
:
$ docker logs 8119a5ec7968
2023-06-05 01:42:08+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1.el8 started.
:
小技的なコマンド
全てのコンテナIDの取得
docker ps -aq
使用例
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1f7f7e124bb9 hello-world "/hello" 7 seconds ago Exited (0) 6 seconds ago hungry_bohr
a1db76564eac rubyimg:tag1 "ruby myapp.rb -o 0.…" 2 weeks ago Exited (255) 2 weeks ago 0.0.0.0:4567->4567/tcp, :::4567->4567/tcp cool_zhukovsky
$ docker ps -aq
1f7f7e124bb9
a1db76564eac
応用例
- 全てのコンテナを削除する
$ echo $(docker ps -aq)
1f7f7e124bb9 a1db76564eac
$ docker rm $(docker ps -aq)
1f7f7e124bb9
a1db76564eac
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Dockerfileについて
- Dockerfileとは:イメージの構築手順をコード化したもの
- Dockerfielを利用する際のざっくりとした流れ
- Dockerfile作成
- イメージ作成(build実行)
- 作成したイメージを実行してコンテナ起動
Dockerfile内容説明
# ベースイメージを指定
FROM ubuntu:20.04
# イメージの構築をする際、実行するコマンド
RUN apt update
RUN apt install -y ruby ruby-bundler
イメージ作成 build
- コマンド
docker build -t img-ruby:tag1 .
- コマンド解説
- docer build:dockerのビルドコマンド
- -t : TAGを指定するオプション
- img-ruby :任意のREPOSITORY名
- tag1 :任意のTAG名
- . :(とりあえず)おまじない的なもの
- 作成したイメージの確認
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
img-ruby tag1 b1e3e239a668 37 seconds ago 156MB
イメージの起動
- イメージを起動(bashも)して、rubyのバージョン確認
$ docker run -it img-ruby:tag1 bash
root@91966cec694c:/# ruby -v
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux-gnu]
ホストOSの環境とコンテナでのファイル共有(ボリューム、マウント)
- コンテナ内で作成したファイルは、コンテナを削除するとファイルも削除される
- ボリューム(マウント)機能を利用することで、ホストOS側とファイルの共有ができる
ボリュームオプション -v
-
イメージ起動時のコマンド
docker run -it -v $PWD:/work/myapp -w /work/myapp my-ruby:dockerfile bash
-
コマンド解説
- -v :ボリュームオプション
-
$PWD:/work/myapp
:
ホストの$PWD(カレントディレクトリ)をコンテナの/work/myappに紐づける - -w :コンテナ内のワークディレクトリ指定オプション
- /work/myapp :コンテナ内のワークディレクトリのパス
【補足】WSLとwindowsのファイル共有
$ cd /mnt/c/tmp
$ ls
Dockerfile
Dockerの構成イメージ
ネットワーク関連 ホストとコンテナ間
portについて
- ホストとコンテナはネットワークが分離している
- portも別々なので、ホストとコンテナのportをマッピングする必要がある
- portのマッピングは docker run実行時に-pオプションで設定する
- -pオプションについては、上記の「基本的なコマンド-runコマンド」参照
コンテナ内で立ち上げたWebServerにアクセスするまで
起動中のコンテナ内のbashに入る
docker exec -it [コンテナID] bash
ネットワーク状況を確認
- ※ssコマンドについては、インストール済み→
apt install iproute2
$ ss -antup
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 4096 127.0.0.1:4567 0.0.0.0:* users:(("ruby",pid=1,fd=5))
- "127.0.0.1:4567"について
ローカルホストのポート4567が動いている という状態
ホストからdockerプロセスの確認
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
857476638f03 rubyimg:tag1 "ruby myapp.rb" 6 seconds ago Up 5 seconds stupefied_perlman
- PORTS が空欄→ポートのマッピングがされていない
コンテナとホストのportをマッピング
- 実行中のコンテナを止める →
docker stop [コンテナID]
- -p オプションでポートをマッピング
$ docker run -v $PWD:/work/myapp -w /work/myapp -d -p 4567:4567 rubyimg:tag1 ruby myapp.rb
5383f6e79de0f368d057f6ac8131d70915b9bb47ae0b07cffc9f55eee69413a7
- 確認すると、"0.0.0.0:4567->4567/tcp"となっており、ホストの4567とコンテナの4567がマッピングされた状態となっている
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5383f6e79de0 rubyimg:tag1 "ruby myapp.rb" 13 seconds ago Up 12 seconds 0.0.0.0:4567->4567/tcp, :::4567->4567/tcp zealous_wright
コンテナに入りネットワーク情報を確認
docker exec -it [コンテナID] bash
- ネットワーク情報確認
# ss -antup
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 4096 127.0.0.1:4567 0.0.0.0:* users:(("ruby",pid=1,fd=5))
- " 127.0.0.1:4567"について
127.0.0.1はローカルホストのことだが、自分自身(コンテナ)内からの通信だけ受け付けるという意味らしい - コンテナ内からのcurlは正常終了する(curlはインストール済み)
# curl http://localhost:4567
Hello world!
自分自身(コンテナ)以外からの通信も受け付けるようにする
- 起動中のコンテナを止める
- 下記コマンドでコンテナ起動
※ここで使用しているのはsinatraで、sinatraの場合は-o 0.0.0.0
$ docker run -v $PWD:/work/myapp -w /work/myapp -d -p 4567:4567 rubyimg:tag1 ruby myapp.rb -o 0.0.0.0
コンテナに入って、ネットワーク情報を確認
$ docker exec -it b bash
# ss -antup
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 4096 0.0.0.0:4567 0.0.0.0:* users:(("ruby",pid=1,fd=5))
- Local Address:Portが「0.0.0.0:4567」となり、外からの通信も受け付けるようになった
ネットワーク関連 コンテナ間通信
- 以下の2つの方法がある
- Dockerネットワークを作成
-
--link
オプション
- --linkオプションはレガシーらしく、Dockerネットワークが推奨されているらしい
- ここではDockerネットワークの説明をする
ネットワークの作成
docker network create [ネットワーク名]
コンテナA,Bでの通信
- 以下の様に、実行時に--netオプションでネットワークを指定する。
→コンテナA,Bが、同じネットワークに属した状態となる
※ ネットワーク名:mynetで作成済みとする- コンテナA
docker run --name [コンテナ名A] <各オプション> --net mynet イメージA:タグA
- コンテナB
docker run -- name [コンテナ名B] <各オプション> --net mynet イメージB:タグB
- コンテナAからコンテナBに対しての通信の設定を行う場合、ホスト名に[コンテナ名B]を設定する。
コンテナ内から見た、ホストマシンのIPアドレスを確認する
事象(困ったこと)
- コンテナAで立ち上げたDBに、コンテナBで立ち上げたアプリケーションからlocalhostで接続できなかった。
- ローカルPCからは、コンテナAのDBにlocalhostでDB接続できていたので、コンテナBからもlocalhostで接続できると思っていた。
参考にした記事
対応方法
- コンテナ内から見た、ホストマシンのIPアドレスを確認する
- コンテナBからはホストマシンのIPアドレスで接続する
- きっと他にも良い方法があると思う
コンテナ内から見たホストマシンIPアドレスの確認方法
- コンテナ名の確認
docker ps -a
- コンテナ内に入る
docker container exec -it コンテナ名 bash
- ホストマシンIPアドレス確認
cat /etc/hosts | awk 'END{print $1}' | sed -e 's/[0-9]\+$/1/g'