2
5

More than 3 years have passed since last update.

Docker① Dockerはじめました。

Last updated at Posted at 2020-03-04

師匠「環境構築にはDockerを使いましょう」
ぼく「承知っす!!!(Docker...?)」
ってことでDockerについて調べてみました。

Dockerとは

参考

Docker入門(第一回)~Dockerとは何か、何が良いのか~

要約

  • Dockerは、コンテナ型の仮想環境を配布・実行するためのプラットフォーム。

  • 仮想マシンとは違う。

    • 仮想マシン ホストマシン上でハイパーバイザを利用してゲストOSを動かす。そのうえでミドルウェアなどを動かす。
    • Docker ホストマシンのカーネルを利用して、プロセスやユーザを隔離する。従って軽量・高速。
  • ミドルウェアのインストールや各種環境設定をコード化して管理する。

    1. コード化されたファイルを共有することで、どこでも誰でも同じ環境が作れる。
    2. 作成した環境を配布しやすい。
    3. スクラップ&ビルドが容易にできる。
  • Dockerイメージは、Web上のDocker Hubで公開されている。
    Dockerイメージを取得すれば、すでに必要なミドルウェアなどがインストールされているDockerコンテナを起動できる。

感想

仮想マシンより軽快に動くらしい。確かに仮想マシンってもっさりしている印象あるよね。
「コード化して管理」ってなんか今風な感じ。
いまいちイメージわかないけど、とりあえず触ってみよう。

Dockerセットアップ、コンテナ起動

参考

Docker入門(第二回)~Dockerセットアップ、コンテナ起動~

Dockerのインストール

ハマった。
例はCentOSだけど、Linuxが好きなのでAmazon Linux2に入れようとした。

いくらやっても
sudo amazon-linux-extras install docker
これでこける。

失敗例
# sudo amazon-linux-extras install docker
Installing docker
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Cleaning repos: amzn2-core amzn2extra-docker docker-ce-stable
12 metadata files removed
6 sqlite files removed
0 metadata files removed
(略)
Resolving Dependencies
--> Running transaction check
---> Package docker.x86_64 0:18.09.9ce-2.amzn2 will be installed
--> Processing Dependency: runc = 1.0.0 for package: docker-18.09.9ce-2.amzn2.x86_64
--> Processing Dependency: containerd = 1.2.6 for package: docker-18.09.9ce-2.amzn2.x86_64
--> Processing Dependency: pigz for package: docker-18.09.9ce-2.amzn2.x86_64
--> Processing Dependency: libcgroup for package: docker-18.09.9ce-2.amzn2.x86_64
--> Running transaction check
---> Package containerd.io.x86_64 0:1.2.13-3.1.el7 will be installed
--> Processing Dependency: container-selinux >= 2:2.74 for package: containerd.io-1.2.13-3.1.el7.x86_64
---> Package libcgroup.x86_64 0:0.41-21.amzn2 will be installed
---> Package pigz.x86_64 0:2.3.4-1.amzn2.0.1 will be installed
--> Finished Dependency Resolution
Error: Package: containerd.io-1.2.13-3.1.el7.x86_64 (docker-ce-stable)
           Requires: container-selinux >= 2:2.74
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest
Installation failed. Check that you have permissions to install.

調べてみたら、こんな記事が。
そうかそうか、docker-ce.repoが邪魔だったのね。
なんでCentOSの記事をそのまま引用したんだろう、反省。

削除して、もう一回
sudo amazon-linux-extras install docker
でいけました。うんうん、知ってた知ってた。

Dockerを動かしてみる

準備

Dockerサービス起動
# systemctl start docker.service

サービスの起動確認
# systemctl status docker

Dockerの自動起動設定
# systemctl enable docker

試しにDockerコマンド実行
# docker info

この辺は特に問題なくいきました。

DockerイメージとDockerコンテナ

  • まず、Dockerイメージがある。
  • Dockerイメージをもとに、Dockerコンテナを起動する。

初期状態

イメージ一覧を表示
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

初期状態では、イメージはない。
従ってヘッダーのみが表示されている。

コンテナ一覧を表示
# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

コンテナも起動していないため、ヘッダーのみが表示されている。

hello-worldイメージを使ってコンテナを動かす

イメージ取得→起動
# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:fc6a51919cfeb2e6763f62b6d9e8815acbf7cd2e476ea353743570610737b752
Status: Downloaded newer image for hello-world:latest

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/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
イメージ一覧を表示
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              fce289e99eb9        14 months ago       1.84kB

イメージが追加されていることを確認。

コンテナ一覧を表示
# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                          PORTS               NAMES
24c4702a238c        hello-world         "/hello"            About a minute ago   Exited (0) About a minute ago                       laughing_pascal

コンテナも起動していることを確認。
「STAUS」が「Exited」になっているため、正確には停止している。
(hello-worldイメージは、MSGを出漁するだけなので停止で問題ない。)

イメージ、コンテナの削除

コンテナ削除
# docker rm <コンテナ名>
 もしくは
# docker rm <CONTAINER ID>
イメージ一覧を表示
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              fce289e99eb9        14 months ago       1.84kB

イメージは消えていない。

コンテナ一覧を表示
# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

コンテナは消えている。

イメージ削除
# docker rmi <イメージ名>
 もしくは
# docker rmi <IMAGE ID>
イメージ一覧を表示
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

イメージも消えた。

コンテナ一覧を表示
# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

もちろん、コンテナは消えている。

Nginxイメージの使用

Nginxイメージの取得
# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
68ced04f60ab: Pull complete
c4039fd85dcc: Pull complete
c16ce02d3d61: Pull complete
Digest: ***
Status: Downloaded newer image for nginx:latest

Nginxコンテナの起動
# docker run -d --name nginx-container -p 8181:80 nginx

起動オプションは以下の通り。

オプション 意味
-d バックグラウンド実行
--name <任意の名前> コンテナ名を指定
-p <ホスト側のPORT>:<コンテナ側のPORT> PORTを指定

http://<サーバのIP>:8181/
で、Nginxにアクセス可能。
(EC2の場合、セキュリティグループの設定変更が必要)

Dockerコマンドについて

参考

Docker入門(第三回)~各種dockerコマンドとDockerイメージ作成について~
Docker コマンドチートシート

各種コマンドによる操作

  • Dockerイメージ取得、イメージ一覧確認
  • コンテナ起動、コンテナ一覧確認
  • コンテナへのログイン
  • ファイルコピー(ホスト→コンテナ内)
  • ファイルコピー(コンテナ内→ホスト)
  • コンテナからDockerイメージ作成
  • コンテナ起動、停止
  • コンテナ削除

など。参考のリンク先をみれば良いので割愛。

ホスト側とのディレクトリ共有

起動時にvオプションをつけることで、ホスト側のディレクトリとコンテナ内のディレクトリを共有することが可能。
使用例としては、ログの出力先など。
例えばコンテナ内でログを出力していた場合、コンテナの停止とともに消えてしまうため。

オプション 意味
-v <ホスト側ディレクトリ>:<コンテナ側ディレクトリ> 両ディレクトリを共有にする
ディレクトリ共有した状態で起動
# docker run -it -d -p 18080:8080 -v /root/tomcat-container/logs:/share/logs --name tomcat centos:7

イメージの作成

ここまではイメージからコンテナを作ってきたが、コンテナからイメージを作ることもできる。

コンテナの停止(やらなくても作成できるみたい。停止したほうが安全?)
# docker stop nginx-container

nginx-containerコンテナから、nginx2イメージを作成
# docker commit nginx-container nginx_2

イメージを確認
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx_2             latest              4a4ce52ad449        6 seconds ago       127MB
nginx               latest              a1523e859360        6 days ago          127MB

nginx_2イメージが作成されている。
試しに作成したイメージからコンテナを起動してみる。

Nginx_2コンテナの起動
# docker run -d --name nginx2-container -p 8182:80 nginx_2

起動したコンテナの確認
# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
53e414bab96d        nginx_2             "nginx -g 'daemon of…"   41 seconds ago      Up 39 seconds       0.0.0.0:8182->80/tcp   nginx2-container
4e29184909ff        nginx               "nginx -g 'daemon of…"   29 hours ago        Up 29 minutes       0.0.0.0:8181->80/tcp   nginx-container

確認できたので止める
# docker stop nginx2-container

停止の確認
# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS                  NAMES
53e414bab96d        nginx_2             "nginx -g 'daemon of…"   2 minutes ago       Exited (0) 9 seconds ago                          nginx2-container
4e29184909ff        nginx               "nginx -g 'daemon of…"   29 hours ago        Up 31 minutes              0.0.0.0:8181->80/tcp   nginx-container

コンテナの削除
# docker rm nginx2-container

削除の確認
# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
4e29184909ff        nginx               "nginx -g 'daemon of…"   29 hours ago        Up 31 minutes       0.0.0.0:8181->80/tcp   nginx-container

Dockefileについて

参考

Docker入門(第四回)~Dockerfileについて~

Dockerfileって何?

公開されているDockerイメージに、「必要なパッケージやアプリを追加する」「各種設定をする」など少し手を加えておきたい場合に使用するもの。
Dockerfile内に、実行したい内容を記述する。

Dockerfileを使用してみる

…と思ったけど、参考記事の例はtomcatだしちょっと微妙かなと。
どうせならLaravel環境作成したりしたいなと。

そんなことを思ってたらこんなものがあった。
Dockerを使ってLaravel開発環境構築
最高っす。ドンピシャっす。
というわけで、実際に動かすのは別の機会にすることにした。

コンテナ間通信について

参考

Docker入門(第五回)〜コンテナ間通信〜

コンテナ間通信

コンテナ同士の通信をするためには、以下2通りの方法がある。
1. Dockerネットワークを作成し、コンテナ名で接続
1. --link オプションを使用して起動する

Dockerネットワークの作成

例として、Dockerネットワーク(bridgeタイプ)を作成する。
その他のタイプについてはこちら参照とのこと。

「network1」というDockerネットワークを作成
# docker network create network1

Dockerネットワークの一覧を表示
# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
064b0ea3a75c        bridge              bridge              local
7281bec71e9e        host                host                local
3585fc587596        network1            bridge              local
272c5bc211eb        none                null                local

「network1」が存在することが確認できる。
デフォルトで「bridge」も存在しているが、これはDNS設定がされておらず名前解決できないため、コンテナ名を使用したコンテナ間通信ができないらしい。

Dockerネットワークの詳細を表示
# docker network inspect network1
[
    {
        "Name": "network1",
        "Id": "3585fc587596ba17195364d8aea2e77add0978813782bfb21b15486153df109c",
        "Created": "2020-03-04T17:38:12.168101241Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
「network1」を使用したコンテナを作成
# docker run -d --name nginx3-container --network network1 -p 8183:80 nginx_2

起動したコンテナを確認
# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
20158137a4ce        nginx_2             "nginx -g 'daemon of…"   3 seconds ago       Up 1 second         0.0.0.0:8183->80/tcp   nginx3-container
1487009fb41a        nginx_2             "nginx -g 'daemon of…"   12 minutes ago      Up 12 minutes       0.0.0.0:8182->80/tcp   nginx2-container
4e29184909ff        nginx               "nginx -g 'daemon of…"   35 hours ago        Up 6 hours          0.0.0.0:8181->80/tcp   nginx-container

なおコンテナ間通信をする場合、PORT番号はコンテナ内部で使用しているPORTを指定すること。


MySQLのコンテナを以下のコマンドで作成した場合、ホスト側のPORTは19090、コンテナ内のPORTは9090となる。

# docker run --name mysql --network wordpress-network -p 19090:9090 -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.7

この場合、コンテナ間通信で指定するPORTは「9090」となる。

--linkオプションによる通信

あらかじめ、mysqlコンテナを「some-mysql」という名前で作成
# docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.7

--linkオプションを用いて「some-mysql:mysql(wordpressコンテナ内で使用しているMySQLのホスト名)」を指定
# docker run --name some-wordpress -e WORDPRESS_DB_PASSWORD=my-secret-pw --link some-mysql:mysql -d -p 8080:80 wordpress

Docker Composeについて

参考

Docker入門(第六回)〜Docker Compose〜

Docker Composeとは

Docker Composeは、複数のコンテナで構成されるアプリケーションについて、Dockerイメージのビルドや各コンテナの起動・停止などをより簡単に行えるようにするツールです。

複数のコンテナを同時に起動したり、オプションを省略できるもの(?)

Docker Composeのインストール

Dockerがインストールされている環境で以下を実行
# curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose

Docker Composeのインストールを確認
# docker-compose --version
docker-compose version 1.21.2, build a133471

docker-compose.ymlについて

Docker Composeを使用する場合、「docker-compose.yml」というファイルが必要となる。
このファイルには、以下のような情報を定義する。
- Dockerイメージをビルドするための情報(使用するDockerfile、イメージ名など)
- コンテナ起動するための情報(ホストとの共有ディレクトリ設定やポートフォワードなどの起動オプションなど)
- 使用するDockerネットワーク

mysqlとwordpressのコンテナを起動するrunコマンド

# docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.7
# docker run --name some-wordpress -e WORDPRESS_DB_PASSWORD=my-secret-pw --link some-mysql:mysql -d -p 8080:80 wordpress

これを「docker-compose.yml」に記載すると、以下の通り。

docker-compose.yml
version: '3'
services:

  wordpress:
    image: wordpress
    container_name: some-wordpress
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_PASSWORD: my-secret-pw

  mysql:
    image: mysql:5.7
    container_name: some-mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: my-secret-pw

自分で作成した(公開でない)Dockerイメージを使用する場合(例)

docker-compose.yml
version: '3'
services:
  tomcat:
    build: ./tomcat
    image: tomcat-image
    container_name: tomcat1
    ports:
      - 8081:8080
    volumes:
      - ./tomcat/share/logs:/share/logs

runコマンドのオプションと「docker-compose.yml」の記載内容を比較すると、以下の通り。

設定内容 runコマンドのオプション docker-compose.yml
コンテナ名 --name container_name
環境変数 -e environment
ポートフォワード -p ports
使用するDockerイメージ コマンドの最後 image
Dockerfileの指定 docker buildコマンド build
共有ディレクトリ -v volumes:

「--link」オプションに対応するものはないが、そもそも「docker-compose.yml」を使用した場合は自動でDockerネットワークを作成するため、自動でservice名で名前解決ができるようになっている。

「docker-compose.yml」を使用してコンテナを起動する。

# cd <docker-compose.ymlが置かれているディレクトリ>

docker-composeによる起動
# docker-compose up -d

起動の確認
# docker-commpose ps
Name                   Command               State          Ports
------------------------------------------------------------------------------
some-mysql       docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp
some-wordpress   docker-entrypoint.sh apach ...   Up      0.0.0.0:8080->80/tcp

次は、Laravel環境を構築をしてみる。

2
5
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
2
5