DamienKarrus’s blog

プログラミングとクライミングの足跡

オリジナルイメージ(2) Dockerfileの書式 Docker入門-10

Dockerfileの書式について簡単にまとめる。 書式を説明するにあたり、既存イメージのDockerfileを例にとると、 httpdのイメージのDockerfileはこのようになっている

FROM debian:bullseye-slim

ENV HTTPD_PREFIX /usr/local/apache2
ENV PATH $HTTPD_PREFIX/bin:$PATH
RUN mkdir -p "$HTTPD_PREFIX" \
    && chown www-data:www-data "$HTTPD_PREFIX"
WORKDIR $HTTPD_PREFIX

# install httpd runtime dependencies
# https://httpd.apache.org/docs/2.4/install.html#requirements
RUN set -eux; \
    apt-get update; \
    apt-get install -y --no-install-recommends \
        libaprutil1-ldap \
        libldap-common \
    ; \
    rm -rf /var/lib/apt/lists/*

ENV HTTPD_VERSION 2.4.52
ENV HTTPD_SHA256 0127f7dc497e9983e9c51474bed75e45607f2f870a7675a86dc90af6d572f5c9
ENV HTTPD_PATCHES=""

# see https://httpd.apache.org/docs/2.4/install.html#requirements
RUN set -eux; \
    \
    # mod_http2 mod_lua mod_proxy_html mod_xml2enc
    # https://anonscm.debian.org/cgit/pkg-apache/apache2.git/tree/debian/control?id=adb6f181257af28ee67af15fc49d2699a0080d4c
    savedAptMark="$(apt-mark showmanual)"; \
    apt-get update; \
    apt-get install -y --no-install-recommends \
        bzip2 \
        ca-certificates \
        dirmngr \
        dpkg-dev \
        gcc \


...(snip)...


STOPSIGNAL SIGWINCH

COPY httpd-foreground /usr/local/bin/

EXPOSE 80
CMD ["httpd-foreground"]

FROM debian:bullseye-slim
debian:bullseye-slim をベースイメージにしている

RUN mkdir ...
RUN set -eux; ...
RUN set -eux; ...
→RUNでapacheのパッケージ(ソースコード)からインストールし、パッチを当ててから make install している。

STOPSIGNAL SIGWINCH
→docker stopした場合、コンテナでCMDなどによって実行されているプロセスにSIGTERMシグナルが送信される。apacheの場合は、プロセス停止はSIGWINCHなので、docker stop後に、apacheがtimeoutするまで待つことになる。そこでここで終了シグナルを明記しておくことにより、timeoutを待たずに終了させることが出来る。

EXPOSE 80
→このパッケージはPORT80で通信するよう作られていることがわかる

CMD ["httpd-foreground"]
→docker run したときは httpd-foreground というコマンドが実行される

よく使うコマンドとしては以下の通り   

命令 説明
FROM ベースイメージを指定する
COPY ファイルやフォルダを追加する
ADD ファイルやフォルダを追加する。圧縮ファイルを指定したときは自動的に展開される(tar/tar.gz/tar.bz2/tar.xz) コピー元にURLを指定しファイルをダウンロードできる(圧縮ファイルは展開されない)
RUN イメージをビルドするときに実行する
CMD
ENTRYPOINT
コンテナを起動するときに実行する既定のコマンドを指定する
EXPOSE 通信を想定するポートの初期値を指定する
VOLUME 外部に保存するデータのマウントポイントの初期値を指定する
ENV 環境変数を定義する

COPY/ADDでは、foo/*.php などワイルドカードも指定できる。ADDは挙動が分かり辛くなるため非推奨になるかもしれない。
実行系ではRUNがイメージ作成時に実行され、CMD/ENTRIPOINTはコンテナ起動時に実行される。つまり RUNはイメージの作成に使用される。

 RUN コマンド1 && コマンド2 && コマンド3 

とする。これは、RUN1つごとに差分レイヤーが作られてしまうため、なるべく一連の動作は1つのRUNコマンドにまとめる。 ビルド完了時になんかコマンドを実行したいときは ONBUILD を使う。

 ONBUILD COPY  コピー元 コピー先
 ONBUILD RUN  コマンド 引数・・・

CMDとENTRYPOINT
docker container run の際にイメージの後に実行コマンドを指定するが、CMD は、この実行コマンドのデフォルト値を設定している。もしユーザが異なるコマンドを指定した場合は、ユーザが指定したコマンドが実行される。
一方 ENTRYPOINT によって指定された場合は、必ずここで指定されたコマンドが実行され、ユーザが docker container run した場合に指定されたものがあれば、それはここで指定されているコマンドへのパラメータとして扱われる。
書式は2種類あり、シェル形式の場合は

 CMD コマンド 引数 ・・・

exec形式の場合は

 CMD ["コマンド","引数",・・・]

いずれの書式でも指定できる(ENTRYPOINTも同様)

次の記事

damienkarrus.hatenablog.com

オリジナルイメージ(1)イメージの作成 Docker入門-9

イメージの作り方

イメージの作り方には2種類ある。

  1. コンテナから作成
    コンテナから作成する場合はベースコンテナに修正を加え、新しいイメージとしてアウトプットする。簡単ではあるが、どこにどう手を加えたかの履歴が残らない為、一般にこの方法は利用されない。
  2. Dockerfileから作成 ベースイメージに修正手順(Dockerfile)と修正ファイルを添付して、新しいイメージとしてビルドする。Dockerfileを修正することにより、イメージの修正が可能。
    イメージの作成にあたりDockerの流儀に従うこと。主に次の6点である。
    (1) 1つのコンテナは1つの処理しかしない
    1つのコンテナは1つの処理しかしない
    DBとappは分ける。ただ1つの処理といってもApachePHPは連携して動作するので分けられない。
    (2) 利用するポートを明確にする
    このイメージがどのポートを経由して外部と接続するかを明確にする(後述のEXPOSE参照)。
    (3) 永続化すべき場所を明確にする
    利用者がファイルを置く場所(マウントポイント)を明確にしておく(後述のVOLUME参照)。
    設定は環境変数で渡す
    (4) 設定を受け取るときは環境変数で受け渡しを行う。
    (5) ログは標準出力に出す
    標準出力に出しておけば利用者はdocker logsコマンドで確認できるようになる。
    (6) メインプログラムが終了してしまうとコンテナも終了する
    メインプログラムは終了せずに動き続けないといけない(後述のCMDやENTRYPOINT参照)。

    Dockerfileからイメージを作る

    ApacheのDocumentRootにindex.htmlをいれたイメージを作ってみる。
    (1)作業用ディレクトリを作り必要なファイルを準備する
$ mkdir work
$ cd work
$ cp ../index.html .

Dockerfileをつくる

$ cat Dockerfile
FROM httpd
COPY index.html /usr/local/apache2/htdocs/

ビルドする

$ docker build -t myimage01 .
    ↑ container はつけない!
Sending build context to Docker daemon  3.072kB
Step 1/2 : FROM httpd
latest: Pulling from library/httpd
Digest: sha256:b7907df5e39a98a087dec5e191e6624854844bc8d0202307428dd90b38c10140
Status: Downloaded newer image for httpd:latest
 ---> faed93b28859
Step 2/2 : COPY index.html /usr/local/apache2/htdocs/
 ---> c4aaa7d4ecb4
Successfully built c4aaa7d4ecb4
Successfully tagged myimage01:latest

できたイメージを確認する

$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
myimage01    latest    c4aaa7d4ecb4   3 minutes ago   144MB

docker history で詳細情報を確認してみる

$ docker history myimage01
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
c4aaa7d4ecb4   37 minutes ago   /bin/sh -c #(nop) COPY file:0d571419f6b9efc0…   62B

できたイメージを利用する

$ docker container run -dit --name myimage -p 8080:80 myimage01

動作確認出来たらコンテナとイメージを削除

$ docker container stop myimage
$ docker container rm myimage
$ docker image rm myimage01

次の記事

damienkarrus.hatenablog.com

複数の手続きを定義ファイルを使って実行する Docker入門-8

Docker Composeは、あらかじめコンテナの起動豊富や、ネットワークの定義、ボリュームの定義などをYAML形式で書いた手続きファイルを読み込んでを実行するしくみである。
大型計算機で使われていたJCLのコンテナ版のようなもの。
いま、Wordpressサーバを立てる手順でこのDocker Composeを使ってみる

まずはDocker Composeを使わずに立ててみる

使用するコンテナは、
 *Wordpress(httpd入り)
 *Mysql
の2個。これにDBのデータを格納するボリュームが1個
※実際にはアップロードされた情報を格納する外部記憶をVolumeかBindでアタッチする必要があるが今は上記3個とする。
手順としては
 1. 独自ネットワーク構築
 2. ボリューム作成
 3. Mysqlコンテナ作成・起動
 4. Wordpressコンテナ作成・起動

という順序で作業するものとする。

$ docker network create wordpressnet
$ docker volume create wordpress_db_volume
$ docker container run --name wordpress-db -dit --mount type=volume,src=wordpress_db_volume,dst=/var/lib/mysql -e MYSQL_ROOT_PASSWORD=myrootpassword -e MYSQL_DATABASE=wordpressdb -e MYSQL_USER=wordpressuser -e MYSQL_PASSWORD=wordpresspass --net wordpressnet mysql:5.7
$ docker container run --name wordpress-app -dit -p 8080:80 -e WORDPRESS_DB_HOST=wordpress-db -e WORDPRESS_DB_NAME=wordpressdb -e WORDPRESS_DB_USER=wordpressuser -e WORDPRESS_DB_PASSWORD=wordpresspass --net wordpressnet wordpress

動作確認方法はブラウザで上記wordpressの管理画面に入り、動作することを確認する。
ここまで確認できたら一旦削除する。

$ docker container stop wordpress-app  
$ docker container stop wordpress-db  
$ docker container rm wordpress-app  
$ docker container rm wordpress-db  
$ docker volume rm wordpress_db_volume  
$ docker network rm wordpressnet  

つぎにDocker Compose を使って実行してみる

Docker Composeのインストール

まずは Docker Compose をインストールするが、言語パッケージのpythonが必要なのでそれを最初にインストールする。

$ sudo apt install -y python3 python3-pip
$ sudo pip3 install docker-compose
↑書籍ではこのように記述されていたが、
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-c_36wcxj/cryptography/
というエラーが出たため、
$ sudo apt install docker-compose
を実行した
$ docker-compose --version
docker-compose version 1.17.1, build unknown
少し古いようだがこれ進めてみる
作業用ディレクトリと定義ファイルの作成

作業用のディレクトリを作成する

$ cd
$ mkdir wp
$ cd wp

定義ファイルを作る。ファイル名称はデフォルト値の'docker-compose.yml'とする
内容は次の通り

version: "3"

services:
  wordpress-db:
    image: mysql:5.7
    networks:
      - wordpressnet
    volumes:
      - wordpress_db_volume:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: myrootpassword
      MYSQL_DATABASE: wordpressdb
      MYSQL_USER: wordpressuser
      MYSQL_PASSWORD: wordpresspass

  wordpress-app:
    depends_on:
      - wordpress-db
    image: wordpress
    networks:
      - wordpressnet
    ports:
      - 8080:80
    restart: always
    environment:
      WORDPRESS_DB_HOST: wordpress-db
      WORDPRESS_DB_NAME: wordpressdb
      WORDPRESS_DB_USER: wordpressuser
      WORDPRESS_DB_PASSWORD: wordpresspass

networks:
  wordpressnet:

volumes:
  wordpress_db_volume:

ネストを間違えただけで構文エラーになるので注意する。ちなみにnetworks:の前にスペースをつけてネストするとエラーになる(おそらく直前のwordpress-app内の設定として理解しようとしたのだろう)
networks:の指定はなくてもよい。ない場合は、このcompose用のネットワーク(上記の場合wp_default)を作るので、上記と同等の動作をする。

docker-compose の実行

ymlファイルのあるディレクトリでdocker-composeを実行する

$ docker-compose up -d ←デタッチモード
Creating network "wp_wordpressnet" with the default driver
Creating volume "wp_wordpress_db_volume" with default driver
Creating wp_wordpress-db_1 ...
Creating wp_wordpress-db_1 ... done
Creating wp_wordpress-app_1 ...
Creating wp_wordpress-app_1 ... done

稼働状況を確認してみる

$ docker-compose ps
       Name                     Command               State                  Ports
--------------------------------------------------------------------------------------------------
wp_wordpress-app_1   docker-entrypoint.sh apach ...   Up      0.0.0.0:8080->80/tcp,:::8080->80/tcp
wp_wordpress-db_1    docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp

コンテナ名称の前に作業ディレクトリ名がつけられる。
また、末尾の1は1つめのという意味で、scaleオプションをつけた場合は2,_3が生成される。

コンテナの停止と破棄

docker-composeから起動されたコンテナやボリュームはdockerコマンドで停止や削除が出来るが、管理上の反故が生じるのでdocker-composeコマンドで操作すべきである。
上記コンテナにブラウザでアクセスしてwordpressが正常に動作することを確認したらコンテナを停止して破棄する

$ docker-compose down
Stopping wp_wordpress-app_1 ... done
Stopping wp_wordpress-db_1  ... done
Removing wp_wordpress-app_1 ... done
Removing wp_wordpress-db_1  ... done
Removing network wp_wordpressnet

ボリュームは削除されずに残っているので、次回起動時に使用することが出来る。

!!ただし、docker volume prune で消去されてしまうので要注意だ!!

$ docker volume ls
DRIVER    VOLUME NAME
local     f42f26184e4653d0210841a88de2b147e536242fe28c740dcb16dd308e308cf7
local     wp_wordpress_db_volume

何か、ワークのボリュームが残ってしまうようだ・・・

docker-composeのオプションやコマンド

docker-composeコマンドの書式は

 docker-compose オプション コマンド 引数

オプションはあまり使用することがない。引数はコマンドごとに異なる。

docker-composeのコマンド
コマンド 説明
up コンテナを作成し起動する
down コンテナ、ネットワーク、イメージ、ボリュームをまとめて停止し削除する
ps コンテナ一覧を表示する
config Composeファイルの確認と表示をする
port ポートの割り当てを表示する
logs コンテナの出力を表示する
start サービスを開始する
stop サービスを停止する
kill コンテナを強制停止する
exec コマンドを実行する
run コンテナを実行する
create サービスを生成する
restart サービスを再起動する
pause サービスを一時停止する
unpause サービスを再開する
rm 停止中のコンテナを削除する
build サービス用のイメージを構築または再起動する
pull サービス用のイメージをダウンロードする
scale サービス用のコンテナの数を指定する
events コンテナからリアルタイムにイベントを受信する
help ヘルプ

次の記事

damienkarrus.hatenablog.com

コンテナのネットワーク docker入門-7

Dockerには初期状態で3つのネットワークが用意されている

  • bridge: コンテナ生成時に特に指定がなければこのネットワークが使われる

  • host: hostマシンのIPアドレス、portをそのまま使用する。IPマスカレードはできない

  • none: ネットワークは使用しない

bridgeだと各コンテナのIPアドレスでアクセスする必要がある。 コンテナのIPアドレスを知るには docker container inspect コンテナ名 で調べられるが、createする毎に変わってしまうためコンテナ間の通信で使用するには不便である。 新たにdockerネットワークを作れば自動的にDNSサーバが立ってコンテナ名称での名前解決ができる。
dockerネットワークを作る

$ docker network create mynet

または明示的に

$ docker network create mynet --subnet 10.0.0.0/16 --gateway 10.0.0.1

とする。 生成されたネットワーク情報を見るには

$ docker network inspect mynet

...(snip)...
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.0.0.0/16",
                    "Gateway": "10.0.0.1"
                }
            ]
        },
...(snip)...

コンテナ生成時にこのmynetを指定する

$ docker container run -dit --name web01 -p 8080:80 --net mynet httpd:2.4
$ docker container run -dit --name web02 -p 8081:80 --net mynet httpd:2.4

ネットワーク接続を確認する

$ docker network inspect mynet

...(snip)...
        "Containers": {
            "08556650cbe98c6cfb623287727a0e04acdf775b40e8fc4a8749e0f969c8891e": {
                "Name": "web02",
                "EndpointID": "3fcb4b7a7d66c8f82a44e934dcf0a82bef04a96f6532c375f744b408fa360b0a",
                "MacAddress": "02:42:0a:00:00:03",
                "IPv4Address": "10.0.0.3/16",
                "IPv6Address": ""
            },
            "7fe34aceb021dcd04c7152b4b18f753ad636f5e274bbe54dbd1cc3e5b3412358": {
                "Name": "web01",
                "EndpointID": "662f2aaf210518da003c0f7696f70dcbb13f568c221a54bc40f057638282dc50",
                "MacAddress": "02:42:0a:00:00:02",
                "IPv4Address": "10.0.0.2/16",
                "IPv6Address": ""
            }
        },
...(snip)...

コンテナからの接続を確認するため第3のコンテナを作る

$ docker container run -rm -it --net mynet ubuntu /bin/bash
# apt update
# apt -y upgrade
# apt install -y iproute2 iputils-ping curl
ping で相通確認
# ping -c 4 web01
80番ポートからレスポンス受信
# curl http://web01/
同様に
# ping -c 4 web02
# curl http://web02/

DNSの確認

# cat /etc/resolv.conf
search ap-northeast-1.compute.internal
nameserver 127.0.0.11
options edns0 ndots:0

nameserverが127.0.0.11に立っている

ネットワークを削除するには

$ docker network rm mynet

次の記事

damienkarrus.hatenablog.com

ボリュームのバックアップ docker入門-6

コンテナがマウントしたボリュームに格納されたデータをバックアップする。バックアップ方法はバックアップ用コンテナからtarを発行して、マウントされたホスト側ディレクトリにtarファイルを生成する。リストアはリストア用コンテナからtarコマンドを発行して、該当するディレクトリにバックアップデータを復元する。またここではバックアップやリストアで使用するコンテナは、非常に軽いlinuxコンテナであるbusyboxを使用する。

動作検証の為、DBにあらかじめデータをインサートしておく

$ docker volume create vol01
$ docker container run -dit --name db01 --mount type=volume,src=vol01,dst=/var/lib/mysql -e MYSQL_ROOT_PASSWORD=mypassword mysql:5.7
$ docker container exec -it db01 /bin/bash
# mysql -p
mysql> create databse exampledb;
mysql> create table exampletable(id int,note char(4));
mysql> insert into exampletable(id,note)values(1,'kaki');
mysql> insert into exampletable(id,note)values(2,'taka');
\q
exit

バックアップ方法

ボリュームをバックアップするにはバックアップ作業を担当するコンテナを作り、このコンテナから該当するボリュームをバックアップする。
バックアップ対象のコンテナがどのボリュームを利用しているか分からない場合もあるので volumes-from オプションを使用して、自動的に紐付けするように指定する。

(1)必要に応じてコンテナを停止

$ docker container stop db01

(2)軽いlinuxシステム(イメージ名:busybox)を利用してtarコマンド発行

$ docker container run --rm --volumes-from db01 --mount type=bind,src="$PWD",dst=/dest busybox tar czf /dest/backup.tar.gz -C /var/lib/mysql .
・--rm : プロセス終了後コンテナ自動削除
・--volumes-from db01 : db01コンテナが利用しているボリューム(複数)を全てマウント
・--mount type=bind src="$PWD",dst=/dest : bind形式でdockerホストのカレントディレクトリをコンテナの/destにマウント
busybox : このコンテナのイメージ名はbusybox
・tar czf /dest/backup.tar.gz -C /var/lib/mysql . : /var/lib/mysqlにcd してからこのディレクトリ以下を全てtarする。バックアップファイルは/dest/backup.tr.gz
これによって、dockerホストのカレントディレクトリにbackup.tar.gzが出来る

リストア方法

(1)旧ボリュームの削除

docker volume rm vol01

(2)リストア用ボリュームの作成

docker volume create vol01

(3)tarファイル解凍

$ docker run --rm --mount type=volume,src=vol01,dst=/var/lib/mysql --mount type=bind,src="$PWD",dst=/dest busybox tar xzf /dest/backup.tar.gz -C /var/lib/mysql

(4)確認

$ docker container run -dit --name db01 --mount type=volume,src=vol01,dst=/var/lib/mysql -e MYSQL_ROOT_PASSWORD=mypassword mysql:5.7
$ docker container exec -it db01 /bin/bash
# mysql -p
mysql> use exampledb;
mysql> select * from exampletable;

これで最初に作成したレコードが2つ表示されるはずである。

 

次の記事

コンテナのネットワーク docker入門-7 - DamienKarrus’s blog (hatenablog.com)

コンテナからデータを分離させる docker入門-5

 マウント(バインドマウント)によるデータの分離

コンテナ内のデータはコンテナを破棄した時点でコンテナと共に破棄されてしまう。そこで一般的にはホスト側のリソースをマウントする。-v オプションを使用する。

-v マウント元 : マウント先

-v オプションは複数指定できるので、apacheのconfigファイルやコンテンツ本体などを

 -v aaa:bbb -v ccc:ddd -v eee:fff

などのように列記できる。マウントの対象はディレクトリだけではなく、ファイルを指定することもできる。

コンテナ起動用の runコマンドを httpd:latest などとしておけば、起動時にいつもhttpdの最新イメージで起動することもできる。

また、複数のコンテナからおなじディレクトリをマウントすることもできる。

なお、Dockerホストとコンテナ間でのcopyコマンドもある。

docker container cp コピー元 コンテナ名:コピー先

使用例

# docker container cp /tmp/index.html my-apache-app:/usr/local/apache2/htdocs/

ボリュームマウントによるデータの分離

ボリュームマウントとは、ホスト上のディレクトリではなく、Docker Engine上で確保した領域をマウントする方法である。

$ docker volume create volume01(任意のvolume名)

作成したボリュームの確認

$ docker volume ls

コンテナの起動例

$ docker container run -dit --name db01 -v volume01:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=mypassword mysql:5.7

であるが、-v オプションではボリュームが存在しない場合は自動的に作られてしまうため、意図しない結果になる場合がある。また、バインドなのかボリュームなのかも不明瞭なため、現在では mount コマンドが推奨されている。

バインド:--mount type=bind,src=マウント元パス,dst=マウント先

ボリューム:--mount type=volume,src=volume名,dst=マウント先

上記のコマンドは以下と等価である

$ docker container run -dit --name db01 --mount type=volume , src=vokume01 , dst=/var/lib/mysql -e MYSQL_ROOT_PASSWORD=mypassword mysql:5.7

 

バインドマウントとボリュームマウントの使い分け

両者に優劣があるわけではなく、使い分けが必要である。

(1)バインドのほうがよい場面

・設定ファイルをコンテナに参照させてたい場合

・ホスト側のファイル修正をリアルタイムに反映したい場合(開発中など)

(2)ボリュームのほうがよい場面

dockerホストから触る必要のない(触れてはいけない)データを保管する場合に適している。

・データベースのデータクラスタ本体など

ボリュームはデフォルトではDockerホスト上のストレージであるが、ボリュームプラグインをインストールすれば、AWSのS3やNFSを利用することもできるようになる。

(3)tmpfs マウント

データをコンテナ上にもホスト上にも保存したくない場合(大量のテンポラリデータを扱う場合)や高速に処理したい場合などはマウント元をRAMディスクにすることができる。tmpfs-size で容量を、tmpfs-mode でファイルモード0700などを指定できる。コンテナ破棄と共にデータも破棄される。

 

次の記事

ボリュームのバックアップ docker入門-6 - DamienKarrus’s blog (hatenablog.com)

 

コンテナにログインする docker入門-4

-dit オプションについて

-d デタッチ バックグラウンドで実行する

-i インタラクティブ 標準入出力をコンテナに連結する

-t ターミナル(端末)を割り当てる

デタッチ←→アタッチの切り替え方法

アタッチ状態で ctrl+P 、ctrl+Q を順に打つ

デタッチ状態で docker container attach

 

コンテナに入り込む

(1)m-apache-appが存在しない状態で

※ps -a で m-apache-app が存在しない状態で

$ docker run -it --name my-apache-app httpd:2.4 /bin/bash

コンテナがアタッチモードで起動される。

※-itオプションが最初にないとctrlキーが効かない

実行すると、プロンプトが

root@15ab6f08e163:/usr/local/apache2#

のように変化する。lsするとapache2以下のファイルが表示される

ctrl+P 、ctrl+Q を順に打つとデタッチされ、ホスト側のコマンドプロンプトが返ってくる。

$ docker container ps -a

で、コンテナが稼働中であることがわかる

再びコンテナに入る

$ docker container attach my-apache-app

※caught SIGWINCH, shutting down graceffully と出てしまうことがある。これはhttpdコンテナがデタッチ/アタッチに対してそのような仕様になっているためで、操作的な問題ではない。

(2)コンテナが稼働している状態で

コンテナをデタッチモードでコンテナを起動しておく

$ docker run  -dit --name my-apache-app -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4

execコマンドでbashを起動する

$ docker container exec -it my-apache-app /bin/bash

プロンプトが変わりコンテナに入ることができた

bashを終了する

# exit

コンテナの状態を確認すると、コンテナは稼働中であることがわかる

$ docker container ps
CONTAINER ID   IMAGE       COMMAND              CREATED          STATUS          PORTS                                   NAMES
6ee4986d3d70   httpd:2.4   "httpd-foreground"   39 minutes ago   Up 39 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp   my-apache-app

run と exec の違い

run コンテナ停止時に使用 終了時はコンテナ終了

exec コンテナ稼働時に使用 終了時もコンテナは稼働のまま

 

次の記事

コンテナからデータを分離させる docker入門-5 - DamienKarrus’s blog (hatenablog.com)