Docker Compose 500

Docker Compose の 500 エラー:原因と解決策

エラーの概要 Docker Compose の 500 エラーは、Docker Compose 自体またはそれが管理するコンテナー内で内部エラーが発生したことを示します。このエラーは通常、コンテナー起動時のアプリケーションクラッシュ、エントリポイント実行の失敗、またはヘルスチェック機構の不具合によって引き起こされます。対象のサービスが正常に起動・稼働できない状態を意味しており、迅速な原因特定と対応が必要です。 実際のエラーメッセージ例 Docker Compose でコンテナーが起動に失敗した際の典型的なエラー出力は以下の通りです。 ERROR: for <service-name> Cannot start service <service-name>: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "<command>": executable file not found in $PATH: unknown または、ヘルスチェック失敗時は以下のように表示されます。 <service-name> | ERROR: Health check failed. Retrying... <service-name> | (Exit status: 1) アプリケーション実行時のエラーログは以下のようなパターンです。 docker-compose logs <service-name> <service-name> | Traceback (most recent call last): <service-name> | File "/app/main.py", line 15, in <module> <service-name> | raise Exception("Database connection failed") <service-name> | Exception: Database connection failed よくある原因と解決手順 原因1:サービスのコンテナー内部でアプリケーションがクラッシュしている コンテナー起動後、アプリケーションが異常終了またはランタイムエラーで落ちてしまう状況です。これは依存関係の欠落、設定ファイルの不在、メモリ不足、または不正な初期化処理によって発生します。 ...

ERROR: for <service-name>  Cannot start service <service-name>: 
OCI runtime create failed: container_linux.go:380: 
starting container process caused: exec: 
2026年5月31日 · ErrorLog
Docker Compose 503

Docker Compose の 503 エラー:原因と解決策

エラーの概要 503エラーは「Service Unavailable」を意味し、Docker Composeでは依存するサービスが正常に起動できていない、または起動完了前にアクセスされている状況を示します。マイクロサービスアーキテクチャではよく発生するエラーで、特に複数コンテナーの起動順序やヘルスチェック設定に起因することが多いです。 実際のエラーメッセージ例 Docker Composeで503エラーが発生した際のログ例を以下に示します。 { "status": 503, "message": "Service Unavailable", "error": "connect ECONNREFUSED 172.20.0.3:5432" } docker compose logs app-service 2024-01-15T10:23:45.123Z ERROR Failed to connect to database: ECONNREFUSED 2024-01-15T10:23:46.456Z WARN Service startup failed, retrying... 2024-01-15T10:23:50.789Z ERROR Max retries exceeded よくある原因と解決手順 原因1:depends_onで依存関係を定義しているが、ヘルスチェック待機を設定していない マイクロサービス構成では、アプリケーションコンテナーがデータベースコンテナーの完全な起動完了を待つ必要があります。docker compose up実行時、デフォルトでは依存するコンテナーが「起動した」ことだけを確認して先に進むため、データベースが受け入れ準備完了する前にアクセスされます。 Before(エラーが起きるコード): version: '3.8' services: postgres: image: postgres:15 environment: POSTGRES_PASSWORD: password ports: - "5432:5432" app: image: myapp:latest depends_on: - postgres ports: - "8080:8080" After(修正後): version: '3.8' services: postgres: image: postgres:15 environment: POSTGRES_PASSWORD: password ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 10s timeout: 5s retries: 5 app: image: myapp:latest depends_on: postgres: condition: service_healthy ports: - "8080:8080" 上記の修正では、service_healthy条件によってPostgresのヘルスチェック成功を待ってからアプリケーション起動が開始されます。 ...

{
  "status": 503,
  "message": "Service Unavailable",
2026年5月31日 · ErrorLog
Docker Compose

Docker Compose の .env 読み込みエラー:UTF-16 BOM問題と解決策

Windows環境でDocker Composeを使う際、PowerShellで作成した.envファイルが原因でコンテナが起動できないケースがあります。エラーメッセージに\xff\xfeやunexpected characterが含まれている場合、ファイルのエンコードが原因です。 エラーの全文 failed to read C:\Users\user\project\.env: line 1: unexpected character "?" in variable name "\xff\xfeG\x00O\x00O\x00G\x00L\x00E\x00_\x00A\x00P\x00I\x00_\x00K\x00E\x00Y\x00=\x00A\x00I\x00z\x00a\x00..." \xff\xfe はUTF-16 LEのBOM(Byte Order Mark)です。続く\x00が各文字の後ろに並んでいることから、ファイル全体がUTF-16 LEで保存されていることがわかります。Docker Composeのenvファイルパーサーは**UTF-8(BOMなし)のみ**を受け付けるため、このファイルを読み込もうとした瞬間にクラッシュします。 よくある原因 PowerShellのechoコマンドはUTF-16 LEで書き出す WindowsのPowerShell(5.1系)では、リダイレクト演算子>やechoコマンドがデフォルトでUTF-16 LE(BOM付き)を使用します。 # これをやってはいけない echo GOOGLE_API_KEY=AIzaSy... > .env # → .envがUTF-16 LE(BOM付き)で保存される Linuxや macOSのシェルと違い、PowerShellは歴史的な経緯からUTF-16をデフォルトエンコードとして採用しています。echoやSet-Contentを使う限り、意識しない限りこの問題が発生します。 VSCodeのエンコード設定が変わっている場合 VSCodeでファイルを新規作成・保存する際、右下のステータスバーが「UTF-16 LE」になっているとDocker Composeが読めないファイルが生成されます。 診断方法 .envファイルの先頭バイトを確認します。 # 先頭4バイトを16進数で確認 $bytes = [System.IO.File]::ReadAllBytes(".env") $bytes[0..3] | ForEach-Object { $_.ToString("X2") } 正常(UTF-8 BOMなし): 47 4F 4F 47 ← "GOOG"の文字コード(例:GOOGLE_API_KEY=...) 異常(UTF-16 LE BOM付き): FF FE 47 00 ← \xff\xfe がBOM、その後\x00が混入 解決手順 方法1:既存の.envファイルをUTF-8に変換する(即時対応) # UTF-16で書かれた.envをUTF-8(BOMなし)に変換して上書き $content = Get-Content ".env" -Encoding Unicode -Raw [System.IO.File]::WriteAllText( (Resolve-Path ".env").Path, $content.Trim() + "`n", [System.Text.UTF8Encoding]::new($false) ) $falseは「BOMを付けない」を意味します。UTF8Encoding::new($true)にするとBOM付きになるため注意してください。 ...

failed to read C:\Users\user\project\.env: line 1: unexpected character "?" in variable name "\xff\xfeG\x00O\x00O\x00G\x00L\x00E\x00_\x00A\x00P\x00I\x00_\x00K\x00E\x00Y\x00=\x00A\x00I\x00z\x00a\x00..."
2026年5月30日 · ErrorLog
Docker Compose 400

Docker Compose の 400 エラー:原因と解決策

エラーの概要 Docker Composeで400エラーが発生する場合、compose.yml(またはdocker-compose.yml)の設定に問題があるか、コマンドのオプション指定が誤っている可能性があります。このエラーはCompose自体が設定ファイルを正しくパースできないことを示しており、設定ファイルの検証とコマンド構文の確認により、ほぼすべてのケースで解決します。 実際のエラーメッセージ例 ERROR: The Compose file './docker-compose.yml' is invalid because: service 'web' has unsupported config option: 'cointainer_name' { "error": "Invalid service configuration", "message": "service 'db' config has unsupported option: 'envrionment'", "code": 400 } Error response from daemon: Ports must be expressed as "port" (a number) or "port/protocol" (a string). よくある原因と解決手順 原因1:compose.ymlのYAML構文エラー(インデント・タブ混在) YAML形式の構文ミスが最も多い原因です。インデント(スペース)の不一致、タブ文字の混在、コロンの後の空白忘れなどが該当します。YAMLはインデントに非常に敏感であり、2文字か4文字のスペースで統一する必要があります。タブ文字を使用するとパーサーが正しく解釈できず、400エラーが発生します。 Before(エラーが起きるコード): version: '3.8' services: web: image: nginx:latest ports: # タブ文字が混在している - "80:80" db: image: postgres:13 # インデントが統一されていない(スペース数が異なる) environment: POSTGRES_PASSWORD: secret After(修正後): version: '3.8' services: web: image: nginx:latest ports: - "80:80" db: image: postgres:13 environment: POSTGRES_PASSWORD: secret 原因2:サービス定義の必須キー不足または値の型エラー serviceセクション内で必須キーが欠けている、または値の型が仕様と異なる場合も400エラーになります。例えば、portsに文字列を指定すべきところに数値を指定したり、environmentをリスト形式で記述すべきところにオブジェクト形式で書いたりすると発生します。また、キー名のタイプミス(cointainer_nameなど)も認識されずエラーとなります。 ...

ERROR: The Compose file './docker-compose.yml' is invalid because:
service 'web' has unsupported config option: 'cointainer_name'
2026年5月30日 · ErrorLog
Docker Compose 401

Docker Compose の 401 エラー:原因と解決策

エラーの概要 Docker Composeで401エラーが発生する場合、コンテナレジストリーへの認証に失敗しています。このエラーはプライベートイメージをpullしようとする際に最も頻繁に発生し、レジストリー側が「認証情報が不正または未提供」と判定した状態です。Docker Hubやプライベートレジストリー(ECR、GCR、プライベートDockerレジストリーなど)の両方で起こりえます。 実際のエラーメッセージ例 ERROR: for <service-name> UnexpectedStatusError(401): 401 Client Error: Unauthorized for url: https://index.docker.io/v2/<image-name>/manifests/latest { "message": "unauthorized: authentication required", "details": "https://docs.docker.com/docker-hub/access-tokens/" } ERROR: for myapp pull access denied for myregistry.azurecr.io/myimage, repository does not exist or may require 'docker login': denied: authentication required よくある原因と解決手順 原因1:docker loginを実行していない Docker Composeでプライベートイメージをpullする前に、docker loginコマンドで認証を済ませていない状況です。認証情報が~/.docker/config.jsonに保存されていないため、レジストリー側は401で応答します。 Before(エラーが起きるコード): # 認証なしで直接実行 $ docker-compose up ERROR: for webapp UnexpectedStatusError(401): 401 Client Error: Unauthorized After(修正後): # 1. 先に認証を完了させる $ docker login Username: <your-username> Password: <your-password> Login Succeeded # 2. その後にdocker-composeを実行 $ docker-compose up 原因2:compose.ymlで正しい認証情報が参照されていない compose.ymlにレジストリー認証情報を含めるとき、x-aws-cred-helperやcredHelpers設定が不正な場合や、設定ファイル自体が存在しない場合に401が発生します。 ...

ERROR: for <service-name>  UnexpectedStatusError(401): 401 Client Error: Unauthorized for url: https://index.docker.io/v2/<image-name>/manifests/latest
2026年5月30日 · ErrorLog
Hugo

Hugo PaperMod で datePublished が 0001-01-01 になるバグ:原因と解決策

エラーの概要 Hugo(PaperMod テーマ)で構築したサイトの構造化データ(JSON-LD)を Google のリッチリザルトテストで確認したところ、datePublished と dateModified に 0001-01-01T00:00:00Z という明らかに誤った日付が出力されていた。記事のフロントマターには正しく date: 2026-05-29 を設定していたにもかかわらず、構造化データには Go の「ゼロ値」に相当する日付が混入していた。 実際のエラー出力例 Google のリッチリザルトテストおよびページソースで確認された JSON-LD の内容: { "@context": "https://schema.org", "@type": "BlogPosting", "headline": "Docker の 404 エラー:原因と解決策", "datePublished": 0001-01-01 00:00:00 +0000 UTC, "dateModified": 0001-01-01 00:00:00 +0000 UTC, "publisher": { "@type": "Organization", "name": "ErrorLog" } } これは有効な JSON ですらなく、Google ボットがパースに失敗する状態だった。 原因 PaperMod テーマの themes/PaperMod/layouts/_partials/templates/schema_json.html における日付出力の実装が問題だった。 問題のあったテンプレートコード(Before): "datePublished": {{ .PublishDate }}, "dateModified": {{ .Lastmod }}, Hugo テンプレートで {{ .PublishDate }} を素のまま展開すると、Go の time.Time 型がデフォルト形式でシリアライズされる。この形式は 0001-01-01 00:00:00 +0000 UTC のような文字列になり、JSON として無効な出力になる。 さらに .PublishDate はフロントマターに publishDate を明示しない場合にゼロ値(0001-01-01)になることがある(Hugo のバージョンや設定により挙動が異なる)。lastmod も同様で、フロントマターに未設定の場合にゼロ値が返る。 ...

{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
2026年5月29日 · ErrorLog
GCP 404

GCP の 404 エラー:原因と解決策

冒頭まとめ GCP の 404 Not Found は、指定した対象が見つからないことを示します。素直な意味に見えますが、このエラーには「権限が無い場合に、存在を隠すため 404 が返される」という広く知られた説明があり、どこまで本当なのかが調べ方を左右します。 Google が公開しているエラー区分の定義ファイルには、実装する側への注意書きが添えられています。段階的な機能の公開や、公開されていない許可名簿のように、利用者の層ごと拒否する場合には 404 の区分を使ってよい。しかし、利用者単位のアクセス制御のように、層の中の一部の利用者だけを拒否する場合には、403 の区分を使わなければならない。こう書かれています。原則としては、権限の設定による拒否は 403 です。 一方で、運用上の公式文書には別の記述もあります。権限の無い利用者に対象の存在を明かさないために、403 の代わりに 404 が返ることがある、と明記されています。つまり「404 は必ず存在の問題」とまでは言えません。 それでも、調べる順序は変わりません。同じ公式文書が勧めているのは、まず識別子と経路を確認し、対象が実在するかを確かめ、それでも解決しなければ裏に認可の問題がないかを考える、という順序です。名前、プロジェクト、場所の3つを先に確かめれば、たいていの 404 はそこで原因に行き着きます。権限の側を調べるのは、その後です。 なお、403 の側の文言には「あるいは対象が存在しない可能性があります」という但し書きが付きます(GCP の 403 の記事)。403 と 404 は、存在と権限の両面で互いに染み出し得る隣どうしの区分だ、と押さえておくのが正確です。 エラーの概要 応答は他のエラーと共通の形で、status に区分名が入ります。 { "error": { "code": 404, "message": "The resource 'projects/my-project/zones/asia-northeast1-a/instances/my-vm' was not found", "status": "NOT_FOUND" } } 読むべきは message に含まれる対象の名前です。上の例では、どのプロジェクトの、どの場所の、どの対象を探したかが完全な形で書かれています。自分が指定したつもりの内容と、ここに出ている内容を並べれば、食い違いはすぐ見つかります。 特に見落としやすいのが場所の部分です。指定を省略した場合、道具の設定に入っている既定値が使われます。その既定値が意図と違っていると、正しい名前を指定しているのに見つからない、という状態になります。 コマンド行の道具からは、同じ内容が簡潔な形で出ます。 ERROR: (gcloud.compute.instances.describe) Could not fetch resource: - The resource 'projects/my-project/zones/asia-northeast1-a/instances/my-vm' was not found まず最初に:応答に出ている完全な名前と、自分の指定を並べる 第一に、message に出ている対象の完全な名前を読みます。ここには、実際に探しに行った先がそのまま書かれています。 ...

{
  "error": {
    "code": 404,
2026年5月28日 · ErrorLog
GCP 429

GCP の 429 エラー:原因と解決策

冒頭まとめ GCP の 429 Too Many Requests は、何かの上限を使い切ったことを示します。エラー区分の定義ファイルでは、利用者ごとの割り当てかもしれないし、ファイル置き場の空き容量かもしれない、という書き方になっています。つまり「要求の回数が多すぎる」とは限りません。量や個数の上限も同じ区分に入ります。 このエラーの扱いやすさは、応答に付く details にあります。上限に関する情報が、機械が読める形で定義されています。何に対する上限か(対象)、どの指標か、上限の識別子、上限の値、上限が適用される条件、そして違反の説明です。さらに、待つべき時間を示す構造も別に定義されています。 したがって、どの上限に当たったかを推測する必要はありません。応答に書かれています。旧来の対処のように、待ち時間を適当に入れて様子を見る、という進め方は不要です。 もう1つ、見落としやすい重要な点があります。上限の出どころが、呼び出したサービスとは限りません。定義には具体例が添えられていて、ある管理サービスを呼び出したときに、その内部で別の計算資源のサービスを使い、そちらの上限に当たる場合がある、と説明されています。この場合、応答にはその依存先のサービス名が入ります。呼び出した先の上限だけを調べても見つからないのは、このためです。 エラーの概要 応答の形は次のようになります。上限に関する詳細と、待ち時間の指示が別々に入ります。 { "error": { "code": 429, "message": "Quota exceeded for quota metric 'Requests' and limit 'Requests per minute'", "status": "RESOURCE_EXHAUSTED", "details": [ { "@type": "type.googleapis.com/google.rpc.QuotaFailure", "violations": [ { "subject": "project:my-project", "description": "Quota 'CPUS' exhausted. Limit: 24 in region asia-northeast1.", "apiService": "compute.googleapis.com", "quotaMetric": "compute.googleapis.com/cpus", "quotaId": "CPUS-per-project-region", "quotaDimensions": { "region": "asia-northeast1" }, "quotaValue": "24" } ] }, { "@type": "type.googleapis.com/google.rpc.RetryInfo", "retryDelay": "30s" } ] } } 読むべき項目を順に挙げます。 ...

{
  "error": {
    "code": 429,
2026年5月28日 · ErrorLog
GCP 500

GCP の 500 エラー:原因と解決策

冒頭まとめ GCP の 500 Internal Server Error は、1つの意味を持つエラーではありません。エラー区分の定義ファイルを見ると、500 に対応する区分は3つあります。 1つ目は内部のエラーです。定義には、下層の系が前提としていた不変の条件が破られたことを意味し、この区分は深刻なエラーのために予約されている、と書かれています。 2つ目は不明なエラーです。定義では、別の空間から受け取った状態がこちらでは未知のエラーに属する場合や、十分なエラー情報を返さない窓口からのエラーが、この区分に変換されることがある、と説明されています。つまり「原因が分からない」ではなく「原因を伝える経路で情報が落ちた」という意味です。 3つ目は回復不能なデータの損失または破損です。説明はこの一文だけですが、意味は重大です。 この3つで、次にやることが変わります。3つ目が返っているなら、再試行してはいけません。同じ操作を繰り返すより、何が失われたかを確認するのが先です。 残る2つについては、再試行が公式に認められています。運用側の公式文書は、指数的に間隔を伸ばしランダム性を加える再試行を勧めており、500 や 503 のサーバー側のエラーでは最初の間隔を最短1秒としています。503 との違いは、定義の側にあります。503 の定義には、一時的な状態である可能性が高く再試行で解消できると書かれているのに対し、500 の定義にはそうした見込みが書かれていません。直る保証の有無が違うだけで、再試行が禁じられているわけではない、と押さえてください(GCP の 503 の記事)。 エラーの概要 応答の形は他のエラーと共通で、status に区分名が入ります。 { "error": { "code": 500, "message": "Internal error encountered.", "status": "INTERNAL" } } status の値が INTERNAL、UNKNOWN、DATA_LOSS のいずれかで、意味が変わります。message は多くの場合、内部でエラーが起きたという趣旨の短い文言だけで、それ以上の手がかりはありません。 details に識別子が入っていれば、そこから判断できる場合があります。設計の指針では、すべてのエラー応答が機械が読める識別子を含むべきとされています。ただし 500 の場合、内部の事情を外に出さない方針から、詳細が乏しいことが実際には多くあります。 そのため、このエラーは他と違って、応答だけで原因に辿り着けないのが普通です。調査は記録の側に移ります。 まず最初に:status を読み、再現するかを見る 第一に、status の値を読みます。DATA_LOSS であれば、再試行の前にデータの状態を確認します。他の2つであれば、次に進みます。 第二に、同じ操作が再現するかを確かめます。1回だけであれば一時的なものです。繰り返し同じ場所で起きるなら、要求の内容に何か引き金があります。 第三に、他の操作でも起きているかを見ます。特定の操作だけなら要求側、幅広い操作で起きているなら提供側の問題である可能性が高くなります。 第四に、稼働状況の表示を確認します。ただし、表示が正常でも特定の機能だけが不調なことはあるので、表示だけを根拠に自分側の問題と決めつけないでください。 よくある原因と解決手順 原因1:一時的なもので、再試行で通る 最も多い形です。同じ要求が2回目には通ります。公式の指針では、間隔を指数的に伸ばしてランダム性を加え、最初の間隔は最短1秒です(429 の最短30秒とは扱いが違います。GCP の 429 の記事)。 ただし、再試行してよいかどうかは操作の種類によります。区分の定義には、503 について、同じ結果になるとは限らない操作の再試行が常に安全とは限らない、という注意が添えられています。同じ注意が 500 にも当てはまります。 Before(結果が変わりうる操作を無条件で再送する): for i in range(3): r = create_resource() # 作成の操作 if r.ok: break time.sleep(2 ** i) # → 1回目が内部で成功していた場合、二重に作られる After(作成の操作は、実物を確認してから判断する): ...

{
  "error": {
    "code": 500,
2026年5月28日 · ErrorLog
GCP 400

GCP の 400 エラー:原因と解決策

冒頭まとめ GCP の 400 Bad Request は、1つの意味を持つエラーではありません。Google が公開しているエラー区分の定義ファイルを見ると、400 に対応する区分は3つあります。引数が不正な場合、対象の状態がその操作を許さない場合、そして値が有効な範囲の外にある場合です。 この3つは、対処が根本的に違います。定義の説明文が、その違いをはっきり述べています。1つ目は「系の状態に関係なく問題のある引数」を指し、例として形式の壊れたファイル名が挙げられています。何度送っても結果は変わりません。2つ目は「系がその操作に必要な状態にない」ことを指し、例として空でないディレクトリの削除が挙げられています。状態を直せば同じ要求が通ります。3つ目は「有効な範囲を越えた操作」で、ファイルの終端を越えて読もうとした場合が例です。 したがって、GCP で 400 を受け取ったときに最初に読むべきは、状態コードではなく応答の status の値です。ここを読まずに要求の書式を疑うと、2つ目や3つ目の場合に見当違いの調査を続けることになります。 さらに、応答には details という配列が付きます。設計の指針には、すべてのエラー応答は機械が読める識別子を含まなければならない、と定められています。どの項目が悪いかを名指しする構造もこの中に入るため、原因の特定はここでほぼ完了します。 エラーの概要 実際の応答は、基本の4項目と details 配列で構成されます。 { "error": { "code": 400, "message": "There was a problem with the request.", "status": "INVALID_ARGUMENT", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "INVALID_ARGUMENT", "domain": "example.googleapis.com", "metadata": { "requestId": "t-a8896317-069f-4198-afed-182a3872a660" } }, { "@type": "type.googleapis.com/google.rpc.BadRequest", "fieldViolations": [ { "field": "destinations[0].login_account.account_id", "description": "String is not a valid number.", "reason": "INVALID_NUMBER_FORMAT" } ] } ] } } details の中身は @type で種類が分かれます。ErrorInfo は機械が読める識別子で、reason に大文字と下線だけの短い語が入ります。設計の指針では、この語は63文字以内で、大文字・数字・下線の形式に従うと定められています。domain には、どのサービスが出したエラーかが入ります。 ...

{
  "error": {
    "code": 400,
2026年5月27日 · ErrorLog