Docker入門
こんにちは!
今回は、Dockerについて学習をしたので記録として残します。
どなたかの参考になれば幸いです。
Dockerとは何か?
Dockerは開発者とシステム管理者が開発のために使用するプラットフォームである。コンテナ化されたアプリケーションをデプロイして実行をする。
コンテナは、アプリケーションの実行に必要なものすべてをカプセル化する実行中のプロセスである。このようにDockerを利用すると、異なる環境でも簡単に移動や実行を行うことができる。
Dockerイメージとは
イメージは、必要なすべてのものが含まれる、スタンドアロンで独立した軽量の実行可能なパッケージである。(コード、ランタイム、ツール、ライブラリ、設定など)
イメージは実行するアプリケーションであり、コンテナはイメージのランタイムインスタンスである。同じイメージから、さらに多くのコンテナを起動することができる。多くのアプリケーションイメージは、Docker hubで公開されているため、プリインストールされた様々なアプリケーション環境を素早く実行することが可能(WebサーバやDBサーバなど)
Dockerのインストール
今回は、DockerとDocker composeのインストールをAmazon Linux2上にインストールを行います。
EC2上にAmazon Linux2のインスタンスを立ち上げてDockerのインストールを行います。
sudo dnf -y install docker
sudo DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
sudo mkdir -p $DOCKER_CONFIG/usr/local/lib/docker/cli-plugins
#v2.24.7 2024/3/12時点の最新
sudo curl -SL https://github.com/docker/compose/releases/download/v2.4.1/docker-compose-linux-x86_64 -o $DOCKER_CONFIG//usr/local/lib/docker/cli-plugins/docker-compose
#実行バイナリに対して実行権限を与えます。
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
#dockerを起動
sudo systemctl start docker
sudo systemctl enable docker
#インストール結果をテストします。
sudo docker compose version
sudo docker version
Dockerの主要なコマンド
sudo docker info
システム上でのdockerの状態を確認
sudo docker help
docker ヘルプ情報の参照
sudo docker container help
docker container ヘルプ情報の確認
sudo docker container ls
実行中のコンテナとdockerイメージをリストする
sudo docker image ls
利用可能なイメージのリスト
sudo docker container run hello-world
or
sudo docker run hello-world
is the oldest command
Docker hubとの通信を含む、Dockerインストール全体をテストするには、docker containerを実行します。このコマンドを実行すると、ローカルでイメージを探し、ない場合は、Docker hubから検索してイメージをダウンロードする。
一度イメージをローカルに保存した場合は、ローカルを参照するため、docker hubからはプルは行わない。イメージが既に存在しているというメッセージが表示される。
docker search [image-name]
docker CLIを使用してイメージを検索する
例として、nginxのイメージを検索
[yunisan1211@ip-x.x.x.x ~]$ sudo docker search nginx
NAME DESCRIPTION STARS OFFICIAL
nginx Official build of Nginx. 19686 [OK]
unit Official build of NGINX Unit: Universal Web … 25 [OK]
nginx/nginx-ingress NGINX and NGINX Plus Ingress Controllers fo… 88
nginxinc/nginx-unprivileged Unprivileged NGINX Dockerfiles 143
nginx/nginx-prometheus-exporter NGINX Prometheus Exporter for NGINX and NGIN… 38
nginxinc/nginx-s3-gateway Authenticating and caching gateway based on … 6
nginx/unit This repository is retired, use the Docker o… 64
nginx/nginx-ingress-operator NGINX Ingress Operator for NGINX and NGINX P… 2
nginxinc/amplify-agent NGINX Amplify Agent docker repository 1
nginx/nginx-quic-qns NGINX QUIC interop 1
nginxinc/ingress-demo Ingress Demo 4
nginxproxy/nginx-proxy Automated nginx proxy for Docker containers … 132
nginxproxy/acme-companion Automated ACME SSL certificate generation fo… 130
bitnami/nginx Bitnami nginx Docker Image 183
bitnami/nginx-ingress-controller Bitnami Docker Image for NGINX Ingress Contr… 32
ubuntu/nginx Nginx, a high-performance reverse proxy & we… 112
nginxinc/nginmesh_proxy_debug 0
nginxproxy/docker-gen Generate files from docker container meta-da… 16
nginxinc/mra-fakes3 0
kasmweb/nginx An Nginx image based off nginx:alpine and in… 7
nginxinc/nginmesh_proxy_init 0
rancher/nginx-ingress-controller 12
nginxinc/mra_python_base 0
nginxinc/ngx-rust-tool 0
docker image pull redis:5.0.10
dockerではタグをつけることができ、タグによって、特定のバージョンのソフトウェアをダウンロードするなどといったことが可能。
docker image pull redis
タグをつけない場合は、最新の安定バージョンがダウンロードされる
docker container run redis
イメージからコンテナを実行し起動する
なお、ローカルにイメージがない場合は、Docker hubからダウンロードして実行しようとする。
例として、nginxのイメージがローカル上にある場合
redisのイメージがローカル上にない場合のdocker container runの挙動をしたに貼り付けています。
[yunisan1211@ip-x.x.x.x ~]$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest e4720093a3c1 3 weeks ago 187MB
httpd latest 2776f4da9d55 7 weeks ago 167MB
[yunisan1211@ip-x.x.x.x ~]$ sudo docker run nginx
/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: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/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
2024/03/11 18:25:08 [notice] 1#1: using the "epoll" event method
2024/03/11 18:25:08 [notice] 1#1: nginx/1.25.4
2024/03/11 18:25:08 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2024/03/11 18:25:08 [notice] 1#1: OS: Linux 6.1.77-99.164.amzn2023.x86_64
2024/03/11 18:25:08 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 32768:65536
2024/03/11 18:25:08 [notice] 1#1: start worker processes
2024/03/11 18:25:08 [notice] 1#1: start worker process 29
^C2024/03/11 18:25:13 [notice] 1#1: signal 2 (SIGINT) received, exiting
2024/03/11 18:25:13 [notice] 29#29: exiting
2024/03/11 18:25:13 [notice] 29#29: exit
2024/03/11 18:25:13 [notice] 1#1: signal 17 (SIGCHLD) received from 29
2024/03/11 18:25:13 [notice] 1#1: worker process 29 exited with code 0
2024/03/11 18:25:13 [notice] 1#1: exit
[yunisan1211@ip-x.x.x.x ~]$ sudo docker container run redis
Unable to find image 'redis:latest' locally
latest: Pulling from library/redis
e1caac4eb9d2: Already exists
7469c6c5b625: Pull complete
a3d1b68c4a62: Pull complete
152cbe749752: Pull complete
7218480dfba1: Pull complete
e61c48a0d344: Pull complete
4f4fb700ef54: Pull complete
82adb0efabd8: Pull complete
Digest: sha256:e647cfe134bf5e8e74e620f66346f93418acfc240b71dd85640325cb7cd01402
Status: Downloaded newer image for redis:latest
1:C 11 Mar 2024 18:25:26.783 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see https://github.com/jemalloc/jemalloc/issues/1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
1:C 11 Mar 2024 18:25:26.783 # WARNING Your system is configured to use the 'xen' clocksource which might lead to degraded performance. Check the result of the [slow-clocksource] system check: run 'redis-server --check-system' to check if the system's clocksource isn't degrading performance.
1:C 11 Mar 2024 18:25:26.783 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 11 Mar 2024 18:25:26.784 * Redis version=7.2.4, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 11 Mar 2024 18:25:26.784 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
1:M 11 Mar 2024 18:25:26.785 * monotonic clock: POSIX clock_gettime
1:M 11 Mar 2024 18:25:26.785 * Running mode=standalone, port=6379.
1:M 11 Mar 2024 18:25:26.786 * Server initialized
1:M 11 Mar 2024 18:25:26.786 * Ready to accept connections tcp
^C1:signal-handler (1710181529) Received SIGINT scheduling shutdown...
1:M 11 Mar 2024 18:25:29.698 * User requested shutdown...
1:M 11 Mar 2024 18:25:29.698 * Saving the final RDB snapshot before exiting.
1:M 11 Mar 2024 18:25:29.702 * DB saved on disk
1:M 11 Mar 2024 18:25:29.703 # Redis is now ready to exit, bye bye...
dockerでnginxサーバを立ち上げて、ローカルマシン上で確認してみる
nginxの起動
sudo docker container run -d --rm --name nginx nginx
ポートを指定して起動する場合
sudo docker container run -p 8080:80 -d --rm --name nginx nginx
作成・起動・停止
#dockerコンテナ作成
sudo docker container create -p 8080:80 --name nginx nginx
#dockerコンテナ起動
sudo docker container start nginx
#dockerコンテナ起動確認
sudo docker container ls
#dockerコンテナ停止
sudo docker container stop nginx
-p 指定ポート:デフォルトポート
-d(バックグラウンドで起動する)
--rm(docker stopを掛けると自動的にコンテナが削除される)
--name(任意の名前をコンテナに命名可能)
起動されたdocker container nginxのIPを調べる
sudo docker inspect nginx | grep -i ipaddress
停止するには
sudo docker container stop nginx
停止されたか確認する
sudo docker container ls
[yunisan1211@ip-x.x.x.x ~]$ sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[yunisan1211@ip-10-0-1-107 ~]$ sudo docker container run -d --rm --name nginx nginx
3bc9d1dc1609f59a35fc6f1e016fedb41d10fbe6cf9f59c6fde08fbbd8fc563a
[yunisan1211@ip-10-0-1-107 ~]$ sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3bc9d1dc1609 nginx "/docker-entrypoint.…" 8 seconds ago Up 7 seconds 80/tcp nginx
[yunisan1211@ip-10-0-1-107 ~]$ sudo docker container ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3bc9d1dc1609 nginx "/docker-entrypoint.…" 17 seconds ago Up 16 seconds 80/tcp nginx
3178bc38e40c redis "docker-entrypoint.s…" 3 minutes ago Exited (0) 3 minutes ago compassionate_mclaren
fa1680134b1f nginx "/docker-entrypoint.…" 4 minutes ago Exited (0) 4 minutes ago naughty_margulis
[yunisan1211@ip-10-0-1-107 ~]$ sudo docker help
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Common Commands:
run Create and run a new container from an image
exec Execute a command in a running container
ps List containers
build Build an image from a Dockerfile
pull Download an image from a registry
push Upload an image to a registry
images List images
login Log in to a registry
logout Log out from a registry
search Search Docker Hub for images
version Show the Docker version information
info Display system-wide information
Management Commands:
builder Manage builds
buildx* Docker Buildx (Docker Inc., v0.0.0+unknown)
compose* Docker Compose (Docker Inc., v2.24.7)
container Manage containers
context Manage contexts
image Manage images
manifest Manage Docker image manifests and manifest lists
network Manage networks
plugin Manage plugins
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes
Swarm Commands:
swarm Manage Swarm
Commands:
attach Attach local standard input, output, and error streams to a running container
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
export Export a container's filesystem as a tar archive
history Show the history of an image
import Import the contents from a tarball to create a filesystem image
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
save Save one or more images to a tar archive (streamed to STDOUT by default)
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
wait Block until one or more containers stop, then print their exit codes
Global Options:
--config string Location of client config files (default "/root/.docker")
-c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use")
-D, --debug Enable debug mode
-H, --host list Daemon socket to connect to
-l, --log-level string Set the logging level ("debug", "info", "warn", "error", "fatal") (default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem")
--tlskey string Path to TLS key file (default "/root/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit
Run 'docker COMMAND --help' for more information on a command.
For more help on how to use Docker, head to https://docs.docker.com/go/guides/
[yunisan1211@ip-10-0-1-107 ~]$ sudo docker inspect nginx | grep -i ipaddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
[yunisan1211@ip-10-0-1-107 ~]$ curl 172.17.0.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[yunisan1211@ip-10-0-1-107 ~]$ sudo docker container stop nginx
[sudo] password for yunisan1211:
nginx
[yunisan1211@ip-10-0-1-107 ~]$ sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[yunisan1211@ip-10-0-1-107 ~]$
EC2のパブリックIPでアクセスするとNginxのwellcomeページが表示された。
dockerコンテナでalmalinuxを起動して、シェルにはいる
一連の流れ
- AlmaLinuxをDocker hub上で探す
- イメージをダウンロードする
- ダウンロードしたイメージの確認
- イメージからコンテナを作成する
- 作成後の確認
- コンテナを起動しシェルに入る、操作する
- シェルからログアウトする
- コンテナを削除する
#AlmaLinuxをDocker hub上で探す
sudo docker search almalinux
#NAME DESCRIPTION STARS OFFICIAL
#almalinux The official build of AlmaLinux OS. 145 [OK]
#イメージをダウンロードする
sudo docker pull almalinux
#Using default tag: latest
#latest: Pulling from library/almalinux
#28130cb29ede: Pull complete
#Digest: sha256:d7f8aa1c5ff918565fa1114d16e27b03fe10944a422e2943a66f6f4a275fa22c
#Status: Downloaded newer image for almalinux:latest
#docker.io/library/almalinux:latest
#ダウンロードしたイメージの確認
sudo docker image ls
#almalinux latest 7407e03f7ffc 3 months ago 184MB
#イメージからコンテナを作成する
sudo docker container create --name almalinux almalinux
#作成後の確認
sudo docker container ps -a
#CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#7da913b4a40a almalinux "/bin/bash" About a minute ago Created almalinux
#コンテナを起動しシェルに入る、操作する
sudo docker container run -it almalinux bash
#[root@f7ddcc59d5ee /]# cat /etc/os-release
#NAME="AlmaLinux"
#VERSION="9.3 (Shamrock Pampas Cat)"
#ID="almalinux"
#ID_LIKE="rhel centos fedora"
#VERSION_ID="9.3"
#PLATFORM_ID="platform:el9"
#PRETTY_NAME="AlmaLinux 9.3 (Shamrock Pampas Cat)"
#ANSI_COLOR="0;34"
#LOGO="fedora-logo-icon"
#CPE_NAME="cpe:/o:almalinux:almalinux:9::baseos"
#HOME_URL="https://almalinux.org/"
#DOCUMENTATION_URL="https://wiki.almalinux.org/"
#BUG_REPORT_URL="https://bugs.almalinux.org/"
#ALMALINUX_MANTISBT_PROJECT="AlmaLinux-9"
#ALMALINUX_MANTISBT_PROJECT_VERSION="9.3"
#REDHAT_SUPPORT_PRODUCT="AlmaLinux"
#REDHAT_SUPPORT_PRODUCT_VERSION="9.3"
#シェルを起動させたまま抜けたい場合
Ctrl + P + Q
# 再び入りたい場合
sudo docker container exec -it [container-id or name] bash
#シェルを終了する場合
exit
#起動させたままの場合は停止する
sudo docker container stop almalinux
#dockerコンテナを削除する
sudo docker container rm almalinux
officialイメージであることを確認した
dockerイメージとコンテナの一覧確認コマンド
#ローカルにあるdockerイメージの一覧取得
sudo docker image ls
#実行中のコンテナ
sudo docker container ls
#停止および終了も含めたコンテナの表示
sudo docker container ls -a or --all
sudo docker container ps -a or --all
#特定の列の絞り込み
sudo docker container ls -a -f status=exited
#特定の列の絞り込みとコンテナIDのみ表示
sudo docker container ls -a -f status=exited -q
dockerイメージとコンテナの削除コマンド
#削除前に停止をする container-idは最初の4文字でOK!
sudo docker container stop [container-id or name]
#削除
sudo docker container rm [container-id or name]
#起動中のコンテナを強制的に削除 -f=fource
sudo docker container rm -f [container-id or name]
#終了したコンテナを全て削除する
sudo docker container rm $(docker container ls -a -f status=exited -q)
#docker imageを削除する
sudo docker image rm [image-id or repo-name] #new
sudo docker rmi [image-id or repo-name] #old
#未解決のイメージ、停止したコンテナ、未解決のビルド キャッシュ、および使用されていないネットワークを削除する
docker system prune
#未使用のイメージも削除します
docker system prune -a
シェル系の操作
#起動後シェルに入りたいとき(コンテナがない場合)-itは必須!
sudo docker container run --name almalinux alumalinux -it bash
#シェルを起動させたまま抜けたいとき
Ctrl + P + Q
#再度シェルに入りたい場合
sudo docker container exec [container-id or name]
#停止させる場合
sudo docker container stop [container-id or name]
#起動させる場合
sudo docker container start [container-id or name]
#シェルに入らずに操作をさせたいとき
sudo docker container exec [container-id or name] コマンド
ログの確認
#ログの確認
sudo docker container logs [id or name]
#ログを継続して確認
sudo docker container logs -f [id or name]
カスタマイズしたコンテナのイメージ化
docker commitを使用してコンテナをイメージ化する
-m コミットメッセージ
-a 作成者の名前
yunilab ⇒ イメージのもとになるコンテナ
yuukun1211/my_almalinux:latest ⇒イメージの名前
docker hunのアカウント/カスタムイメージ名:バージョンとしたほうがよい。
sudo docker commit -m "nmap installed" -a "yuki.sakai" yunilab yuukun1211/my_almalinux:latest
#sha256:a60df9cc54772dd98ced09c98b5ac043a3975505549bd7b9c6dbd5998d01269d
sudo docker image ls
#REPOSITORY TAG IMAGE ID CREATED SIZE
#yuukun1211/my_almalinux latest a60df9cc5477 14 seconds ago 251MB
#almalinux latest 7407e03f7ffc 3 months ago 184MB
sudo docker container run -it yuukun1211/my_almalinux
[root@b055860a7529 /]# nmap
Nmap 7.92 ( https://nmap.org )
docker image tag repo new_reponame
tag付けをすることでコピーを作成することができる。
new_reponameは通常、自分のリポジトリ/元のリポジトリ名:versionとする。
カスタムリポジトリをdocker hubにアップロードする
#docker hubにログインする
sudo docker login
#カスタムイメージをpushする
sudo docker image push account/repo_name:tag
docker hubをみるとアップロードができている!
Dockerfile
Dockerfileとは、Dockerイメージを作成するためのテキストファイルである。Dockerfile内には、基本となるOS、インストールする必要があるSW、コピーするファイル、ディレクトリ、開くポート、実行するコマンドなど、新しいDockerイメージを作成するために必要な指示が含まれている。
Dokcerfileの書き方としては、「FROM」「RUN」「CMD」などのインストラクションに引数を記述し作成する。
FROM
「FROM」インストラクションは、Dockerfileの中で一番最初に記述されるべき命令で、新たに作成するDockerイメージのベースとなるイメージを指定する。
#FROMでイメージを指定 イメージの名前:タグ名(バージョン) FROM nginx:latest
RUN
「RUN」インストラクションはDockerイメージのビルド時にシェルコマンドを実行するための命令である。
この命令を使用することで、イメージにソフトウェアをインストールしたり、セットアップの手順を実行したりすることができる。
#RUNでシェルコマンドを実行する RUN apt update && apt install -y curl
「RUN」インストラクションは実行ごとに新しいレイヤを作成してその上でコマンドを実行するため、多くの「RUN」を持つDockerfileは多くのレイヤからなるイメージを作成しイメージのサイズが大きくなる。そのため、レイヤ数は最小限にすることが望ましい。
このため、複数のコマンドを一度にまとめて実行するときは、「&&」でつなぎ、「RUN」を減らし、複数行になるときは\をつかい可視性をあげる。
CMD
「CMD」インストラクションは、Dockerコンテナが実行された時にデフォルトで実行するコマンドを定義する。原則として末尾に書く。複数書いても一番最後の命令しか処理されないことに注意する。
# 書式:CMD ["実行ファイル", "パラメータ1","パラメータ2"]
$ CMD ["apachectl","-D","FOREGROUND"]
COPYとADD
「COPY」インストラクションは、ホスト(ローカル)のファイルやディレクトリをDockerイメージにコピーする。
具体的な使い方としては、ソースコードや設定ファイルはローカルで作成してCOPYを使ってDockerイメージにコピーして使用する。
「ADD」インストラクションは、自動的にtar展開してからコピーを行う。(ADDはリモートファイルを追加できる点もCOPYと異なる)
# 書式: COPY [コピー元][コピー先]
①ファイルをファイルに
COPY index.html /mydir/index.html
②ファイルをディレクトリ以下に
COPY index.html /mydir/
③ディレクトリをディレクトリに
COPY src/ /mydir/
# 書式: ADD[追加元][追加先]
#tarファイルを展開
ADD ./hoge/hoge.tar /hoge/
#通常はCOPYコマンドを使用し、tarファイルを扱うときやリモートファイルを扱う際はADDを使用する。
ARGとENV
「ENV」インストラクションは、Dockerfile内で環境変数を設定するために使用される。設定された環境変数は、その後のDockerfileの中で使用することができ、また生成されたDockerイメージから作成されるすべてのコンテナで利用することが可能。
「ARG」インストラクションは、同一Dockerfile内でのみ使用可能である
つまり、そのコンテナ全体で共有したいような変数を事前に決めておきたい場合は、ENVを使用し、インストールするSWのバージョンといったビルド時に必要なもの等はARGという認識でよさそうです。
# 書式: ENV [環境変数名] = [値]
ENV MYSQL_USER=yunilab
ENV MYSQL_PASSWORD=hogefoobar
# 書式: ARG [変数名] = [値]
ARG VERSION="18.00"
FROM ubuntu:${VERSION}
WORKDIR
「WORKDIR」インストラクションは、コマンドを実行する作業ディレクトリを指定する。
# 書式: WORKDIR [ディレクトリのパス]
WORKDIR /app
#移行は/appでの操作が行われる。
「WORKDIR」インストラクションを使用することで、Dockerfileが読みやすくなり、絶対パスを何度も書く手間を省くことができる。
EXPOSE
コンテナが特定のポートをlistenしていることをDockerに通知する役割を果たす。
!実際にEXPOSE命令自体は、ポートを公開するわけではなく、イメージ作成者とコンテナ運用者のドキュメント的な側面があるため、実際のポートを公開するには、dokcer run -pを使用する必要があることに注意する
#80番ポートをlistenしていることを通知
EXPOSE 80
VOLUME
VOLUMEを使用することにより、コンテナ内のデータをホストマシン上に永続保管することが可能。
マウントする位置を示す。「docker run -v /foo/bar:/var/lib/mysql」と同じ [ホスト上のディレクトリ:コンテナ内のディレクトリ]
VOLUME["/foo/bar/"] or VOLUME /foo/bar/のような指定が可能。
FROM ubuntu
RUN mkdir/myvol \
&& echo "hello world" > /myvol/hogehoge
VOLUME /myvol
#1コマンドごとにイメージレイヤーが上乗せされる
#docker historyコマンドで確認ができる
#FROMでイメージを指定 イメージの名前:タグ名(バージョン)
FROM nginx:latest
#COPYでホストからファイルをイメージにコピーする
COPY index.html index.html
#RUNでシェルコマンドを実行する
RUN apt update && apt install -y curl
#ENVで環境変数を指定
ENV env_key env_value
#CMDでコンテナが起動したときに最初に起動するコマンド
CMD ["nginx", "-g", "deamon", "off"]
作成したDockerfileの起動は下記のように行う
docker build . -t example:latest
Docker Compose
Docker Composeとは、これまでDocker runなどでコンテナ一つごとにコマンドを打って操作していたものを、composeを用いることにより、複数のコンテナで構成されるアプリケーションについて、Dockerイメージのビルドや各コンテナの起動・停止などをより簡単に行えるようにするツールといえる。
コンテナを起動するまでの流れ
Dockerfileの作成
docker-compose.ymlファイルで直接イメージを指定すれば、Docker composeでコンテナを起動するためのDockerfileは必要ないですが、既存のイメージに対して追加の設定やカスタマイズを行いたい場合は、Dockerfileを作成し、それをdocker-compose.ymlから参照する。
docker-compose.ymlの作成
docker-compose.ymlとはDocker Composeの設定ファイルであり、これから作成するコンテナの初期状態を「ports:」「volumes:」などYAML形式を用いて定義する。
また、このファイルは通常、プロジェクトのルートディレクトリに配置するのが一般的である。
docker-compose.ymlを使用することにより、複数のコンテナで構成されるアプリケーションの全体像を一目で把握でき、さらに一つのコマンドですべてのコンテナを起動したり、停止するといったことも可能になる。
docker-composeコマンドでコンテナ起動
docker-compose.ymlファイルが存在するディレクトリでdocker compose upコマンドを実行すると、docker-compose.ymlファイルに記述されたすべてのサービス(コンテナ)をビルドし、起動することができる。
docker-compose.ymlファイルの書き方
services: # (1)
db:
image: mysql:5.7 # (2)
volumes: # (4)
- db_data:/var/lib/mysql
restart: always
environment: # (6)
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: your_database
MYSQL_USER: user_name
MYSQL_PASSWORD: user_password
web:
build: ./rails_project # (3)
command: bundle exec rails s -p 3000 -b '0.0.0.0' # (9)
volumes: # (4)
- .:/myapp
ports: # (7)
- "3000:3000"
depends_on: # (8)
- db
volumes: # (5)
db_data:
services
ここでは、作成したいサービス(コンテナ)を列挙する
サンプルでは「web」と「db」という名前で2つのコンテナについて、それぞれ設定が記述されています。
services:
db: #service_name
web: #service_name
サービス名は任意の名前を付けることができるが、「そのサービスが何を示しているか理解しやすい名前を付けること」「サービス名をほかのサービスから参照している場合があるので、変更する場合は参照されているサービス名も変更すること」に気を付けること。
image
既存のイメージに対して追加の設定やカスタマイズを行う必要がない場合、image:に続いて、Dockerイメージを指定することで、そのイメージよりビルドを行います。
image: mysql:5.7 #イメージ名:タグ
build
image:よりビルドするのではなく、用意したDockerfileよりビルドする場合、build:へumlファイルが置いてあるディレクトリからDockerfileが置いてあるディレクトリへの相対パスを記述します。
build: ./rails_project #Dockerfileがあるディレクトリへの相対パス
volumes【サービス内にある方】
volumesはデータをコンテナの外に保存するための設定項目であり、ホストにもデータを共有することでデータの永続性を可能する。
#dbコンテナ
volumes:
- db_data:/var/lib/mysql #ホストディレクトリ:コンテナ内ディレクトリ
#webコンテナ
volumes:
- .:/myapp
volumesはホスト側のディレクトリとコンテナ内のディレクトリをマウントするために使用され、ホスト上で変更を行うとリアルタイムにコンテナ内にも反映される。
volumes【トップレベルで指定されている方】
ここでのvolumesはDocker Composeにボリュームを作成するように指示します。そしてここで定義されたボリュームはサービス内のvolumesで使用することができ、サンプルにおいてもdbコンテナにおいて使用されています。
volumes:
db_data:
volumes:を使うとデータはDockerコンテナの起動・停止のサイクルから独立して保存・管理することができるため、コンテナが削除されてもボリュームに保存されたデータは保持される。
ボリュームの考え方は結構難しいので、以下の記事を見たほうがよろしいかと。。
https://qiita.com/aki_55p/items/63c47214cab7bcb027e0
-vオプションと--mountオプションの項目が参考になった。
environment
environmentは、Dockerコンテナ内で使用される環境変数を設定するために使用する。
Dockerコンテナはホストの環境と完全に分離されて動作するため、コンテナ内部で環境変数を設定する必要がある。
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: your_database
MYSQL_USER: user_name
MYSQL_PASSWORD: user_password
ports
portsの設定では、ホストマシンとDockerコンテナ間でのネットワークポートのマッピングを指定する。
指定する形式は「ホストマシンのポート番号:コンテナのポート番号」となる
ports:
- "3000:3000" # ホストマシンのポート番号:コンテナのポート番号
depends_on
depends_onはサービス間の依存関係を定義するために使用し、Docker Composeに指定したサービスが他の1つ以上のサービスに依存していることを伝えることができる。
その結果、Docker Composeは、そのサービスを開始する前に依存しているすべてのサービスが先に開始されていることを確認してくれる。
# (webコンテナ)
depends_on:
- db
上記の内容では、webコンテナがdbコンテナに依存しているので、dbコンテナが先に開始されることをDocker Composeは確認します。
command
commandはサービスコンテナが起動したときに実行するコマンドを指定する
command: bundle exec rails s -p 3000 -b '0.0.0.0'
Docker Composeコマンドで操作する
up (コンテナ作成・起動)
docker compose up #イメージが存在しないときはビルドする
オプションでは以下の2つがよくつかわれる。
- --build イメージをビルドした上でコンテナを作成・起動する
- -d コンテナをバックグラウンドで起動させる
docker compose up --build
docker compose up -d
ps (コンテナ一覧表示)
停止中を含めたコンテナの一覧を表示をさせたい場合は、-aオプションを付ける。
docker compose ps # コンテナの一覧を表示
docker compose ps -a #停止中を含めたコンテナの一覧を表示
logs (ログを表示)
logsコマンドの後に、サービス名を指定することでログを表示させる
docker compose logs web
#サービス名を指定`
run (コンテナ作成後、コマンドを実行)
runコマンドの後に、サービス名とコマンドを指定することで、コンテナを作成して1度だけコマンドを実行する。
docker compose run web ruby app.rb #サービスとコマンドを指定
exec (コマンドを実行)
起動中のコンテナでexecコマンドの後に、サービス名とコマンドを指定することでコマンドを実行する。
docker compose exec web cat /etc/httpd/httpd.conf
#サービスとコマンドを指定`
down (コンテナを停止・削除)
downコマンドを付けるだけで、upコマンドで作成されたコンテナを停止・削除する。
docker compose down
ここまでで、Dockerに必要な一通りの知識は学べたかと思います。
あとは自分でコンテナを作成したり、いろいろトライしてみて身につけていくことをおすすめします!
私自身もDockerという領域に初めてダイブしたので、これからも学習を続けていきたいと思います!!