---
title: "Dockerコンテナ起動・実行コマンドの使い分け｜run・start・execと起動しない時の対処"
url: "https://www.issoh.co.jp/tech/details/3935/"
published: 2024-10-23
updated: 2026-10-19
categories: ["Kubernetes・コンテナ"]
publisher: "株式会社一創"
---

# Dockerコンテナ起動・実行コマンドの使い分け｜run・start・execと起動しない時の対処

Dockerコンテナの起動でよくあるつまずきは、**「コンテナを作る」と「コンテナを動かす」が別の操作**だと知らずに、毎回 `docker run` を打ってしまうことです。`docker run` は作成と起動をまとめて行うコマンドで、既存のコンテナを動かすのは `docker start`、動いているコンテナの中でコマンドを実行するのは `docker exec` です。この記事では3つの使い分けに加え、起動しないときの終了コードとエラー文言、自動起動、Docker Composeの起動待ちまでを、Docker Engine 29.5.2・CLI 29.9.0・Compose 5.6.0で実際に打った結果つきで整理します（2026年10月時点のEngine最新は29.9.1）。

## まとめ

- **イメージから新しく作って動かす**なら `docker run`。名前を指定せず、終了時の自動削除も指定しない場合は、2回実行すると別々のコンテナが残ります。
- **停止中・作成済みのコンテナを動かす**なら `docker start`（正式名は `docker container start`）。対話シェルへ戻るなら `docker start -ai <名前>` です。
- **動いているコンテナに入る・中でコマンドを実行する**なら `docker exec -it <名前> sh`。停止中・一時停止中のコンテナには使えません。
- **起動しない**ときは `docker ps -a` のSTATUS列と終了コード、次に `docker logs` を見ます。125はdockerコマンド自体の失敗、126・127は起動コマンドの誤り、137は強制終了です。
- **ホスト再起動後も自動で立ち上げる**なら `--restart unless-stopped`。既存コンテナには `docker update --restart` で後付けできます。
- **複数コンテナ**は `docker compose up -d`。DBの準備完了を待たせるには `healthcheck` と `condition: service_healthy` が必要です。

## run・create・start・execの使い分け

コンテナは「イメージ → 作成済み（Created）→ 実行中（Up）→ 停止（Exited）」と状態を移ります。どの状態からどの状態へ動かしたいかで、打つコマンドが決まります。

| やりたいこと         | コマンド             | 状態の変化               |
| -------------- | ---------------- | ------------------- |
| イメージから作って動かす   | `docker run`     | イメージ → Up           |
| 作るだけ（まだ動かさない）  | `docker create`  | イメージ → Created      |
| 作成済み・停止中を動かす   | `docker start`   | Created・Exited → Up |
| 動いているコンテナで作業する | `docker exec`    | Upのまま（プロセスを追加）      |
| 止めて動かし直す       | `docker restart` | Up → Exited → Up    |

### docker runによるコンテナの新規作成・起動

```
# nginxをバックグラウンド起動し、ホストの8080をコンテナの80へ転送
docker run -d --name web -p 8080:80 nginx:alpine

# 対話シェルで起動し、終了したらコンテナごと削除
docker run -it --rm ubuntu:24.04 bash
```

| オプション              | 意味                          |
| ------------------ | --------------------------- |
| `-d`               | バックグラウンドで実行                 |
| `--name web`       | 名前を固定する（start・exec・stopで使う） |
| `-p 8080:80`       | ホスト8080をコンテナ80へ公開           |
| `-it`              | 標準入力と疑似端末をつなぐ（シェル用）         |
| `-v "$(pwd)":/app` | ホストのディレクトリをマウント             |
| `-e KEY=value`     | 環境変数を渡す                     |
| `--rm`             | 終了時にコンテナを削除                 |

`--name` を付けないと `gifted_leavitt` のようなランダム名が付き、実測でも `docker run alpine:3 true` を2回打つと別名のExitedコンテナが2つ残りました。名前を固定したまま同じ `docker run` を打ち直すと、終了コード125で次のエラーになります。

```
docker: Error response from daemon: Conflict. The container name "/web" is already in use by container "fd243afe...". You have to remove (or rename) that container to be able to reuse that name.
```

このエラーが出たら、既存コンテナを `docker start web` で動かすのが正解です。設定を変えたいときだけ `docker rm web` してから作り直します。

### docker createとdocker startによる作成・起動の分離

ポート公開やマウントは**作成時にしか指定できません**。設定を固めたコンテナを先に作り、必要なときに起動する使い方ができます。

```
# 作成のみ（STATUSは Created）
docker create --name batch -e TZ=Asia/Tokyo alpine:3 sleep 3600

# 起動する
docker start batch

# 起動して標準出力をつなぐ（終わるまで戻らない）
docker start -a batch
```

`docker run -it ubuntu:24.04 bash` で作ったコンテナを `exit` で抜けると、シェルが終わるのでコンテナも止まります。同じコンテナでシェルを起動し直して接続するには `docker start -ai <名前>` を使います。`-a` は出力、`-i` は標準入力をつなぐオプションです（[docker container start](https://docs.docker.com/reference/cli/docker/container/start/)）。なお実行中のコンテナに `docker start` を打ってもエラーにはならず、終了コード0で何も起きません。

## docker execでコンテナに入る方法とコマンド実行

「コンテナに入る」とは、**実行中のコンテナの中でシェルのプロセスを追加で起動する**ことです。メインプロセスには触れないので、抜けてもコンテナは止まりません。

```
# シェルを開く（bashが無いalpine系は sh）
docker exec -it web sh

# 単発のコマンドだけ実行する
docker exec web nginx -t

# ユーザー・作業ディレクトリ・環境変数を指定して実行
docker exec -u 1000 -w /tmp -e DEBUG=1 web sh -c 'id -u; pwd'
```

停止中と一時停止中のコンテナには入れません。実測したエラーは次のとおりで、どちらも終了コードは1です。

| 状態             | docker exec のエラー                                            | 対処                       |
| -------------- | ----------------------------------------------------------- | ------------------------ |
| Created・Exited | container <ID> is not running                               | `docker start` してから exec |
| Paused         | Container <名前> is paused, unpause the container before exec | `docker unpause`         |
| 存在しない          | No such container: <名前>                                     | `docker ps -a` で名前を確認    |

### docker attach との違いとデタッチ

`docker attach` はメインプロセス（PID 1）の入出力に直接つなぐコマンドです。メインプロセスがシェルなら、そこで `exit` を実行するとコンテナも終了します。`Ctrl-C` で終了するかは、端末設定やプロセスのSIGINT処理によって異なります。動かしたまま抜けるデタッチキー `Ctrl-P` `Ctrl-Q` が効くのは、`-i` と `-t` を付けて起動したコンテナだけです（[docker container attach](https://docs.docker.com/reference/cli/docker/container/attach/)）。作業が目的なら attach ではなく exec を使ってください。

## 起動しない・すぐ終了するときの切り分け

推測でコマンドを打ち直す前に、STATUS列・終了コード・ログの3点を確認します。

```
docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
docker logs --tail 50 web
docker inspect -f '{{.State.Status}} {{.State.ExitCode}} {{.State.OOMKilled}}' web
```

### STATUS列の読み方

`docker ps -a` のSTATUS列は状態ごとに次のように出ます（Engine 29.5.2で実測）。`docker inspect` の `State.Status` は created・running・paused・restarting・removing・exited・dead のいずれかです。

| STATUS列の表示                            | State.Status | 意味                          |
| ------------------------------------- | ------------ | --------------------------- |
| Created                               | created      | 作成済みで未起動。起動に失敗した run もここに残る |
| Up 11 seconds                         | running      | 実行中                         |
| Up Less than a second (Paused)        | paused       | 一時停止中。exec不可                |
| Restarting (1) Less than a second ago | restarting   | 再起動ポリシーで再起動を繰り返している         |
| Exited (0) 2 seconds ago              | exited       | 停止。括弧内が終了コード                |

`Exited (0)` はエラーではなく、メインプロセスが終わっただけです。`ubuntu:24.04` の既定コマンドは `/bin/bash` なので、`docker run -d ubuntu:24.04` は端末が無いまま bash が即終了し、2秒後には Exited (0) でした。`-dit` を付けると Up のまま残ります。常駐させたいなら、サーバーをフォアグラウンドで動かすイメージかコマンドを指定します。

### 終了コード別の原因

以下は、主にフォアグラウンド実行した `docker run` の終了値と、その実測例です。CLIの終了値と `docker inspect` の `State.ExitCode` は別の情報で、名前衝突などの125を既存コンテナの終了コードから判定することはできません。また、アプリが同じ数値を明示的に返す場合もあるため、数値だけで原因を確定せず、エラーメッセージとログを照合します。

| 終了コード | 意味              | 実測した例                              |
| ----- | --------------- | ---------------------------------- |
| 0     | 正常終了            | nginxは docker stop でも0             |
| 1〜124 | アプリ自身のエラー       | `sh -c 'exit 3'` は3                |
| 125   | dockerコマンド自体の失敗 | 未知のオプション・名前衝突・ポート衝突                |
| 126   | コマンドを実行できない     | 実行権限の無いファイルを指定                     |
| 127   | コマンドが見つからない     | executable file not found in $PATH |
| 137   | SIGKILLで終了      | 停止猶予切れ・`-m 8m` でOOM                |
| 143   | SIGTERMで終了      | `--init` 付きの sleep を stop          |

126・127で失敗した `docker run` は、コンテナが **Created のまま残り、名前を占有します**。コマンドを直して打ち直すと名前衝突の125になるので、先に `docker rm` します。メモリ不足かどうかは `State.OOMKilled` が true かで判別できます。

### 頻出エラーと対処

| エラーメッセージ（冒頭）                                                  | 原因             | 対処                             |
| ------------------------------------------------------------- | -------------- | ------------------------------ |
| port is already allocated                                     | ホスト側ポートが使用中    | 別ポートで作り直す                      |
| The container name … is already in use                        | 同名コンテナが残っている   | 既存を start、または rm               |
| executable file not found in $PATH                            | 起動コマンドの誤り（127） | コマンド名・パスを確認                    |
| exec format error                                             | CPUアーキテクチャ不一致  | ホスト対応イメージへ変更。異種CPUはエミュレーションも確認 |
| `conflicting options: cannot specify both --restart and --rm` | 併用不可の指定        | どちらかを外す                        |

ポート衝突には落とし穴があります。`docker run -p 18080:80` が衝突で失敗するとコンテナは Created で残り、そのコンテナに `docker start` をもう一度打つと、Engine 29.5.2では**終了コード0で起動するのにポートが公開されませんでした**（PORTS列が空、衝突相手を止めた後の restart でも空のまま）。衝突したら start で再挑戦せず、`docker rm` して別ポートで作り直してください。

### Dockerデーモンへの接続エラーと対処

CLI 29系では、デーモンへの接続失敗の文言が原因ごとに分かれています（moby の [client/request.go](https://github.com/moby/moby/blob/master/client/request.go)）。

| エラーの冒頭                                                                 | 原因        | 対処              |
| ---------------------------------------------------------------------- | --------- | --------------- |
| failed to connect to the docker API at …; check if the path is correct | ソケットが無い   | デーモン起動・コンテキスト確認 |
| permission denied while trying to connect to the docker API            | ソケットの権限不足 | dockerグループへ追加   |
| Cannot connect to the Docker daemon at …                               | 接続拒否      | デーモンを起動         |

1つ目は「デーモンが止まっている」だけでなく、**CLIが別のソケットを見ている**ときにも出ます。今回の検証機でも、Colimaは動いていたのに既定コンテキストが `/var/run/docker.sock` を指していてこのエラーになりました。`docker context ls` で現在のコンテキストを確認し、`docker context use colima` のように切り替えます。Colimaの設定は[Colimaとは？MacでDocker Desktopを外す導入手順と設定の落とし穴【0.10系】](/tech/details/17842/)にまとめています。

```
# Linux：デーモンを起動し、OS起動時にも自動起動
sudo systemctl enable --now docker

# Linux：sudoなしで使う（dockerグループはroot相当の権限を持つ）
sudo usermod -aG docker $USER
newgrp docker

# Docker Desktop：GUIを開かずに起動・状態確認
docker desktop start
docker desktop status
```

dockerグループは root 相当の権限を与えると公式が注意しています（[Linux post-installation steps](https://docs.docker.com/engine/install/linux-postinstall/)）。共用サーバーでは安易に追加しないでください。`docker desktop` コマンドは [Docker Desktop CLI](https://docs.docker.com/desktop/features/desktop-cli/) の機能で、Desktopの要件やライセンスは[Docker Desktopの導入手順とライセンス境界｜4.89系の要件と無料代替への移行](/tech/details/17442/)で扱っています。

## 停止・再起動・削除と終了の猶予

`docker stop` はメインプロセスに停止シグナル（既定SIGTERM、イメージの `STOPSIGNAL` で変わる）を送り、猶予を過ぎるとSIGKILLで落とします。猶予の既定は**Linuxコンテナで10秒、Windowsコンテナで30秒**です（[docker container stop](https://docs.docker.com/reference/cli/docker/container/stop/)）。

```
docker stop -t 60 db      # 猶予60秒で停止
docker restart web        # stop して start
docker rm batch           # 停止中のコンテナを削除
docker rm -f web          # 実行中でも強制削除（猶予なし）
docker container prune    # 停止中のコンテナをまとめて削除
```

### docker stopの停止時間とPID 1のシグナル処理

同じ `docker stop` でも、かかる時間と終了コードはメインプロセスによって変わります。

| コンテナ                        | stopにかかった時間 | 終了コード |
| --------------------------- | ----------- | ----- |
| `alpine:3 sleep 300`        | 10.4秒       | 137   |
| `--init alpine:3 sleep 300` | 0.3秒        | 143   |
| `nginx:1.30.6-alpine`       | 0.3秒        | 0     |

PID名前空間のPID 1は、原則としてハンドラを設定したシグナルだけを受け取りますが、祖先のPID名前空間から送るSIGKILLとSIGSTOPは例外です（[pid\_namespaces(7)](https://man7.org/linux/man-pages/man7/pid%5Fnamespaces.7.html)）。`sleep` はSIGTERMを無視して10秒待たされ、SIGKILLで137になります。`--init` はシグナルを中継する init を PID 1 に置くので、sleep が即座に終わります。nginx はイメージの `STOPSIGNAL` が SIGQUIT で、自分で終了処理をして0を返します。**stopのたびに10秒待たされ137で終わるなら、停止シグナルへの応答や終了処理が猶予内に完了していない可能性があります**。`--init` を付けるか、Dockerfile の `CMD` をシェル形式から exec 形式（JSON配列）に変えます。Dockerfileの書き方は[Dockerfileとは｜書き方・主要命令・ベストプラクティスを解説【2026年版】](/tech/details/3315/)で解説しています。

## 再起動ポリシーによるホスト起動時の自動起動

再起動ポリシーは `--restart` で指定し、値は4種類です（[Start containers automatically](https://docs.docker.com/engine/containers/start-containers-automatically/)）。

| ポリシー             | 挙動                          | 使いどころ      |
| ---------------- | --------------------------- | ---------- |
| `no`             | 再起動しない（既定）                  | 検証・使い捨て    |
| `on-failure:3`   | 異常終了時に最大3回。デーモン再起動時は対象外     | バッチ・ジョブ    |
| `always`         | 常に再起動。手動停止してもデーモン再起動で復活     | 止めることがない常駐 |
| `unless-stopped` | alwaysと同じ。ただし手動停止したものは復活しない | 常駐サービスの既定  |

```
docker run -d --name web --restart unless-stopped -p 8080:80 nginx:alpine

# 既存コンテナに後付け（停止不要）
docker update --restart unless-stopped web
```

迷ったら `unless-stopped` です。`always` だと、メンテナンスで手動停止したコンテナがホスト再起動で勝手に復活します。再起動の間隔は100ミリ秒から倍々に延び、上限は1分です（[docker container run](https://docs.docker.com/reference/cli/docker/container/run/)）。実測では `on-failure:3` で即 `exit 3` するコンテナは3回再起動して `RestartCount` が3になり、Exited (3) で止まりました。`always` の場合はSTATUS列が Restarting (1) と Exited を行き来します。`--rm` とは併用できず、終了コード125で拒否されます。

## Docker Composeによる複数コンテナの一括起動

アプリとDBのように複数のコンテナを使う構成は、`compose.yaml` に定義して `docker compose up -d` で起動します。現在サポートされているCLIはCompose v2とv5で、Docker CLIのプラグインとして入れた場合は `docker compose`（ハイフンなし）で呼びます。Python製のv1は `docker-compose` で呼び出しますが、現行版のスタンドアロン配布も同じコマンド名を使うため、ハイフンの有無だけではバージョンを判別できません（[History and development of Docker Compose](https://docs.docker.com/compose/intro/history/)）。

```
services:
  app:
    image: myapp:1.0   # 自分で用意したアプリのイメージ名へ置き換える
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
  db:
    image: postgres:18
    environment:
      POSTGRES_PASSWORD: example
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 2s
      retries: 10
      start_period: 10s
    restart: unless-stopped
```

```
docker compose up -d        # 一括起動
docker compose up -d app    # appと依存先だけ起動
docker compose ps           # 状態確認
docker compose stop         # 停止（コンテナは残る）
docker compose down         # コンテナとネットワークを削除
```

### depends\_onの指定形式とDBの準備完了待ち

Composeが待つのは依存先が「running」になるところまでで、受け付け可能になるまでは待ちません（[Control startup and shutdown order in Compose](https://docs.docker.com/compose/how-tos/startup-order/)）。起動直後に `pg_isready` でDBへ接続するだけのappを postgres:18 と組み合わせて試すと、差がはっきり出ました。

| depends\_onの書き方              | up -dにかかった時間 | appの結果                    |
| ---------------------------- | ------------ | ------------------------- |
| リスト形式（`- db`）                | 1.4秒         | no response で Exited (1)  |
| `condition: service_healthy` | 9.5秒         | accepting connections で成功 |

DBに接続するサービスは、healthcheck付きの `service_healthy` で書いてください。`docker compose down` はコンテナを消すので、中に入れたパッケージや設定も消えます。一時停止したいだけなら `stop` です。compose.yaml の書き方は[docker-composeとは？複数コンテナをymlで定義し一括管理する仕組みを解説](/tech/details/13282/)で扱っています。

## docker runを再開コマンド代わりに使う運用の事故

障害対応で避けたいのが、**止まったコンテナを再開するつもりで `docker run` を打ち直す**ケースです。これは再開ではなく新規作成なので、Exitedのコンテナが積み上がり、名前を固定していれば125で失敗し、前のコンテナに書き込んだデータは新しいコンテナに引き継がれません。ボリュームを設定していなければ、DBのデータもログもそこにはありません。

判断はシンプルです。**永続データは名前付きボリュームに保存してコンテナの削除・再作成に備え、既存コンテナの再開は `docker start` で行う**。CIや一度きりの検証のように捨てる前提のものは `--rm` を付けて残しません。残すコンテナと捨てるコンテナで、データの保存先と削除方針を分けて管理してください。本番でコンテナを常時動かすなら、ホスト単位の再起動ポリシーだけに頼らず、ECSなどの実行基盤で障害を検知して代替タスクを起動する構成を検討します。復旧時間はヘルスチェックや起動時間の設定で変わります。クラウド上のコンテナ基盤の設計は[インフラ構築（AWS・Google Cloud・Azure）](/service/system/aws/)でご相談いただけます。

## よくある質問

### docker run と docker start の違いは何ですか？

`docker run` はイメージから新しいコンテナを作って起動します。`docker start` は既にある（Created か Exited の）コンテナを起動します。停止したコンテナを再開したいときに run を使うと別のコンテナができ、前のコンテナのデータは引き継がれません。

### 起動中のコンテナに入るにはどうすればよいですか？

`docker exec -it <コンテナ名> bash` を実行します。bashが入っていないalpine系のイメージでは `sh` を指定します。停止中なら先に `docker start` し、一時停止中なら `docker unpause` します。

### 停止したコンテナを起動して、そのままシェルに入るには？

`docker run -it` で作ったコンテナなら `docker start -ai <名前>` で元のシェルに戻れます。メインプロセスがサーバーのコンテナは `docker start <名前>` のあと `docker exec -it <名前> sh` で入ります。

### コンテナの状態（status）はどう確認しますか？

`docker ps -a` のSTATUS列で Created・Up・Exited などを確認できます。スクリプトで判定するなら `docker inspect -f '{{.State.Status}}' <名前>` が created・running・exited などの値を返します。

### Dockerを再起動するコマンドは？

コンテナなら `docker restart <名前>`、Linuxのデーモンなら `sudo systemctl restart docker`、Docker Desktopなら `docker desktop restart` です。既定設定では、デーモン再起動時にコンテナも停止し、再起動ポリシーが `no` なら自動では再開しません。ただし、Linuxコンテナで `live-restore` が有効なら、条件を満たすデーモン再起動中も実行を継続できます。

## 関連記事

- [Dockerとは｜仮想マシンとの違い・必要スペック・Desktop/Engineの違いとインストール手順【2026年10月】](/tech/details/6857/)
- [docker-composeとは？複数コンテナをymlで定義し一括管理する仕組みを解説](/tech/details/13282/)
- [Dockerfileとは｜書き方・主要命令・ベストプラクティスを解説【2026年版】](/tech/details/3315/)
- [Docker Desktopの導入手順とライセンス境界｜4.89系の要件と無料代替への移行](/tech/details/17442/)
- [Dockerの仕組みを図解｜コンテナ隔離・アーキテクチャ・VMとの違いを実機コマンドで確認](/tech/details/2661/)

---

出典: [Dockerコンテナ起動・実行コマンドの使い分け｜run・start・execと起動しない時の対処](<https://www.issoh.co.jp/tech/details/3935/>)（株式会社一創）
