概要: 「docker run」コマンドは、Dockerコンテナを起動する際の基本となる命令です。この記事では、`docker run`の基本的な使い方から、`-it`、`–rm`、`-p`、`-e`、`–name`といった主要オプションの具体的な活用法までを解説します。開発や運用における効率的なコンテナ利用のヒントを提供します。
docker runコマンドの全体像と効率的な基本操作
`docker run`コマンドの基本的な仕組みと流れを理解する
`docker run`コマンドは、指定されたDockerイメージを基に新しいコンテナを起動するための中心的な命令です。一見するとシンプルなコマンドですが、その裏側では複数のプロセスが自動的に処理されています。まず、指定されたイメージがローカル環境に存在するか確認し、もしなければDocker Hubなどのレジストリから自動的にダウンロード(`docker pull`に相当)します。次に、そのイメージの上に書き込み可能な「コンテナレイヤー」を生成することで、隔離された実行環境(コンテナ)を作成します。最後に、このコンテナ内で指定されたコマンド(またはイメージに定義されたデフォルトコマンド)を実行し、プロセスを開始します。
この一連の動作により、ユーザーは手動でイメージのダウンロードやコンテナの作成、起動といったステップを踏む必要がなく、たった一つのコマンドでアプリケーション環境を瞬時に立ち上げることが可能になります。この効率性が、クラウドネイティブな開発やデプロイメントにおいてDockerが標準技術として広く採用されている理由の一つです。
出典:docker run — Docker-docs-ja 24.0 ドキュメント
最小限のオプションでコンテナを起動し動作を確認する
`docker run`コマンドの最も基本的な使い方は、イメージ名を指定するだけです。例えば、テスト目的で「Hello World」を表示するコンテナを起動したい場合、`docker run hello-world`と入力します。このコマンドを実行すると、まず`hello-world`イメージがローカルになければダウンロードされ、その後コンテナが起動してプログラムが実行されます。実行が完了すると、コンテナは自動的に終了します。実行後のコンテナの状態を確認するには、`docker ps -a`コマンドを使用します。これにより、停止したコンテナも含め、すべてのコンテナのリストが表示され、`hello-world`コンテナが正常に起動・終了したことが確認できます。
開発や検証で一時的にコンテナを起動したい場合は、コマンド実行後にコンテナを自動的に削除する`–rm`オプションが非常に便利です。例えば、`docker run –rm hello-world`と実行すれば、コンテナ終了後にそのコンテナはシステムから自動的に削除され、不要なリソースが残るのを防げます。これにより、環境のクリーンアップの手間を省き、より効率的な開発・検証ワークフローを実現できます。
バックグラウンド実行と実行後のコンテナ管理
Webサーバーやデータベースなど、長時間稼働させるコンテナは、通常バックグラウンドで実行します。これには`-d`(または`–detach`)オプションを使用します。例えば、`docker run -d nginx`と実行すると、Nginxコンテナがバックグラウンドで起動し、コマンドプロンプトがすぐに返ってきます。稼働中のコンテナは`docker ps`コマンドで確認できます。コンテナを停止したい場合は、`docker stop [コンテナ名またはID]`、削除したい場合は`docker rm [コンテナ名またはID]`を使用します。
コンテナに一時的に接続してコマンドを実行したい場合は、`docker exec -it [コンテナ名またはID] bash`のように指定します。これにより、稼働中のコンテナ内でシェルを起動し、内部の状態を確認したり、設定ファイルを編集したりすることが可能です。作業が完了したら`exit`でシェルを終了します。コンテナのライフサイクルを適切に管理することは、安定した開発・運用環境を維持するために不可欠です。
主要オプションの機能と具体的な使い方
ホストとコンテナ間のネットワーク通信とファイル共有を設定する
コンテナ内のサービスをホストOSや外部から利用するには、ポートフォワーディングの設定が必要です。`-p`オプションを使用して、`ホストポート:コンテナポート`の形式で指定します。例えば、`docker run -p 8080:80 nginx`と実行すると、ホストOSの8080番ポートへのアクセスが、コンテナ内のNginxが稼働する80番ポートに転送されます。これにより、ブラウザから`http://localhost:8080`でコンテナ内のWebサーバーにアクセスできるようになります。
また、ホストOSとコンテナ間でファイルを共有するには`-v`オプション(ボリュームマウント)を使用します。`ホストパス:コンテナパス`の形式で指定し、例えば`docker run -v ~/app/data:/var/www/html nginx`とすると、ホストの`~/app/data`ディレクトリがコンテナの`/var/www/html`にマウントされ、ファイルが双方向で同期されます。これにより、ホスト側でソースコードを編集し、リアルタイムでコンテナ内のアプリケーションに反映させることが可能になり、開発効率が大幅に向上します。
コンテナの環境設定とネットワークを柔軟に制御する
コンテナ内でアプリケーションが利用する環境変数を設定するには、`-e`オプション(または`–env`)を使用します。例えば、データベース接続情報をコンテナに渡したい場合、`docker run -e DB_HOST=mydb -e DB_USER=user app_image`のように指定します。これにより、コンテナ内部のアプリケーションは指定された環境変数から値を取得し、柔軟に動作を変更できます。パスワードなどの機密情報は、より安全なSecrets管理の仕組みを検討することも推奨されます。
複数のコンテナ間で通信を行う場合や、特定のネットワーク設定を適用したい場合は、`–network`オプションが役立ちます。事前に`docker network create my_network`でカスタムネットワークを作成し、`docker run –network my_network db_image`のようにコンテナを接続します。これにより、同じネットワーク内のコンテナ同士はコンテナ名で相互に通信できるようになり、複雑なマルチコンテナアプリケーションの構成が容易になります。デフォルトの`bridge`ネットワークとは異なり、コンテナ間のIPアドレスを意識することなく、より安全で管理しやすい環境を構築できます。
コンテナの識別とインタラクティブな操作を可能にする
コンテナには自動的にIDが割り振られますが、これを人間が識別しやすい名前に変更するには`–name`オプションを使用します。例えば、`docker run –name my-web-server -d nginx`と実行すると、このNginxコンテナは`my-web-server`という名前で管理できるようになります。これにより、`docker stop my-web-server`や`docker logs my-web-server`のように、IDではなく名前で操作が可能になり、特に多数のコンテナを扱う場合に管理の効率が格段に向上します。
開発やデバッグの際、コンテナの内部で直接コマンドを実行したい場合は、`-it`オプションを使用します。`-i`(または`–interactive`)は標準入力に接続し、`-t`(または`–tty`)は疑似ターミナルを割り当てます。この二つを組み合わせることで、`docker run -it ubuntu bash`のようにコンテナを起動し、そのコンテナ内で直接シェル操作を行うことが可能になります。これにより、コンテナ内のファイルシステムを探索したり、プログラムを手動で実行したりといったインタラクティブなデバッグ作業が行えます。
`docker run`コマンドのオプションは、コンテナの「イメージ開発者が設定したデフォルト値」や「Dockerランタイムの標準設定」を、実行時にオーバーライド(上書き)するためのものです。これにより、同じイメージからでも多様な環境要件に対応したコンテナを柔軟に起動できます。
ただし、オプションが多岐にわたるため、意図しない設定ミスが発生する可能性もあります。実行前には必ず公式ドキュメントやイメージの提供元が推奨する設定を確認し、セキュリティ面にも十分な配慮が必要です。不必要な権限を与えない、機密情報を直接オプションに含めないといった対策を心がけましょう。
開発・運用で役立つdocker run実践活用例
開発環境構築における`docker run`の活用
開発環境の構築において`docker run`は絶大な威力を発揮します。例えば、特定のプログラミング言語のバージョンやデータベースのバージョンを、ホストOSに直接インストールすることなく、コンテナとして隔離して実行できます。これにより、異なるプロジェクトで異なるバージョンのNode.jsやPython、PostgreSQLなどが必要な場合でも、互いに干渉することなく並行して開発を進めることが可能です。
具体的な例として、Node.jsのバージョン18が必要なプロジェクトでは`docker run -it –rm node:18 bash`で一時的な環境を立ち上げ、バージョン20が必要な別のプロジェクトでは`docker run -it –rm node:20 bash`とすることで、簡単に環境を切り替えられます。また、`docker run -d –name my-dev-db -e POSTGRES_PASSWORD=mysecret postgres:14`のようにデータベースを起動し、アプリケーションからそのコンテナに接続することで、開発者はDBのインストールや設定に時間を費やすことなく、すぐに開発に着手できます。
CI/CDパイプラインでの自動テスト実行
継続的インテグレーション/継続的デリバリー(CI/CD)パイプラインにおいて、`docker run`は自動テストの実行環境を構築するために不可欠です。CIツール(Jenkins, GitLab CI, GitHub Actionsなど)は、新しいコードがプッシュされるたびに、クリーンな環境でテストを実行する必要があります。この際、`docker run`コマンドを使って、テストに必要な依存サービス(例: データベース、キャッシュサーバー、特定のブラウザ環境)を一時的に起動します。
例えば、Webアプリケーションの結合テストを行う前に、`docker run -d –name test-db -e MYSQL_ROOT_PASSWORD=root mysql:8.0`でMySQLコンテナを起動し、テスト実行中にアプリケーションがこのデータベースに接続するように設定します。テストが完了したら、`docker stop test-db && docker rm test-db`でコンテナを停止・削除することで、テスト環境が常にクリーンな状態に保たれ、テスト結果の信頼性が向上します。これにより、環境依存によるテストの失敗を防ぎ、開発者はコードの品質に集中できます。
一時的なツール実行やデータ処理での応用
特定のCLIツールやデータ処理スクリプトを一時的に実行したい場合にも`docker run`は非常に有効です。ホストOSにツールをインストールすることなく、必要な時だけコンテナを起動して利用できるため、ホスト環境を汚染することなく、依存関係の問題も回避できます。これは特に、あまり頻繁に使わないツールや、特定のバージョンのツールを使いたい場合に便利です。
例として、画像ファイルの形式を一括変換するツールを使いたい場合、`docker run –rm -v $(pwd):/app custom-image-converter image_tool.sh input.jpg output.png`のように実行できます。このコマンドでは、カレントディレクトリをコンテナ内にマウントし、その中の画像ファイルに対してコンテナ内の変換ツールを実行しています。また、`docker run –rm alpine/git clone https://github.com/example/repo.git`のように、`alpine/git`イメージを使ってGitリポジトリをクローンするといった使い方も可能です。これにより、特定のツールをホストにインストールする手間や、バージョン管理の煩雑さから解放されます。
docker run利用時のよくある課題と対処法
イメージが見つからない、またはコンテナが起動しない場合の確認点
`docker run`実行時に「Unable to find image ‘…’ locally」や「Error response from daemon: No such image」といったエラーが表示される場合、指定したイメージがローカルに存在しないか、名前のスペルミスが考えられます。まずはイメージ名が正しいか確認し、必要であれば`docker pull [イメージ名]`で手動でダウンロードを試みます。それでも解決しない場合は、Docker Hubなどのレジストリでイメージ名が正しいか、またはプライベートレジストリからの取得で認証情報に問題がないかを確認します。
コンテナが起動直後に終了してしまう場合は、内部で実行されるコマンドに問題がある可能性があります。`docker ps -a`で終了したコンテナのIDを確認し、`docker logs [コンテナID]`でログを確認してください。ログには、アプリケーションのエラーや、コンテナ内で実行されるコマンドが見つからない(`executable file not found`)などの原因が示されていることが多いです。また、`-d`オプションでバックグラウンド実行しているつもりが、実際はフォアグラウンドで動作するアプリケーションがなく、すぐに終了しているケースもあります。このような場合は、`docker run -it [イメージ名] bash`でインタラクティブにコンテナに入り、手動でコマンドを実行して動作を確認すると良いでしょう。
ポートの衝突やボリュームマウントの失敗への対処
「Bind for 0.0.0.0:8080 failed: port is already allocated」のようなエラーは、ホストOSの指定したポートが既に他のプロセスによって使用されていることを意味します。この場合、`-p`オプションで異なるホストポートを指定するか、既存のプロセスを停止してポートを解放する必要があります。例えば、`docker run -p 8081:80 nginx`のようにホスト側のポート番号を変更します。どのプロセスがポートを使用しているかは、OSのコマンド(例: Linux/macOSなら`lsof -i :8080`、Windowsなら`netstat -ano | findstr :8080`)で確認できます。
ボリュームマウントが期待通りに動作しない場合は、パスの指定ミスやホスト側のファイル権限に問題がある可能性があります。`docker run -v /wrong/path:/app/data image`のようにホストパスが存在しない場合、Dockerは自動的にそのディレクトリを作成しますが、そこにファイルが存在しないため、コンテナからは空に見えます。ホスト側のパスが正しいか、またDockerユーザーがそのパスへの読み書き権限を持っているかを確認してください。また、コンテナ内のパスも、アプリケーションが想定している正しい場所にマウントされているかを検証することが重要です。
コンテナ内のログ確認とデバッグの基本
コンテナで問題が発生した場合、まず最初に行うべきはコンテナのログを確認することです。`docker logs [コンテナ名またはID]`コマンドを使用すると、コンテナの標準出力(stdout)と標準エラー出力(stderr)の内容が表示され、アプリケーションのエラーメッセージや警告、デバッグ情報などを確認できます。`-f`オプションを付けると、リアルタイムでログを追跡できるため、コンテナの起動中に何が起きているかを把握するのに役立ちます。
ログだけでは原因が特定できない場合、`docker exec -it [コンテナ名またはID] bash`(または`sh`)を使用して、実行中のコンテナの内部に接続し、シェル環境で直接調査します。コンテナ内でファイルシステムを探索したり、`ps aux`でプロセスを確認したり、`ping`コマンドでネットワーク接続をテストしたりすることで、問題の原因を絞り込むことが可能です。また、コンテナを起動する際にデバッグモードを有効にする環境変数を`-e`オプションで渡すことも有効なデバッグ手法となります。
`docker run`トラブルシューティングの基本チェックリスト
- イメージ名の確認: スペルミスやタグの誤りはないか?
- ログの確認: `docker logs [コンテナ名/ID]`でエラーメッセージをチェックしたか?
- ポートの競合: `-p`で指定したホストポートが使用中でないか?
- ボリュームパス: `-v`で指定したホスト/コンテナパスは正しいか、権限はあるか?
- 環境変数: `-e`で必要な環境変数が正しく設定されているか?
- コンテナ内部調査: `docker exec -it [コンテナ名/ID] bash`で内部に入り状況を確認したか?
- 公式ドキュメント: 使用しているイメージの公式ドキュメントを参照したか?
【ケース】コンテナ設定ミスから学ぶトラブルシューティング
架空のケース:Webアプリケーションが外部からアクセスできない
ある日、開発チームのAさんが新しいWebアプリケーションをDockerコンテナで起動しました。`docker run -d –name my-web app_image`と実行し、コンテナは問題なく起動したように見えました。しかし、ブラウザで`http://localhost:80`にアクセスしても「サイトにアクセスできません」というエラーが表示され、Webアプリケーションが表示されません。`docker ps`で確認すると、`my-web`コンテナは確かに稼働していますが、PORTS欄が空になっています。
このケースでの原因は、ポートフォワーディングオプション`-p`の指定漏れです。`docker run`コマンドで`-p`オプションを指定しない場合、コンテナ内部のポートは外部に公開されません。このため、コンテナ内でWebサーバー(例: ポート80)が起動していても、ホストOSや外部からそのポートにアクセスすることはできません。Aさんは、`docker stop my-web && docker rm my-web`で既存のコンテナを停止・削除し、新たに`docker run -d –name my-web -p 80:80 app_image`と実行し直しました。これにより、ホストOSの80番ポートがコンテナの80番ポートにマッピングされ、無事にWebアプリケーションにアクセスできるようになりました。
架空のケース:データベースコンテナが起動直後に終了してしまう
Bさんは、ローカル開発環境としてPostgreSQLデータベースをコンテナで起動しようとしました。`docker run -d –name my-postgres postgres:14`と実行したところ、`docker ps`ではコンテナが表示されず、`docker ps -a`で確認すると`Exited (1) …`と表示され、起動直後に終了していることが分かりました。`docker logs my-postgres`でログを確認したところ、「FATAL: password authentication failed for user “postgres”」というエラーメッセージが大量に出力されていました。
この原因は、PostgreSQLイメージの必須環境変数である管理者パスワード(`POSTGRES_PASSWORD`)が設定されていなかったことです。PostgreSQLイメージは、デフォルトで`postgres`ユーザーのパスワード設定を要求します。Bさんは、既存のコンテナを停止・削除し、今度は`docker run -d –name my-postgres -e POSTGRES_PASSWORD=mysecretpassword postgres:14`と、`-e`オプションで環境変数を指定して再実行しました。これにより、データベースコンテナは正常に起動し、稼働状態を維持することができました。このようなケースでは、使用するDockerイメージの公式ドキュメントで、どのような環境変数が必須か、または推奨されているかを事前に確認することが重要です。
架空のケース:ボリュームマウントした設定ファイルが反映されない
Cさんは、Nginxコンテナでカスタム設定ファイルを使用するため、ホストOS上の`./nginx.conf`ファイルをコンテナの`/etc/nginx/nginx.conf`にボリュームマウントしようとしました。`docker run -d –name my-nginx -p 80:80 -v ./nginx.conf:/etc/nginx/nginx.conf nginx`と実行し、ブラウザでアクセスすると、期待したカスタム設定ではなくデフォルトのNginxページが表示されてしまいます。
原因を調査すると、Cさんはホスト側のパスを誤って指定していたことが判明しました。具体的には、ホストの`./nginx.conf`は存在せず、代わりに`./conf/nginx.conf`にファイルがありました。`docker run`コマンドで指定したホスト側のパスが存在しない場合、Dockerはそのパスを空のディレクトリとして作成し、マウントしてしまうことがあります。結果として、コンテナ内の`/etc/nginx/nginx.conf`は空のディレクトリとして扱われ、Nginxはデフォルトの設定を読み込んでいました。
Cさんは、`docker stop my-nginx && docker rm my-nginx`でコンテナを停止・削除後、正確なパスである`docker run -d –name my-nginx -p 80:80 -v $(pwd)/conf/nginx.conf:/etc/nginx/nginx.conf nginx`と修正して再実行しました。これにより、正しい設定ファイルがコンテナにマウントされ、期待通りのNginxの動作が確認できました。ボリュームマウントのパスは、ホスト側とコンテナ側の両方で正確に指定し、特にホスト側のファイルやディレクトリが存在するかを事前に確認することが、この種のトラブルを防ぐ鍵となります。
まとめ
よくある質問
Q: docker runとdocker execの違いは何ですか?
A: `docker run`は新しいコンテナを作成・起動しますが、`docker exec`は既存の起動中コンテナ内でコマンドを実行します。用途が異なるため、状況に応じて使い分けが必要です。
Q: docker run -itの-iと-tはどんな役割ですか?
A: `-i`は標準入力を開いたままにする対話モードを有効に、`-t`は擬似端末を割り当て、ユーザーがターミナル操作できるようにします。両方で対話的なシェル操作が可能です。
Q: コンテナ終了後に自動削除するにはどうしますか?
A: `–rm`オプションを使用すると、コンテナが停止した際に自動で削除されます。一時的なコンテナや使い捨てのテスト環境でリソースを節約するのに便利です。
Q: 起動時にコンテナ名を指定するメリットは?
A: `–name`オプションでコンテナ名を指定すると、ランダムなIDではなく認識しやすい名前で管理できます。特定のコンテナの操作や識別が容易になり、コマンド入力ミスも減らせます。
Q: 外部から特定のポートでコンテナにアクセスするには?
A: `-p`オプションでポートマッピングを設定します。例えば`-p 8080:80`とすると、ホストの8080番ポートがコンテナの80番ポートに転送され、外部からのサービス利用が可能になります。
