Docker入門

Dockerの開発環境をローカル環境に構築する手順や、 Docker を使ったプログラムの記述方法や実行までをサンプルを使いながら順に学習していきます。

MongoDBをdocker-composeで起動する

MongoDBとは

OSSなドキュメントデータベースのこと。 json形式でデータを保存することができる。

実行方法

ソースコード取得

git clone https://github.com/new-awesomedocker/MongoDB.git

移動

cd MongoDB

コンテナ起動

docker-compose up -d

コンテナ内部に入る。

docker exec -it mongo bash

mongoshの起動確認→完了

mongosh

dockerのためのcgroup入門

cgroups概要

cgroupはリソースごとにコントローラーが存在し、コントローラーはcgroupfsという特別なファイルシステムを介して使います。 このファイルシステムは、ストレージデバイス上に存在するわけではなく、メモリ上にだけ存在します。

Ubuntu20.04では /sys/fs/cgroup ディレクトリ以下に、各コントローラーに対応するcgroupファイルシステムがマウントされています。

cgroupsは、Linuxカーネルの一部として提供されており、コマンドラインツール(通常は「cgroup-tools」パッケージに含まれています)やAPIを介して操作することができます。

cgroupsはファイルとして扱う

cgroupfsという名前の仮想ファイルシステムにディレクトリーを作成することにより、システム上の cgroup 階層を管理できます。

デフォルトのパスは/sys/fs/cgroup/です。

from https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/9/html/managing_monitoring_and_updating_the_kernel/assembly_using-cgroupfs-to-manually-manage-cgroups_managing-monitoring-and-updating-the-kernel

新規プロセスを作ってみる

次のように、cgroup配下にフォルダーを作成することで新規プロセスを作成することができます。

mkdir /sys/fs/cgroup/Example/

/sys/fs/cgroup/Example/ ディレクトリーには、memory および pids コントローラー用のコントローラー固有のファイルも含まれます。

これらのファイルは、linux kernelに含まれる、cgroupsによって自動的に作成されたものです。

cat /sys/fs/cgroup/cgroup.controllers

実際にlinux環境下で上記のコマンドを打つとプロセスが見えると思います。

cgroup
cgroup

ブラウザを開いてcgroupsを見てみる。

1.まずはブラウザを開き、ターミナルでtopコマンドを入力します。

top

cgroup process確認
cgroup process確認

この時に開いたブラウザのPIDをtopで確認しましょう。 今回だと、PID:2331ですね。

2.PIDをメモしたらqを押してtopコマンドを終了します。

3./proc配下にあるプロセスを確認しょう。

cat /proc/2331/cgroup

プロセスが属する cgroup を表示するには、cat proc/<PID>/cgroup コマンドを実行します。

4./sys/fs/cgroup配下を調べる

先ほど調べた結果を、/sys/fs/cgroup配下で調べましょう。

プロセスに関する情報が記述されてますね!

Dockerエラー Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "bash": executable file not found in $PATH: unknown

docker-compose run go bash
Error response from daemon: failed to create shim task: OCI runtime create failed: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "bash": executable file not found in $PATH: unknown

対応:bashではなくsh

docker-compose run go sh

Dockerイメージをファイルとして保存する方法

ビルドしたDockerイメージを圧縮ファイルとして配りたい場合。

解決策:docker exportコマンドを使用する

まずはdocker psでコンテナの一覧を取得する

docker ps -a
CONTAINER ID IMAGE COMMAND CREATED ... NAMES
77d9619a7a71 ubuntu:14.04 "/bin/bash" 10 seconds ago ... high_shockley

ここで、CONTAINER IDが 77d9619a7a71 のコンテナのイメージを圧縮ファイルとして保存、共有したい場合。

次のようにdocker exportコマンドを使用する。

docker export 77d9619a7a71 > update.tar

exportされた圧縮ファイルは、docker importでコンテナイメージを読み込む素材として使える。

docker import - update < update.tar

別解:docker saveコマンドを使用する

docker saveコマンドでもDockerイメージを圧縮ファイルとして保存することができる。

docker save [オプション] <イメージ名>[:<タグ>] -o <アーカイブファイル名>

例えば、myimage:latestの最新のDockerイメージを保存しておきたい場合。

docker save myimage:latest -o myimage.tar

このようなコマンドを入力することで、myimage.tarファイルが作成されます。

圧縮されたファイルを再度読み込むにはdocker loadコマンドを使用します。

docker load < myimage.tar

起動したコンテナとローカルPCでファイル送信をする【Docker】

解決策:

dockercpコマンドを使用することでコンテナとローカルPC間でファイルのコピーが可能です。

構文は以下の通り。

docker cp <ローカルファイルパス> <コンテナ名またはID>:<コンテナ内のディレクトリパス>

または、docker-composeでも同様の操作が可能

docker-compose cp <サービス名>:<ローカルファイルパス> <コンテナ内のディレクトリパス>

具体例:ubuntuコンテナで実践

コンテナ内部のファイルをローカルPCにコピー

次のコマンドでubuntuを360秒間だけ立ち上げ、bashでログインします。

docker run -d --name testcopy ubuntu:14.04 sleep 360
docker exec -it testcopy bash

コンテナ内部では次のコマンドを入力して、I am in the containerと書かれたfile.txtファイルを作成し、exitでコンテナを抜けます。

cd /root
echo 'I am in the container' > file.txt
exit

ここで作成したファイルをローカルにコピーしましょう。

docker cp testcopy:/root/file.txt .

このdocker cpコマンドでコンテナ名かコンテナIDとローカルファイルパスを指定することでコピーが可能です。

cat file.txt

実行結果

I am in the container

ローカルPCのファイルをコンテナ内部へコピー

反対に、ローカルPCのファイルをコンテナ内部へコピーする場合は先にファイル名を記述しましょう

echo 'I am in the host' > host.txt
docker cp host.txt testcopy:/root/host.txt

docker runでコンテナ名に名前を付け、ログを取得する

docker runでコンテナ名を付ける方法

コンテナ名を付けるには--nameオプションを使用します。

docker run -p 80:80 --name mynginx -d nginx 

この場合、-dオプションでデタッチモードでnginxを起動しています。

そのため、--nameオプションでmynginxという名前を与えてます。

与えた名前を指定してログを出力することも可能です。

docker logs mynginx

実行ログ

コマンド

docker run -p 80:80 --name mynginx -d nginx 

ログ確認コマンド

docker logs mynginx

実行

/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2023/06/04 02:58:15 [notice] 1#1: using the "epoll" event method
2023/06/04 02:58:15 [notice] 1#1: nginx/1.25.0
2023/06/04 02:58:15 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2023/06/04 02:58:15 [notice] 1#1: OS: Linux 5.15.90.1-microsoft-standard-WSL2
2023/06/04 02:58:15 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023/06/04 02:58:15 [notice] 1#1: start worker processes
2023/06/04 02:58:15 [notice] 1#1: start worker process 29
2023/06/04 02:58:15 [notice] 1#1: start worker process 30
2023/06/04 02:58:15 [notice] 1#1: start worker process 31
2023/06/04 02:58:15 [notice] 1#1: start worker process 32
2023/06/04 02:58:15 [notice] 1#1: start worker process 33
2023/06/04 02:58:15 [notice] 1#1: start worker process 34
2023/06/04 02:58:15 [notice] 1#1: start worker process 35
2023/06/04 02:58:15 [notice] 1#1: start worker process 36
2023/06/04 02:58:15 [notice] 1#1: start worker process 37
2023/06/04 02:58:15 [notice] 1#1: start worker process 38
2023/06/04 02:58:15 [notice] 1#1: start worker process 39
2023/06/04 02:58:15 [notice] 1#1: start worker process 40
2023/06/04 02:58:15 [notice] 1#1: start worker process 41
2023/06/04 02:58:15 [notice] 1#1: start worker process 42
2023/06/04 02:58:15 [notice] 1#1: start worker process 43
2023/06/04 02:58:15 [notice] 1#1: start worker process 44
2023/06/04 02:58:15 [notice] 1#1: start worker process 45
2023/06/04 02:58:15 [notice] 1#1: start worker process 46
2023/06/04 02:58:15 [notice] 1#1: start worker process 47
2023/06/04 02:58:15 [notice] 1#1: start worker process 48

docker runのdオプションの使い方と使いどころ

docker run-d オプションは、コンテナをデタッチモード(バックグラウンドで実行)で起動するためのオプションです。 通常、docker run コマンドを実行すると、コンテナはアタッチモードで起動し、コンテナの標準出力をターミナルに表示します。しかし、-d オプションを使用すると、コンテナはバックグラウンドで実行され、コンテナの標準出力は表示されません。

以下に例を示します:

docker run -d nginx

上記のコマンドは、Docker HubからNGINXイメージを取得し、それをバックグラウンドで実行します。コンテナはデタッチモードで起動されるため、コンテナのログは表示されず、コマンドプロンプトがすぐに利用可能になります。

デタッチモードで実行したコンテナのログを表示するには、docker logs コマンドを使用します。以下に例を示します:

docker logs <container_id>

上記のコマンドで <container_id> は、実際のコンテナのIDに置き換える必要があります。

コンテナ名に名前を付ける

docker.hatenablog.jp