Dockerコマンド、Dockerfile・Compose file リファレンス

docker exec

コンテナ内でコマンド操作します。

例)container_nameというコンテナに対し以下コマンドを実行します。(シェルの起動)

$ docker exec -it container_name /bin/bash

コンテナ内でrootユーザによる各種コマンド操作ができます。exitコマンドで終了します。

docker-compose exec

docker-composeファイルにより各種コンテナを起動している場合には、サービス名を指定して以下コマンドでも同様の操作が可能です。

$ docker-compose exec service_name bash

docker ps

格納コンテナは以下コマンドで確認できます。

$sudo docker ps -a

以下lsコマンドによる出力結果と同じです。

$ sudo docker container ls -a

使用頻度の高いdockerコマンドメモ

  • List images:
    $ docker image ls
  • Pulling an alpine image:
    $ docker image pull alpine
  • Run a container from a locally-available image:
    $ docker container run -it alpine sh
  • Run a container in the background ( -d option) from an image:
    $ docker container run -d nginx
  • List only running containers:
    $ docker container ls
  • List all containers:
    $ docker container ls -a
  • Inject a process inside a running container:
    $ docker container exec -it <container_id/name> bash
  • Stop a container:
    $ docker container stop <container id/name>
  • Delete a container:
    $ docker container rm <container id/name>
  • 不要なボリューム削除
    $ docker volume prune --all
  • 不要なビルドキャッシュの削除
    $ docker builder prune --all
  • キャッシュを無効にしてビルド
    $ docker compose build --no-cache

不要なdocker imageの削除

リストアップ(タグの無い<none>イメージファイルのリストアップ
イメージ作成時にタグ付しないと不要なイメージとしてリストアップされるので注意)

$ docker images -f dangling=true -q

上記<none>タグのイメージ削除

$ docker rmi $(sudo docker images -f dangling=true -q)

または

$ docker image prune

注)docker rmi を実行してもディスクスペースが増えないのは、Docker が使用している仮想ディスクが拡張は自動的に行うが縮小は行われないためです。Docker イメージやコンテナのデータを削除しても、使われていたディスクスペースは空の状態で確保されたままとなっています。

ディスクスペースを開放するために、追加で下記コマンドを実行します。

全イメージが削除されます。

$ docker system prune -a

全コンテナの停止・削除

コンテナリスト

$ docker ps -a

全コンテナ停止・削除

$ docker stop $(docker ps -a -q)
$ docker rm $(docker ps -a -q)

停止中のコンテナ一覧

$ docker ps -f “status=exited”

イメージを削除する場合、事前にコンテナを削除する必要が有ります。

Docker pullコマンド:イメージのダウンロード・アップデート

tagを指定しないとタグlatestがダウンロードされます。
(latestでタグ付けされていないイメージの場合エラーとなります)

ex)

$ docker pull divante/pimcore5-php:php-7.3-base

イメージのアップデート

既存イメージのアップデートもpullコマンドで行います。
(既存コンテナを削除、アップデート後コンテナを再構築)

最新バージョン(tag:latest)へのアップデート・変更

$ docker pull divante/pimcore5-php

Tag指定バージョンのアップデート

$ docker pull divante/pimcore5-php:php-7.3-base

docker pull コマンドによりアップデートされた旧イメージは、tag<none>表記になり、イメージIDを指定しても削除できない場合があります。

この場合、イメージダイジェストを下記コマンドで確認後、このダイジェストを指定して削除します。

$ docker images --digests
REPOSITORY    TAG         DIGEST                                                                    IMAGE ID       CREATED         SIZE
nginx        <none>      sha256:763e7f0188e378fef0c761854552c70bbd817555dc4de029681a2e972e25e30e   89ec9da68213   8 months ago    19.9MB

<none>タグイメージの削除

$ docker rmi nginx@sha256:763e7f0188e378fef0c761854552c70bbd817555dc4de029681a2e972e25e30e   89ec9da68213  
Untagged: nginx@sha256:763e7f0188e378fef0c761854552c70bbd817555dc4de029681a2e972e25e30e

Docker runコマンド

オプションとしてコンテナ名、ポートなどを指定します。

Dockerコンテナへのファイルコピー

ローカル端末から稼働コンテナへのウェブコンテンツコピーやコンテナ内ファイルのコピーなどに使用。

ファイルコピー(ローカルファイル<—>コンテナ)

$ docker cp foo.txt mycontainer:/foo.txt
$ docker cp mycontainer:/foo.txt foo.txt

マルチファイルコピー(ローカルファイル<—>コンテナ)

$ docker cp src/. mycontainer:/target
$ docker cp mycontainer:/src/. target

Docker Compose

複数コンテナ同時起動

ex) docker-compose.ymlファイルを作成し、以下コマンドでコンテナ起動

version: '3.3'
services:
  freepbx:
    image: flaviostutz/freepbx:14.0
    network_mode: host
    restart: always
    volumes:
      - freepbx-backup:/backup
      - freepbx-recordings:/var/spool/asterisk/monitor

volumes:
  freepbx-backup:
  freepbx-recordings:

上記ファイルで定義したコンテナを同時起動(バックグラウンド)

$ docker-compose up -d

稼働コンテナの確認

$ docker-compose ps

停止コマンド

$ docker-compose stop

Docker-Composeファイルの内容を変更した場合

再度以下コマンドを実行して変更内容を反映させます。(各コンテナは稼働したままでOKです)

$ docker-compose up -d

この場合、変更箇所のサービスコンテナのみが初期化されます。
このため上記サービスコンテナにおいて変更前に追加・修正した設定・ファイルは全て初期化・削除されます。

Docker Commit

コンテナ内でアップデート、ファイルの追加・変更などをした内容を引継ぎ新たなイメージファイルを作成。

$ docker commit -m "What you did to the image" -a "Author Name" container_id repository/new_image_name

-m:メッセージオプション、-a:作成者

$ docker commit -m "apt updated" -a "Takanobu Fuse" fdg768888 takanobu/ubuntu:updated

コンテナログ確認

$ docker logs [OPTIONS] CONTAINER
$ docker compose logs [OPTIONS] [SERVICE...]

Dockerコンテナ設定変更(アップデート)

Dockerコンテナの自動起動変更

Flag Description
no Do not automatically restart the container. (the default)
on-failure[:max-retries] Restart the container if it exits due to an error, which manifests as a non-zero exit code. Optionally, limit the number of times the Docker daemon attempts to restart the container using the :max-retries option.
always Always restart the container if it stops. If it is manually stopped, it is restarted only when Docker daemon restarts or the container itself is manually restarted. (See the second bullet listed in restart policy details)
unless-stopped Similar to always, except that when the container is stopped (manually or otherwise), it is not restarted even after Docker daemon restarts.

ホストマシン再起動後起動しない場合

$ docker update --restart no CONTAINER_NAME(or ID)

ホストマシン再起動後も起動する場合

$ docker run -d --restart unless-stopped redis

既に起動しているコンテナの設定を ”ホストマシン再起動後も起動する”に変更 する場合

$ docker update --restart unless-stopped redis

全てのコンテナに上記変更内容を適用する場合

$ docker update --restart unless-stopped $(docker ps -q)

Docker Volume

ホストとコンテナ間でファイルを共有する際に設定します。ホスト側でボリューム名のみ指定した場合は、/var/lib/docker/volumesに指定したボリューム名のフォルダが作成されます。

ex1) ホスト側shared, vhost, htmlフォルダは/var/lib/docker/volumesに作成されます。

注) コンテナ側のディレクトリの内容がホスト側に反映されます。コンテナ内のディレクトリをホスト側で参照したい場合には、こちらを利用します。

    volumes:
      - shared:/etc/nginx/certs
      - vhost:/etc/nginx/vhost.d
      - html:/usr/share/nginx/html

ex2) ホスト側shared, vhost, htmlフォルダは指定ディレクトリに作成されます。

注) ホスト側に指定デイレクトリが存在しない場合、ホスト側に新たに新規ディレクトリが作成され、コンテナ内の指定ディレクトリにマウントされます。このためコンテナ側のディレクトリの中身が空になります。

    volumes:
      - ./shared:/etc/nginx/certs
      - ./vhost:/etc/nginx/vhost.d
      - ~/html:/usr/share/nginx/html
$ docker volume help

Usage:	docker volume COMMAND

Manage volumes

Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes

Run 'docker volume COMMAND --help' for more information on a command.

不要なVolumeの削除

$ docker volume prune --all

Docker-Compose 外部ボリューム

composeによるコンテナ外のVolumeを参照する場合、予めdockerコマンドによりボリュームを作成。

$ docker volume create data

docker-composeファイルで外部ボリューム “data” を指定(external)

version: "3.7"

services:
  db:
    image: postgres
    volumes:
      - data:/var/lib/postgresql/data

volumes:
  data:
    external: true

ボリューム名による指定(external)

volumes:
  data:
    external:
      name: actual-name-of-volume

ホストーコンテナ間のボリューム相関関係

単一ディレクトリを指定した場合、コンテナが指定ディレクトリを作成。
その他、ホスト側の絶対パス、相対パス、外部ボリューム名などを表します。

volumes:
  # Just specify a path and let the Engine create a volume
  - /var/lib/mysql

  # Specify an absolute path mapping
  - /opt/data:/var/lib/mysql

  # Path on the host, relative to the Compose file
  - ./cache:/tmp/cache

  # User-relative path
  - ~/configs:/etc/configs/:ro

  # Named volume
  - datavolume:/var/lib/mysql

Dockerfile portオプション:-p(publish)とexposeの違い

-p(publish):

ホストとコンテナ間のポートを定義。 ex) ホストポート:コンテナポート —> 80:8080
dockerネットワーク外部からホストのポートを経由してコンテナにアクセス可。
このオプションは以下のexposeオプションを包括。

expose:

コンテナのポートを定義。dockerネットワーク内でのみポートを指定してアクセス可。

Docker-Compose file “expose”, “ports”

expose

ports

稼働コンテナのネットワークの確認

$ docker inspect CONTAINER_NAME

ports: ホストマシンとコンテナのポートがマッピングされている場合

"Ports": {
                "443/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "443"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "443"
                    }
                ],
                "80/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "80"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "80"
                    }
                ]
            },

expose: Dockerネットワーク内のみでポート開放している場合

"Ports": {
                "6379/tcp": null
            },

Docker Networks: DockerコンテナへのIPアドレスのアサイン

subnetを指定してdockerネットワークを作成後、IPアドレスをアサインしてコンテナを起動

docker network create --subnet=172.18.0.0/16 mynet123

--ip オプションでIPアドレスを指定してコンテナを起動

docker run --net mynet123 --ip 172.18.0.22 -it ubuntu bash

Docker-Composeファイルで指定する場合

version: "3.7"

services:
  app:
    image: nginx:alpine
    networks:
      app_net:
        ipv4_address: 172.16.238.10
        ipv6_address: 2001:3984:3989::10

networks:
  app_net:
    ipam:
      driver: default
      config:
        - subnet: "172.16.238.0/24"
        - subnet: "2001:3984:3989::/64"

ipam(IP Address Manager)により、ネットワークモード、サブネットマスク等を指定

ネットワーク設定リファレンス

その他の設定オプションについては、上記同ページの以下参照のこと。

Compose file: depends_on

ex) depend_onで指定したサービスdb,redisを起動後、webサービスを開始。

version: "3.7"
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

Docker-Compose Build

DockerfileによりDocker Hub: https://hub.docker.com/ 等から提供されているイメージを元にカスタムイメージを作成できますが、Docker-Composeファイル内でもこの作業が行えます。

version: "3.7"
services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternate
      args:
        buildno: 1
    image: webapp:tag

webapp —> イメージ名
context —> Dockerfileディレクトリ:./dir
dockerfile —> Dockerfile-alternate
args —> ビルド時のみ使用される環境変数
image —> イメージ名:タグ


Docker Composeファイルでビルドしたイメージを再ビルドする場合、イメージ作成過程の各プロセスでキャッシュされたボリュームが再利用されます。このキャッシュボリュームを利用したくない場合は --no-cache オプションを付与して再ビルドします。

$ docker compose --no-cache build SERVICE

ビルドキャッシュの削除

$ docker builder prune --all

Dockerfile RUN CMD ENTRYPOINT

RUN

以下shellとexecの2種類のフォームで記述します。イメージに新たなパッケージを追加する際等に使用します。

  • RUN <command> ( shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
    /bin/shシェルにより各コマンドが実行される。一連のコマンドを実行した場合、次のコマンドに変数などが引き継がれる。

  • RUN ["executable", "param1", "param2"] ( exec form)
    シェル無しでコマンドを直接実行。/bin/bashを使用する場合もこのフォームを使用する。

RUNインストラクション

以下apt-get update と apt-get install はセットで記述すること。別々に記述するとupdateのキャッシュされた古いデータからパッケージがアップデートされるため。

RUN apt-get update && apt-get install -y \
    package-bar \
    package-baz \
    package-foo

CMD

以下RUNと同様なexecとshellフォームに加え、ENTRYPOINTのパラメータとしてのフォームがあります。Dockerコンテナ内で実行されるデフォルトのコマンドを指定。複数のCMDを指定した場合、最後のCMDのみ有効。

  • CMD ["executable","param1","param2"] ( exec form, this is the preferred form)
  • CMD ["param1","param2"] (as default parameters to ENTRYPOINT )
  • CMD command param1 param2 ( shell form)

ENTRYPOINT

RUNと同様、以下のexecまたはshellフォームで記述します。コンテナ起動時に必ず実行されるコマンドで、ENTRYPOINTに続けてCMDを指定すると、CMDがENTRYPOINTの引数になります。

  • ENTRYPOINT ["executable", "param1", "param2"] ( exec form, preferred)
  • ENTRYPOINT command param1 param2 ( shell form)

Understand how CMD and ENTRYPOINT interact

Both CMD and ENTRYPOINT instructions define what command gets executed when running a container. There are few rules that describe their co-operation.

  1. Dockerfile should specify at least one of CMD or ENTRYPOINT commands.
  2. ENTRYPOINT should be defined when using the container as an executable.
  3. CMD should be used as a way of defining default arguments for an ENTRYPOINT command or for executing an ad-hoc command in a container.
  4. CMD will be overridden when running the container with alternative arguments.

The table below shows what command is executed for different ENTRYPOINT / CMD combinations:

No ENTRYPOINT ENTRYPOINT exec_entry p1_entry ENTRYPOINT [“exec_entry”, “p1_entry”]
No CMD error, not allowed /bin/sh -c exec_entry p1_entry exec_entry p1_entry
CMD [“exec_cmd”, “p1_cmd”] exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry exec_cmd p1_cmd
CMD [“p1_cmd”, “p2_cmd”] p1_cmd p2_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry p1_cmd p2_cmd
CMD exec_cmd p1_cmd /bin/sh -c exec_cmd p1_cmd /bin/sh -c exec_entry p1_entry exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd

CMDとENTRYPOINTの違い

一つのコンテナ内でマルチサービスを実行

If you have one main process that needs to start first and stay running but you temporarily need to run some other processes (perhaps to interact with the main process) then you can use bash’s job control to facilitate that. First, the wrapper script:

#!/bin/bash
  
# turn on bash's job control
set -m
  
# Start the primary process and put it in the background
./my_main_process &
  
# Start the helper process
./my_helper_process
  
# the my_helper_process might need to know how to wait on the
# primary process to start before it does its work and returns
  
  
# now we bring the primary process back into the foreground
# and leave it there
fg %1

Dockerfile COPY

host_folderの中身を全てdocker_folder/sub_folderにコピーする場合(host_folder/*としない)

COPY host_folder/ /docker_folder/sub_folder/

Dockerfile ADD or COPY

Compose file: command

bash -c によるマルチコマンド実行例

command: bash -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"

適用例)

DockerHub Mariadbの文字コードをcommandで指定

https://hub.docker.com/_/mariadb?tab=description

デフォルトではlatin1に設定されるため、事前にutf8mb4を指定。

command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci']

Docker CLI: docker image inspect/docker inspect

Dockerイメージの詳細表示

Dockerコンテナの詳細表示