Docker DesktopにCritical脆弱性、CVE-2025-9074 ─ macOS・Linuxも含め更新推奨

コンテナ技術は、開発から運用まで幅広い現場で欠かせない存在となっています。その中でも Docker Desktop は、Windows・macOS・Linux などの環境で簡単に Docker を利用できるツールとして、多くの開発者やエンジニアに利用されています。日常的にローカル開発環境を立ち上げたり、テスト用に複数のコンテナを起動したりする用途で広く普及しており、影響範囲は非常に大きいと言えます。

今回報告された脆弱性 CVE-2025-9074 は、そうした日常的に利用される開発環境に潜む重大なリスクです。影響は特定の設定や条件に限定されず、Enhanced Container Isolation(ECI)や「Expose daemon」設定の有無にかかわらず影響を受けることが判明しています。これにより、普段はセキュアだと考えていた環境でも、不正アクセスやコンテナ制御の乗っ取りといった深刻な被害に発展する可能性があります。

特に Windows 環境では、WSL を介したホストドライブへのアクセスが可能になるなど追加的なリスクが確認されていますが、macOS や Linux でも同様にコンテナ間の不正制御が可能になるため、「Windows ユーザーだけが対象」ではなく、すべての Docker Desktop ユーザーが直ちにアップデートすべき事案です。

Docker 側は迅速に修正版をリリースしており、2025年8月20日に公開された Docker Desktop 4.44.3 で本脆弱性が修正されています。本記事では、脆弱性の詳細とリスク、そしてユーザーが取るべき対策について整理します。

脆弱性の概要

今回報告された CVE-2025-9074 は、Docker Desktop 上で稼働する Linux コンテナが、本来アクセスできないはずの Docker Engine API に直接アクセスできてしまうという脆弱性です。Docker Engine API はコンテナのライフサイクル管理やイメージ操作などを行うための強力なインターフェースであり、ここに不正アクセスされると、ユーザーの意図しない操作が可能になってしまいます。

この問題の本質は、Docker Desktop が内部で利用している サブネット経由の通信経路にあります。通常であれば、セキュリティ設定やネットワークの分離によってコンテナからホスト側の管理 API へ直接到達できないように設計されています。しかし、今回の脆弱性では、その設計をすり抜ける形でアクセスが可能となり、結果として以下のようなリスクが生じます。

  • 不正なコンテナ制御: 攻撃者が任意に新しいコンテナを生成したり、既存コンテナを停止・削除したりできる。
  • イメージの操作: ローカルに保存された Docker イメージを削除、改ざん、あるいは外部に流出させる可能性。
  • 設定の改変: 環境構築や開発に利用する設定を不正に変更される危険性。

さらに問題を深刻化させているのは、この挙動が ECI(Enhanced Container Isolation)や「Expose daemon」の設定有無に依存しない という点です。つまり、セキュリティオプションを強化していたとしても、今回の脆弱性を防ぐことはできません。

また、Windows 環境においては、WSL バックエンドを利用している場合、通常は制御できない ホストドライブがユーザー権限でマウントされる リスクが確認されています。これはシステム内のファイルが意図せず外部から参照・改変されることにつながり、開発用 PC の安全性を直接脅かす可能性があります。

一方で macOS や Linux 環境においても、Docker Engine API の権限を奪取されれば同様にコンテナ制御やイメージ操作が行われるため、プラットフォームに依存しない深刻な脅威となっています。

今回の脆弱性は CVSS v4.0 ベーススコア 9.3(Critical) として評価されており、最も高い深刻度レベルに分類されています。この評価は、単なる理論的リスクではなく、現実に悪用された場合の影響が極めて広範囲かつ深刻であることを意味しています。

影響範囲

今回の脆弱性 CVE-2025-9074 は、Docker Desktop を利用しているすべてのユーザーに影響を与える可能性があります。特定の環境や利用方法に限定された問題ではなく、Windows・macOS・Linux のいずれにおいても共通してリスクが存在する点が重要です。

まず Windows 環境については、特に WSL(Windows Subsystem for Linux)をバックエンドとして利用している場合に深刻な追加リスクが指摘されています。WSL 上の Linux コンテナからホストマシンのドライブをユーザー権限でマウントされる可能性があり、これによって開発者が扱うソースコードや機密データが不正に参照・改変される危険性が生じます。これは通常のコンテナ分離モデルでは想定されない挙動であり、ローカル開発環境全体が攻撃者に乗っ取られる可能性を意味します。

一方で macOS や Linux 環境でも安心はできません。Docker Engine API へのアクセスが可能になる点は共通しており、攻撃者がこの API を操作することで、以下のようなリスクが発生します。

  • 不正なコンテナの生成・削除・停止などによる環境の破壊
  • ローカルに保存された Docker イメージの不正利用や流出
  • 開発環境に必要な設定やデータの改変によるサービス停止や混乱

つまり、「Windows 以外の環境では被害が軽い」とは言えず、開発環境に依存するすべてのユーザーが影響を受ける可能性があるのです。Docker Desktop は開発者にとって日常的に利用するツールであり、ローカル環境のコンテナ基盤そのものが脆弱化するという点で、被害の範囲は単一コンテナにとどまらず、開発プロジェクト全体、さらには組織内のリポジトリや CI/CD パイプラインに波及するリスクを孕んでいます。

加えて、今回の脆弱性は ECI(Enhanced Container Isolation)や「Expose daemon」設定の有無に依存せず影響するため、「セキュリティ機能を有効化しているから安全」と考えていたユーザーも例外ではありません。むしろ、多くの利用環境で普段通りにコンテナを実行しているだけで影響を受けるため、利用者全体を巻き込む普遍的な問題と言えます。

結論として、この脆弱性は 「Docker Desktop を利用するすべてのユーザーが対象」であり、特定のプラットフォームや構成に限定されたリスクではありません。そのため、Windows だけでなく macOS や Linux を利用している開発者やエンジニアも例外なく、迅速なアップデート対応が求められます。

対策

今回の脆弱性 CVE-2025-9074 に対しては、Docker 社がすでに修正版を公開しており、Docker Desktop 4.44.3 以降にアップデートすることで解消されます。現地時間 2025 年 8 月 20 日にリリースされたこのバージョンには、脆弱性を突いた不正アクセス経路を封じる修正が含まれており、ユーザー側で追加の設定変更を行う必要はありません。

重要な点は、設定や回避策では問題を防げないということです。ECI(Enhanced Container Isolation)の有効化や「Expose daemon」の無効化など、従来のセキュリティオプションを組み合わせてもこの脆弱性を防ぐことはできません。根本的な対策は Docker Desktop 自体を更新することに尽きます。

アップデート手順

1.現在のバージョンを確認

ターミナルで以下を実行し、Docker Desktop 4.44.3 以上であるかを確認します。

docker version

または、Docker Desktop Dashboardの右下に表示されているバージョンが4.44.3以上になっていることを確認します。

2.最新版の入手

Docker の公式サイト(https://www.docker.com/products/docker-desktop)から最新版をダウンロードします。Docker Desktop Dashboardの通知からでもダウンロード可能です。

3.Docker Desktopのアップデート

  • Windows / macOS: インストーラを実行し、既存の Docker Desktop に上書きインストール。
  • Linux: パッケージマネージャ(例: apt や dnf)を利用して更新、もしくは公式のインストーラを再適用。

4.アップデートの実行

右下がUpdateという表示になっている場合、これをクリックしてアップデートを行ってください。Software Updateページが表示されるので、更新を実施してください。

5.アップデート後の確認

  • 再度 docker version を実行し、クライアント・サーバともに 4.44.3 以上であることを確認。
  • 念のため、既存のコンテナが正常に動作するかテスト。

運用上の留意点

  • 全環境での更新を徹底: 個人開発環境だけでなく、チームメンバーや CI/CD 用のビルド環境など、Docker Desktop を利用しているすべての端末で更新が必要です。
  • 旧バージョンの利用を避ける: 脆弱性が公開されているため、旧バージョンを使い続けると攻撃者に狙われやすくなります。
  • 定期的なバージョンチェック: Docker Desktop は短いリリースサイクルで更新されるため、今回の件を機に定期的にバージョン確認を行い、常に最新を維持する運用を推奨します。
  • CI/CD パイプラインの確認: ビルド環境やテスト環境で Docker Desktop を利用している場合、更新漏れがあるとチーム全体のリスクにつながるため、パイプラインの実行ホストも忘れずに更新してください。

結論として、唯一の有効な対策は速やかなアップデートです。Windows 環境だけでなく macOS・Linux を含むすべての開発環境で Docker Desktop を利用しているユーザーは、今すぐバージョン確認を行い、必要に応じて更新を実施することが強く推奨されます。

おわりに

今回明らかになった CVE-2025-9074 は、Docker Desktop の根幹である Docker Engine API へのアクセス制御に関わる重大な脆弱性であり、影響範囲は Windows・macOS・Linux を含むすべての利用者に及びます。特定の環境に限定された問題ではなく、普段の開発作業やテスト環境、さらには CI/CD パイプラインにまで影響する可能性がある点が非常に危険です。

特に Windows 環境では WSL を介したホストドライブへのアクセスが可能になるなど追加的なリスクがありますが、これはあくまで一部の強調事例であり、macOS や Linux 環境でも Docker Engine API を乗っ取られることで同等の深刻な被害が生じ得ます。したがって、「Windows 以外は安全」と考えるのは誤りです。開発者がどの OS を利用していようと、この脆弱性を軽視すべきではありません。

Docker 社は迅速に修正版を提供しており、2025 年 8 月 20 日公開の Docker Desktop 4.44.3 で問題は解消されています。今回の事例から学べる重要な教訓は、脆弱性対策は「設定や部分的な防御策では不十分」であり、ソフトウェアを常に最新の状態に保つことこそが最も確実な防御策であるという点です。

また、個人開発者だけでなく、組織として Docker Desktop を利用している場合は、全メンバーの環境を一斉に更新する体制が不可欠です。ひとりでも古いバージョンを使い続ければ、その環境が攻撃者に狙われ、結果的にプロジェクト全体のセキュリティを損なう恐れがあります。特にクラウド連携やソースコード管理リポジトリと接続している開発環境では、被害が企業全体に波及する可能性すらあります。

さらに、今回の脆弱性に限らず、日常的なセキュリティ対策として 安全性が確認されていない不明なコンテナイメージを軽率に起動しない ことも重要です。公式リポジトリや信頼できる配布元以外から入手したコンテナには、脆弱性を悪用するコードやマルウェアが含まれる可能性があります。OS やツールを最新化することと同様に、利用するコンテナの信頼性を確認することも忘れてはなりません。

結論として、今すぐ Docker Desktop のバージョンを確認し、4.44.3 以上に更新することが最優先の対応です。加えて、怪しいコンテナを不用意に起動せず、信頼できるソースのみを利用することが、Docker 環境全体の安全を守るうえで不可欠な行動となります。

参考文献

Docker Composeのversionが不要になっていた

かなり前からdocker-compose.yamlversionが不要になっていたようですが、macOS上ではversion is 'obsolete'のメッセージが出ていなかったので、気づきませんでした。

Windows環境でversion is 'obsolete'のメッセージが表示されるのを見かけたので、調べてみると後方互換性を維持するために残っているだけで、意味のない項目になっているようです。

この説明を読む限り、ワーニングメッセージが表示されるようですが、macOSのDocker Desktopに同梱されているDocker Composeでは特にメッセージが出ていませんでした。ただ、versionがなくても問題なく動作するので、無理に削除する必要はないものの、新たに作成する場合はversionをつけないようにした方がよさそうです。

Laravel Sail+PHPStormで開発環境を構築する

Laravelで作りたいアプリケーションがあるため、macOS上で開発するための環境を構築します。

Laravel Sailでインストールする

macOS上でDocker Desktopを導入している場合、もっとも簡単に開発環境を構築できる手段になると思います。

作成したいアプリケーションがexample-appの場合、次のようにコマンドを入力します。

$ curl -s "https://laravel.build/example-app" | bash

最後にパスワードが求められますので入力してください。

初期設定を行う

PHPStormで開発を行うため、アプリケーションを開いた後必要な初期設定を行います。

まずはコンテナを起動します。

$ ./vendor/bin/sail up

コンテナが起動している状態で、設定をひらきます。

PHP言語レベル、CLIインタープリターを設定します。

今回はLaravel 10.xがサポートしているバージョンのうち、8.3を使用していますので、PHP言語レベルは8.3を指定しています。

また、CLIインタープリターはローカルのPHPではなく、Dockerコンテナー上のPHPを使用することで、ローカルにPHPをインストールしなくて済みます。CLIインタープリターの右の…ボタンをクリックし、CLIインタープリターダイアログの左上の+ボタンをクリックし、「From Docker, Vagrant, VM, WSL, Remote…」をクリックしてください。

リモートPHPインタープリターの構成ダイアログで、Dockerを選択し、

サーバーの右ある新規…ボタンをクリックし、

OKボタンをクリックしてください。

OKボタンをクリックすると設定は完了します。

デバッグの設定を行う

次にデバッグの設定を行います。docker-compose.ymlを確認すると、SAIL_XDEBUG_MODE環境変数がない場合、デバッグモードがOFFになっています。

        environment:
            WWWUSER: '${WWWUSER}'
            LARAVEL_SAIL: 1
            XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
            XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
            IGNITION_LOCAL_SITES_PATH: '${PWD}'

docker-compose.ymlを修正するのではなく、.envファイルにSAIL_XDEBUG_MODEを追加します。

SAIL_XDEBUG_MODE=debug

また、Settings…>PHP>サーバーの「パスマッピングを使用する」のチェックボックスを外しておきます。

これがあると以下のような警告が表示され、ブレークポイントで止まりません。

環境変数を反映するためにいったんDockerコンテナーを停止して起動しなおします。

動作確認のためにroutes/web.phpにデバッグを設定し、

デバッグを有効化(虫のマークをクリックして以下のようにします)

http://localhostにアクセスすると、以下のようなダイアログが表示されます。

このまま進めると、ブレークポイントで止まります。

これで環境構築は完了です。

まとめ

プロジェクトの作成から初期設定、デバッグの設定までを行いました。デバッグについては一応動作していますが、若干動作が怪しいので、今後の開発で調整するかもしれません。

Dockerコマンドチートシート20選+α(実行例付き)

dockerコマンドの中でもよく使うコマンドを実行例付きで20個集めました。

Dockerの状態を確認する

Dockerのバージョン情報を表示

docker --version
$ docker --version
Docker version 24.0.5, build ced0996

より詳細なバージョン情報が知りたい場合は、docker versionコマンドを使用します。

docker version

こちらはクライアントおよび現在接続しているサーバーのより詳細なバージョン情報を得られます。

$ docker version
Client:
 Cloud integration: v1.0.35-desktop+001
 Version:           24.0.5
 API version:       1.43
 Go version:        go1.20.6
 Git commit:        ced0996
 Built:             Fri Jul 21 20:32:30 2023
 OS/Arch:           darwin/arm64
 Context:           desktop-linux

Server: Docker Desktop 4.22.1 (118664)
 Engine:
  Version:          24.0.5
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.6
  Git commit:       a61e2b4
  Built:            Fri Jul 21 20:35:38 2023
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.6.21
  GitCommit:        3dce8eb055cbb6872793272b4f20ed16117344f8
 runc:
  Version:          1.1.7
  GitCommit:        v1.1.7-0-g860f061
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Dockerの実行状態を確認

docker info
$ docker info
Client:
 Version:    24.0.5
 Context:    desktop-linux
 Debug Mode: false
・・・
WARNING: daemon is not using the default seccomp profile

イメージの操作

イメージの一覧表示

実行結果に表示されるREPOSITORYがイメージ名、TAGがタグ名です。

docker images
$ docker images
REPOSITORY                                                TAG                                                                          IMAGE ID       CREATED         SIZE
ubuntu                                                    22.04                                                                        a2f229f811bf   3 weeks ago     69.2MB
ubuntu                                                    20.04                                                                        15c9d636cadd   4 weeks ago     65.7MB

イメージの検索

キーワードをイメージ名や説明に含むイメージを検索します。

docker search <キーワード>
$ docker search nginx
NAME                                              DESCRIPTION                                      STARS     OFFICIAL   AUTOMATED
nginx                                             Official build of Nginx.                         18963     [OK]
unit                                              Official build of NGINX Unit: Universal Web …   10        [OK]
nginxinc/nginx-unprivileged                       Unprivileged NGINX Dockerfiles                   114

イメージの検索はできますが、タグを検索することはできないため、Docker Hubで探してください。

イメージの取得

イメージ名またはイメージ名とタグ名を指定してイメージを取得します。

docker pull <イメージ名>[:タグ]

タグを省略するとデフォルトタグ(多くの場合はlatestタグ)が取得されます。

$ docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
db76c1f8aa17: Pull complete
Digest: sha256:ec050c32e4a6085b423d36ecd025c0d3ff00c38ab93a3d71a460ff1c44fa6d77
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest

What's Next?
  View summary of image vulnerabilities and recommendations → docker scout quickview ubuntu

latestは取得タイミングによってバージョンが異なるため、基本的にはタグ(バージョン)を指定するのが推奨です。

$ docker pull ubuntu:20.04
20.04: Pulling from library/ubuntu
82d728d38b98: Pull complete
Digest: sha256:33a5cc25d22c45900796a1aca487ad7a7cb09f09ea00b779e3b2026b4fc2faba
Status: Downloaded newer image for ubuntu:20.04
docker.io/library/ubuntu:20.04

What's Next?
  View summary of image vulnerabilities and recommendations → docker scout quickview ubuntu:20.04

過去に取得したlatestタグのイメージを最新化する場合は再度docker pullしてください。

$ docker pull phpmyadmin/phpmyadmin
Using default tag: latest
latest: Pulling from phpmyadmin/phpmyadmin
faef57eae888: Pull complete
989a1d6c052e: Pull complete
0705c9c2f22d: Pull complete
621478e043ce: Pull complete
98246dcca987: Pull complete
bfed8c155cb6: Pull complete
7a7c2e908867: Pull complete
d176994b625c: Pull complete
2d8ace6a2716: Pull complete
c70df516383c: Pull complete
15e1b44fe4c7: Pull complete
65e50d44e95a: Pull complete
77f68910bc0a: Pull complete
605dd3a6e332: Pull complete
99ce27188f07: Pull complete
74d64e32c5d5: Pull complete
ef5fc9928b9f: Pull complete
163f3256e112: Pull complete
Digest: sha256:67ba2550fd004399ab0b95b64021a88ea544011e566a9a1995180a3decb6410d
Status: Downloaded newer image for phpmyadmin/phpmyadmin:latest
docker.io/phpmyadmin/phpmyadmin:latest

What's Next?
  View summary of image vulnerabilities and recommendations → docker scout quickview phpmyadmin/phpmyadmin

イメージの削除

docker rmi <イメージ名 or イメージ名:タグ or イメージID>

タグなしは:latestを指定しているのと同じです。

$ docker rmi hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:dcba6daec718f547568c562956fa47e1b03673dd010fe6ee58ca806767031d1c
Deleted: sha256:b038788ddb222cb7d6025b411759e4f5abe9910486c8f98534ead97befd77dd7
Deleted: sha256:a7866053acacfefb68912a8916b67d6847c12b51949c6b8a5580c6609c08ae45

コンテナの操作

実行中のコンテナを一覧表示

実行中のコンテナのリストを表示します。

docker ps

一覧に表示されるCONTAINER IDがコンテナIDで、NAMESがコンテナ名です。

$ docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED         STATUS         PORTS                  NAMES
17e44cfb7902   nginx     "/docker-entrypoint.…"   4 seconds ago   Up 3 seconds   0.0.0.0:8080->80/tcp   nginx01

すべてのコンテナを一覧表示

停止しているコンテナも表示したい場合は-aオプションを使います。

docker ps -a

ステータス(STATUS)で現在の状況を確認できます。Exitedになっている場合はすでに停止しているコンテナです。

CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS                      PORTS                  NAMES
17e44cfb7902   nginx     "/docker-entrypoint.…"   6 minutes ago    Up 6 minutes                0.0.0.0:8080->80/tcp   nginx01
21dc45864d5f   busybox   "sh"                      29 minutes ago   Exited (0) 29 minutes ago                          bold_volhard

コンテナの起動

docker run <イメージ名>[:<タグ名>]
docker run <イメージID>

$ 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
2023/09/03 03:46:40 [notice] 1#1: using the "epoll" event method
2023/09/03 03:46:40 [notice] 1#1: nginx/1.25.2
2023/09/03 03:46:40 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2023/09/03 03:46:40 [notice] 1#1: OS: Linux 5.15.49-linuxkit-pr
2023/09/03 03:46:40 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023/09/03 03:46:40 [notice] 1#1: start worker processes
2023/09/03 03:46:40 [notice] 1#1: start worker process 29
2023/09/03 03:46:40 [notice] 1#1: start worker process 30
2023/09/03 03:46:40 [notice] 1#1: start worker process 31
2023/09/03 03:46:40 [notice] 1#1: start worker process 32
2023/09/03 03:46:40 [notice] 1#1: start worker process 33

後述の-dオプションをつけないと制御が返ってこない点に注意が必要です。Ctrl+Cでコンテナを停止されることができます。

コンテナ名を指定して起動する

コンテナ名を指定しないと適当な名前で起動します。コンテナ名を指定したい場合は--nameオプションを使用します。

docker run --name <コンテナ名> <イメージ名>[:<タグ名>]
docker run --name <コンテナ名> <イメージID>
$ docker run -d --name web nginx
$ docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED         STATUS         PORTS     NAMES
ce2fa12b11da   nginx     "/docker-entrypoint.…"   3 seconds ago   Up 3 seconds   80/tcp    web

NAMESが指定したコンテナ名になっていることが確認できます。

すでに存在するコンテナ名を指定するとエラーになりますので、使用していないコンテナ名かどうかを確認するようにしましょう。

$ docker run -d --name web nginx
docker: Error response from daemon: Conflict. The container name "/web" is already in use by container "ce2fa12b11da0fcf214221c5cb4687ed48f5ac73e6e71586d2ddcee98202df7e". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.

コンテナ名は実行中でも変更可能です。

# 起動中のコンテナのコンテナ名がwebになっていることを確認
$ docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED         STATUS         PORTS     NAMES
ce2fa12b11da   nginx     "/docker-entrypoint.…"   5 minutes ago   Up 5 minutes   80/tcp    web

# コンテナIDと新しいコンテナ名を指定してリネームする
$ docker rename ce2fa12b11da web01

# コンテナ名がweb01に変更されていることを確認する
$ docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED         STATUS         PORTS     NAMES
ce2fa12b11da   nginx     "/docker-entrypoint.…"   5 minutes ago   Up 5 minutes   80/tcp    web01

ポートをマッピングしてコンテナを起動

docker run -p <ホスト側ポート番号>:<コンテナ側ポート番号> <イメージ名>[:<タグ名>]
docker run -p <ホスト側ポート番号>:<コンテナ側ポート番号> <イメージID>

nginxイメージで80ポートで公開されているポートを8080ポートでアクセスするには以下のようにします。

# -pオプションなしで80ポートが公開されていることを確認する
$ docker run -d nginx
d9fdeb14dbdbf035e12e7e6d45a24acd84c9da8cf8b8dbadc71d19baeb510ab0

$ docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED         STATUS         PORTS     NAMES
d9fdeb14dbdb   nginx     "/docker-entrypoint.…"   4 seconds ago   Up 3 seconds   80/tcp    zen_jepsen

# -pオプションをつけて8080ポートでアクセスできるようにする
$ docker run -d -p 8080:80 nginx
55378527d5381db7a3c50bc7a59ad2d8665499bee22f6a319d7e36ae44a08273

$ docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS          PORTS                  NAMES
55378527d538   nginx     "/docker-entrypoint.…"   2 seconds ago    Up 1 second     0.0.0.0:8080->80/tcp   great_lichterman
d9fdeb14dbdb   nginx     "/docker-entrypoint.…"   37 seconds ago   Up 36 seconds   80/tcp                 zen_jepsen

# 実際にアクセスできることも確認する
$ curl http://localhost/
curl: (7) Failed to connect to localhost port 80 after 6 ms: Couldn't connect to server
$ curl http://localhost:8080/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
・・・

-pオプションをつけるとSTATUSの表示が0.0.0.0:8080->80/tcpとなり、ホスト側が8080ポートでアクセスするとコンテナ側の80ポートにフォワードする設定になっていることがわかります。

コンテナをバックグラウンド実行で起動する

docker run -d <イメージ名>[:<タグ名>]
docker run -d <イメージID>
$ docker run -d nginx
8e715a36735862e297ddc4cec19bb6c1ae96cd4f822e3f4cd915a0d183b87e59

$ docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS          PORTS     NAMES
8e715a367358   nginx     "/docker-entrypoint.…"   10 seconds ago   Up 10 seconds   80/tcp    pedantic_cohen

コンテナの停止

docker stop <コンテナID>
docker stop <コンテナ名>
# コンテナが起動していることを確認
$ docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED         STATUS         PORTS     NAMES
ce2fa12b11da   nginx     "/docker-entrypoint.…"   5 minutes ago   Up 5 minutes   80/tcp    web01

# コンテナを停止する
$ docker stop ce2
ce2

# コンテナがdocker psでの表示から消え、docker ps -aでのみ確認できるようになっていることを確認
$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS                     PORTS     NAMES
ce2fa12b11da   nginx     "/docker-entrypoint.…"   32 minutes ago   Exited (0) 7 seconds ago             web01

コンテナの起動

docker start <コンテナID>
docker start <コンテナ名>
# 停止しているコンテナを確認する
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                   CREATED        STATUS                      PORTS     NAMES
17e44cfb7902   nginx     "/docker-entrypoint.…"   16 hours ago   Exited (0) 58 minutes ago             nginx01

# コンテナのコンテナIDの一部を指定してコンテナを起動
$ docker start 17e
17e

# コンテナが起動したことを確認する
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                   CREATED        STATUS          PORTS                  NAMES
17e44cfb7902   nginx     "/docker-entrypoint.…"   16 hours ago   Up 14 seconds   0.0.0.0:8080->80/tcp   nginx01

コンテナの削除

docker rm <コンテナID>
docker rm <コンテナ名>
# 停止しているコンテナのコンテナIDを確認する
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                   CREATED        STATUS                     PORTS     NAMES
17e44cfb7902   nginx     "/docker-entrypoint.…"   16 hours ago   Exited (0) 2 seconds ago             nginx01

# コンテナIDの一部を指定してコンテナを削除する
$ docker rm 17e
17e

# コンテナが削除されたことを確認する
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

起動中のコンテナ内でコマンドを実行

docker exec -itコマンドを使うとコンテナ内で任意のコマンドを実行できます。

docker exec -it <コンテナID> <コマンド>
docker exec -it <コンテナ名> <コマンド>
$ docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED          STATUS         PORTS     NAMES
ce2fa12b11da   nginx     "/docker-entrypoint.…"   39 minutes ago   Up 3 seconds   80/tcp    web01

# コンテナで「ls -l /var/log/nginx」を実行する
$ docker exec -it web01 ls -l /var/log/nginx
total 0
lrwxrwxrwx 1 root root 11 Aug 15 23:58 access.log -> /dev/stdout
lrwxrwxrwx 1 root root 11 Aug 15 23:58 error.log -> /dev/stderr

停止中のコンテナに実行してもエラーとなります。

$ docker stop web01
web01

$ docker exec -it web01 ls -l /var/log/nginx
Error response from daemon: Container ce2fa12b11da0fcf214221c5cb4687ed48f5ac73e6e71586d2ddcee98202df7e is not running

-itオプションにはもう一つ使い方があり、sshコマンドを使わなくてもコンテナ内にログインできるようになります。

$ docker exec -it web01 /bin/bash
root@ce2fa12b11da:/#

コンテナのセキュリティを高めるためには不要なサービスは公開せず、不要なポートも開けない方がよいため、-itオプションでのログインは非常に重要なテクニックとなります。

コンテナのログを表示

コンテナが出力するログを確認します。

docker logs <コンテナID>
docker logs <コンテナ名>

この例ではnginxイメージから作成したコンテナのログを確認しています。

$ docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED        STATUS        PORTS                  NAMES
17e44cfb7902   nginx     "/docker-entrypoint.…"   15 hours ago   Up 15 hours   0.0.0.0:8080->80/tcp   nginx01
$ docker logs 17e
/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
2023/08/31 22:20:56 [notice] 1#1: using the "epoll" event method
2023/08/31 22:20:56 [notice] 1#1: nginx/1.25.2
2023/08/31 22:20:56 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2023/08/31 22:20:56 [notice] 1#1: OS: Linux 5.15.49-linuxkit-pr
2023/08/31 22:20:56 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023/08/31 22:20:56 [notice] 1#1: start worker processes
2023/08/31 22:20:56 [notice] 1#1: start worker process 29
2023/08/31 22:20:56 [notice] 1#1: start worker process 30
2023/08/31 22:20:56 [notice] 1#1: start worker process 31
2023/08/31 22:20:56 [notice] 1#1: start worker process 32
2023/08/31 22:20:56 [notice] 1#1: start worker process 33

ボリュームの操作

ボリュームの一覧表示

一覧に表示されるVOLUME NAMEがボリューム名です。

docker volume ls
$ docker volume ls
DRIVER    VOLUME NAME
local     hello

ボリュームの作成

コンテナ起動にボリュームを作成できるため、使用頻度は低いですが、ボリューム単独で作成することもできます。

docker volume creare <ボリューム名>

helloボリュームを作成する場合は以下を実行します。

$ docker volume create hello
hello

ボリュームの削除

<ボリューム名>を指定してコンテナで使用していないボリュームを削除します。

docker volume rm <ボリューム名>

helloボリュームを削除する場合は以下を実行します。

$ docker volume rm hello
hello

コンテナで使用しているボリュームを削除しようとするとエラーになります。

# ボリュームを作成
$ docker volume rm hello
hello
$ docker volume ls
DRIVER    VOLUME NAME
local     hello

# ボリュームをコンテナで使用する
$ docker run -d -v hello:/world busybox
ef22b9ed8a199057d11e9303eb153872d434b56cf098358da6c761f0aca8b201

# 削除しようとするとエラーとなり、使用しているボリュームのコンテナIDが表示される
$ docker volume rm hello
Error response from daemon: remove hello: volume is in use - [ef22b9ed8a199057d11e9303eb153872d434b56cf098358da6c761f0aca8b201]
$ docker volume ls
DRIVER    VOLUME NAME
local     hello
$ ボリュームを使用しているコンテナを削除する
$ docker rm ef22
ef22

# 再度ボリュームの削除を試み、削除できることを確認する
$ docker volume rm hello
hello
$ docker volume ls
DRIVER    VOLUME NAME

ボリュームを使用しているコンテナを調べる(応用)

xargsコマンドとjqコマンドを組み合わせた方法になりますが、以下のようにすることで指定のコンテナ名(.Name == "hello"がボリューム名を指定している箇所)を使用しているコンテナのコンテナIDを調べることができます。

docker ps -aq | xargs docker inspect | jq '.[] | select(.Mounts[]? | .Name == "hello") | .Id'
"21dc45864d5fa616e293f53b9324f1461b0e14f73adbcd57c2801c4a4ea90b31"

Apple Silicon MacのDockerでOracle Databaseを動かす

執筆時点(2023/03/01)での暫定的な対応となる点にご注意ください。将来的にはOracle DatabaseがARMに対応する可能性があります。
Oracle DatabaseのARM対応については、以下の動画の26:40 – 27:22をご覧ください。

Oracle Database: What’s new, what’s next

Apple Silicon MacでOracle Databaseを動かす選択肢はいくつかありますが、よく知られている方法は私の環境ではうまく生きませんでした。

ここでは私の環境で成功した方法を共有します。

この方法は、

で紹介されている方法になります。

手順を実行するためには、

  • Homebrew
  • Docker

が必要となります。

Colimaをインストールする

まずはColimaをインストールします。Dockerの--platform linux/x86_64ではうまくいきませんでしたので、ご注意ください。

$ brew install colima

Homebrewでインストールしますので、インストールしていない場合は先にインストールしてください。

次にColimaを起動します。起動するとDockerのコンテキストが変更されます。

$ colima start --arch x86_64 --memory 4

ここでは参考にした記事と同じく4(GB)のメモリを割り当てていますが、必要に応じて増やしてください。

$ docker context ls
NAME                TYPE                DESCRIPTION                               DOCKER ENDPOINT                                     KUBERNETES ENDPOINT   ORCHESTRATOR
colima *            moby                colima                                    unix:///Users/user1/.colima/default/docker.sock
default             moby                Current DOCKER_HOST based configuration   unix:///var/run/docker.sock                                               swarm
desktop-linux       moby                                                          unix:///Users/user1/.docker/run/docker.sock

現在のコンテキストがcolimaになっていることを確認してください。変更されていない場合は、

$ docker context use colima

で変更してください。

Oracle Databaseを起動する

Oracle DatabaseをDockerで起動します。

$ docker run -d -p 1521:1521 -e ORACLE_PASSWORD=<パスワード> -v oracle-volume:/opt/oracle/oradata gvenzl/oracle-xe

<パスワード>部分は任意のパスワードを設定してください。このパスワードはSYSユーザーとSYSTEMユーザーのパスワードになります。

例えば、パスワードをpasswordにした場合は以下のようになります。

$ docker run -d -p 1521:1521 -e ORACLE_PASSWORD=password -v oracle-volume:/opt/oracle/oradata gvenzl/oracle-xe

すぐに制御が返ってきますので、少し経ったら接続してみましょう。ローカルにSQL*Plusはインストールされていないと思いますので、何かしらのデータベース接続ツールを使用してください。

私はDataGripを使って接続しています。ユーザーはsystem、パスワードは先ほど起動時に設定したパスワードを入力してください。

まとめ

恐らくこれが現状では最も簡単にApple Silicon MacでOracle Databaseを動作させる方法だと思います。将来的にはVirtualBoxなどでもっと簡単にOracle Databaseを動作させることができるようになる可能性がありますので、暫定的な対応とお考えください。

sudoなしでdockerコマンドを実行できるようにする(dockerグループへユーザーを追加)

dockerコマンドを実行するときにsudoをつけずに実行できるようにする方法について解説します。

一般ユーザーがsudoなしで実行できるのは好ましい設定ではありません。本設定はローカル環境での利用にとどめ、ほかの人と共有して使用するサーバーや本番環境では、誤ってコンテナを停止してしまうなどの事故を防ぐためsudoを使用して操作することを推奨します。

ユーザーをdockerグループに追加する

手順自体はとてもシンプルですが、一つずつ確認していきます。

dockerグループの確認

まずはdockerグループがあるか確認します。

$ cat /etc/group | grep docker                                                                                                                                                           
docker:x:957:

Dockerのインストール方法にもよりますが、たいていはdockerグループが存在しています。

dockerグループが存在しない場合(コマンドを実行しても何も表示されない場合)は、以下のコマンドを実行してdockerグループを作成してください。

$ sudo groupadd docker

ユーザーをdockerグループに追加する

gpasswdコマンドを使ってdockerコマンドを使用したいユーザーをdockerグループに追加します。現在のユーザーを追加したい場合は以下のように実行します。

$ sudo gpasswd -a $USER docker                                                                                                                                                         
[sudo] password for xxx: 
Adding user xxx to group docker

現在のユーザー以外を追加したい場合は、$USERの部分を対象のユーザーに置き換えてください。

dockerデーモンを再起動する(dockerグループを作成した場合のみ)

dockerグループを作成した場合は、dockerデーモンの再起動が必要な場合があります。

systemctlを使用している場合は、以下のコマンドを実行します。

$ sudo systemctl restart docker                                                                                                                                                         
[sudo] password for xxx: 

ローカル環境で再起動しても問題ないのであれば、再起動していただいても構いません。

ログアウトして再度ログインする

前の手順で再起動している方はそのままログインしてください。それ以外の場合は一度ログアウトしてから、再度ログインしてください。

以上で、sudoなしでdockerコマンド(docker-composeコマンドも)が実行できるようになります。

なぜPermission deniedになるのか

そもそも、なぜdockerコマンドをsudoなしで実行するとPermission deniedになるかというと、dockerデーモンがUnixソケットを使用しており、dockerデーモンがrootユーザーで実行しているためです。

$ ls -l /var/run/docker.sock
srw-rw----  1 root    docker     0 Mar 19 09:51 docker.sock

実際に/var/run/docker.sockを見てみると、rootユーザーが所有者になっていることがわかります。

このことから、dockerデーモンと通信するdockerコマンドの実行には、docker.sockを読み取ることのできるrootユーザーまたはrootユーザー相当の権限が必要なため、sudoを使用します。

一方で、グループはdockerになっており、同様に読み取り権限があるため、ユーザーをdockerグループに追加することで、sudoを使用したときと同様にdockerコマンドが使用できるようになるという仕組みです。

モバイルバージョンを終了