1
3

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 1 year has passed since last update.

Docker のチュートリアル的なものをやってみたメモ

Last updated at Posted at 2022-05-05

以前、Docker を自力で学習しようとして挫折しました。コマンドもオプションもできることが多すぎて、どれがファーストステップなのか分かりませんでした。『仕組みと使い方がわかる Docker&Kubernetesのきほんのきほん(マイナビ出版)』を購入して、ようやくそれらしいことができるようになりました...。嬉しかったので叩いたコマンドをメモとして残します。

この記事は Docker v20.10、macOS Monterey でのハンズオンです。

Hello World

公式サイトから Docker Desktop for mac をダウンロードしてインストールします。

まずは Hello World を実行してみます。

docker run hello-world

以下のような結果が出力されれば、最初の一歩は完了です。

> Unable to find image 'hello-world:latest' locally
> latest: Pulling from library/hello-world
> 2db29710123e: Pull complete 
> ...

> 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.

仕組み

Docker は docker hub などで公開された「イメージ」を PULL(ダウンロード)してローカルに保存します。イメージには、nginx やら mysql やら node やら、ローカルインストールするような各種ソフトウェアから OS までさまざまなものが揃っています。

イメージから「コンテナ」を作り START すると各種サービスが稼働します。「ネットワーク」を使うとコンテナ同士を連携させることもできます。ローカルマシン上に小さなPCがいくつも動いているようなイメージですね。

nginx など Web サーバーを稼働させた場合は HTTP を経由して小さな PC にアクセスします。利用が終わったら STOP で電源を切り、RM で廃棄します。

runコマンド

run

コンテナを動かすには、コンテナの作成、起動、イメージのプル、のステップが必要です。

  • docker container create
  • docker container start
  • docker container pull

これらは run コマンドでまとめて実行することができます。

サンプルとしてWeb サーバーの nginx を run コマンドで稼働します。

docker run --name container01 -d -p 8080:80 nginx:1.21

--name コンテナ名を指定する。
-d バックグラウンドで実行を継続する。
-p 8080:80 ホストの 8080 番ポートをコンテナの 80 番ポートにバインドする。
nginx:1.21 バージョンを省略すると latest を指定したのと同じ。

http://localhost:8080 にアクセスすると「Welcome to nginx!」の画面が表示されます。

cpコマンド

cp

cp コマンドでホストからコンテナにファイルをコピーすることができます。

稼働させたコンテナ "container01" のインデックスページを差し替えてみます。

# サンプルとして送り込む HTML を作成
echo "<html>
  <head></head>
  <body>test</body>
</html>" >index.html
docker cp ./index.html container01:/usr/share/nginx/html/

container01:/usr/share/nginx/html/
コンテナ名:コピー先のパス
この例では nginx の公開フォルダにファイルを送り込んでいる

http://localhost:8080 をリロードするとコンテンツが「test」に変わります。

execコマンド

exec

exec コマンドを使うと稼働させたコンテナの中でコマンドを実行することができます。コマンドとしてシェルを渡すと、SSH で接続したかのようにコンテナを操作することができます。

Docker イメージは Linux ベースで作られていてそのほとんどが bash を備えているため、稼働させたコンテナ "container01" で bash を実行してみます。

docker exec -it container01 bash

-i ホストのキーボード入力をコンテナに送る。
-t ホストとコンテナのターミナルをバインドする。
正確な補足ではないので tty,pts あたりで検索すると理解が深まるかもです。

uname コマンドを叩くと Linux らしきものが動いているのが分かります。

# root@4643ee0e17a5:/
uname -a
Linux 4643ee0e17a5 5.10.104-linuxkit #1 SMP Thu Mar 17 17:08:06 UTC 2022 x86_64 GNU/Linux

ls コマンドを叩くとさきほどの cp コマンドで送り込んだファイルが格納されていることが分かります。

# root@4643ee0e17a5:/
ls -l /usr/share/nginx/html/
> -rw-r--r-- 1 root root    497 Jan 25 15:03 50x.html
> -rw-r--r-- 1  501 dialout  51 May  5 12:10 index.html

確認が終わったら exit で抜けます。

# root@4643ee0e17a5:/
exit

Dockerfile

dockerfile

イメージはプルするだけでなく、毎回ファイルコピーなどのカスタマイズを加えることが多くなりそうです。毎回実行する手順は Dockerfile というファイルにひとまとめにしておくことができます。

任意のフォルダを作成します。

mkdir image

サンプルとしてインデックスページを作成します。

echo "<html>
  <head></head>
  <body>foobar</body>
</html>" >image/index.html

Dockerfile を作成します。

touch image/Dockerfile
# ./image/Dockerfile
FROM nginx
COPY index.html /usr/share/nginx/html/

build コマンドでビルドします。

docker build -t image01 ./image/

> [+] Building 0.1s (7/7) FINISHED
> => [internal] load build definition from Dockerfile
> => => transferring dockerfile: 92B
> => [internal] load .dockerignore
...

-t image01 という名前でイメージを作成する。

イメージのリストを確認すると、新しく「image01」が追加されています。

docker image ls

> REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
> image01       latest    a7ca92fca6b5   3 seconds ago   142MB

run コマンドで実行します。

docker run --name container02 -d -p 8081:80 image01

http://localhost:8081 にアクセスして「foobar」が表示されれば成功です。

ネットワーク

network

次は 2 つのコンテナを run してネットワークで連携させてみます。
サンプルとして WordPress とデータ保存の mysql のコンテナを稼働してみましょう。

# ネットワークの作成
docker network create network01

# mysql のコンテナ
docker run \
  --name container03 \
  -dit \
  --net=network01 \
  -e MYSQL_ROOT_PASSWORD=rootpass \
  -e MYSQL_DATABASE=db1 \
  -e MYSQL_USER=user1 \
  -e MYSQL_PASSWORD=pass \
  mysql:5.7 \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci \
  --default-authentication-plugin=mysql_native_password
  
# wordpress のコンテナ
docker run \
  --name container04 \
  -dit \
  --net=network01 \
  -p 8082:80 \
  -e WORDPRESS_DB_HOST=container03 \
  -e WORDPRESS_DB_NAME=db1 \
  -e WORDPRESS_DB_USER=user1 \
  -e WORDPRESS_DB_PASSWORD=pass \
  wordpress:5.9

それぞれのコンテナは同じネットワーク「network01」上に存在し、mysql のコンテナに生成した「db1」というデータベースに wordpress のコンテナがアクセスします。

http://localhost:8082/ にアクセスすると WordPress のセットアップ画面が表示されます。任意のログイン情報を入れてセットアップすると mysql のコンテナの db1 にテーブルが作成されます。

サンプルとして cp コマンドでダンプファイルを送り込んで、exec コマンドで mysql に取り込んでみます。

# ダンプを吐き出す
mkdir db
mysqldump {ローカルのDB名} -p > ./db/restore.sql

# cp コマンドでコンテナに送り込む
docker cp ./db/restore.sql container03:/var/lib/mysql/

# mysql のコンテナでコマンドを実行
docker exec -it container03 mysql db1 -uroot -p
> Enter password
> # "rootpass" で入る

# ダンプを取り込む
mysql> source /var/lib/mysql/restore.sql

# データが取り込まれたか確認する
mysql> select user_login from wp_users;
> +------------+
> | user_login |
> +------------+
> | user1      |
> | user2      |
> +------------+

# 確認できたら抜ける
mysql> exit

docker-compose.yml

compose

イメージに対する操作手順を Dockerfile に書いたのと同じように、複数コンテナの操作手順は docker-compose.yml にひとまとめにして書くことができます。

前述の wordpress と mysql の設定は以下のように書けます。

# docker-compose.yml
version: "3"

services:
  container_mysql:
    image: mysql:5.7
    container_name: container05
    networks:
      - net000
    volumes:
      - type: bind
        source: $PWD/db
        target: /tmp/db
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: db1
      MYSQL_USER: user1
      MYSQL_PASSWORD: pass
      
  container_wordpress:
    depends_on:
      - container_mysql
    image: wordpress:5.9
    container_name: container06
    networks:
      - net000
    ports:
      - 8083:80
    environment:
      WORDPRESS_DB_HOST: container_mysql
      WORDPRESS_DB_NAME: db1
      WORDPRESS_DB_USER: user1
      WORDPRESS_DB_PASSWORD: pass
      
networks:
  net000:

docker-compose.ymlcompose up コマンドを使って一気にコンテナを稼働します。

docker compose -f ./docker-compose.yml up -d

さきほど cp コマンドで送り込んだダンプは、ボリュームをマウントしてコンテナ内に送り込むようにしました。

# docker-compose.yml の抜粋
volumes:
- type: bind
  source: $PWD/db
  target: /tmp/db

type:bind コピーでなくホストのファイルシステムを参照する。

コンテナの中に入るとダンプが送り込まれていることが確認できます。

docker exec -it container05 bash
> root@bd5bd4aeff49:/# 

ls -la /tmp/db
> drwxr-xr-x 4 mysql root    128 May  5 08:06 .
> drwxrwxrwt 1 root  root   4096 May  5 13:37 ..
> -rw-r--r-- 1 mysql root 140399 May  5 13:34 restore.sql

compose up コマンドで立ち上げたコンテナ群は compose down で停止します。

docker compose -f ./docker-compose.yml down

stop/rmコマンド

stop

現在稼働しているコンテナ群を確認してみます。

docker container ls

> CONTAINER ID   IMAGE           COMMAND                  CREATED          STATUS          PORTS                  NAMES
> 76f3edbed706   wordpress:5.9   "docker-entrypoint.s…"   12 minutes ago   Up 12 minutes   0.0.0.0:8082->80/tcp   container04
> 05edbb9b4af8   mysql:5.7       "docker-entrypoint.s…"   13 minutes ago   Up 13 minutes   3306/tcp, 33060/tcp    container03
> ed0ab41237df   image01         "/docker-entrypoint.…"   15 minutes ago   Up 15 minutes   0.0.0.0:8081->80/tcp   container02
> 2884a2cd7478   nginx:1.21      "/docker-entrypoint.…"   21 minutes ago   Up 21 minutes   0.0.0.0:8080->80/tcp   container01

run コマンドで稼働したコンテナはローカルに保存されます。たまり続けるとストレージを圧迫するので、使い終わったら stop で停止し rm で削除します。

# コンテナの停止
docker container stop container01

# コンテナの削除
docker container rm container01

同じようにイメージやネットワークも削除します。

docker image ls

> REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
> image01      latest    51b935b7a7db   41 minutes ago   142MB
> mysql        5.7       8aa4b5ffb001   7 days ago       462MB
> wordpress    5.9       b44d413c437a   2 weeks ago      606MB
> nginx        1.21      fa5269854a5e   2 weeks ago      142MB

# イメージの削除
docker image rm image01

GUI でもクリック操作で停止や削除できるため、全てをかたっぱしから消したい時はこちらのほうが楽かもしれません。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?