devops2024-01-20·8 min·327/348

Docker 컨테이너 시작 실패 해결 가이드

Docker 컨테이너가 시작되지 않는 문제를 진단하고 해결하는 방법을 알아봅니다.

Docker 컨테이너 시작 실패 해결 가이드

Docker 컨테이너가 시작되지 않는 문제는 다양한 원인에 의해 발생할 수 있습니다. 이 글에서는 흔한 에러 패턴과 해결 방법을 체계적으로 다룹니다.

Environment

$ docker --version
Docker version 24.0.7, build afdd53b

$ docker-compose --version
Docker Compose version v2.23.0

$ docker info
Server Version: 24.0.7
Storage Driver: overlay2

Problem: 컨테이너 즉시 종료 (Exit Code 1)

$ docker run -d --name myapp nginx:latest
$ docker ps -a
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS                      PORTS     NAMES
abc123def456   nginx:latest   "/docker-entrypoint.…"   5 seconds ago    Exited (1) 3 seconds ago              myapp

$ docker logs myapp
/docker-entrypoint.sh: line 19: exec: nginx: not found

또는:

$ docker run -d --name myapp python:3.11 python app.py
$ docker logs myapp
python: can't open file '/app/app.py': [Errno 2] No such file or directory

Analysis: 에러 원인 분석

# 1. 컨테이너 상태 확인
$ docker inspect myapp --format='{{.State.Status}} {{.State.ExitCode}}'
exited 1

# 2. 상세 로그 확인
$ docker logs --tail 50 --timestamps myapp

# 3. 컨테이너 내부 셸 접근 시도
$ docker exec -it myapp /bin/sh
error: failed to start container "myapp": OCI runtime create failed

# 4. 이미지 레이어 확인
$ docker history nginx:latest

Solution: 컨테이너 시작 실패 해결

방법 1: Dockerfile 검증

# Dockerfile
FROM python:3.11-slim

# Set working directory
WORKDIR /app

# Copy requirements first (for caching)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY . .

# Verify files exist
RUN ls -la /app

# Run with proper command
CMD ["python", "app.py"]
# Build and test
$ docker build -t myapp .
$ docker run -it myapp ls -la /app  # Verify files
$ docker run -d --name myapp myapp

방법 2:Entrypoint 디버깅

# Debug version - keep container running
FROM python:3.11-slim

WORKDIR /app
COPY . .

# Override CMD for debugging
CMD ["sleep", "infinity"]
# Run debug container
$ docker run -it --name debug myapp-debug

# Exec into container
$ docker exec -it debug /bin/bash

# Inside container - check files
$ ls -la /app
$ python app.py  # Test manually

방법 3: 환경 변수 확인

# Check environment variables
$ docker inspect myapp --format='{{range .Config.Env}}{{println .}}{{end}}'

# Run with explicit env vars
$ docker run -d \
  -e DATABASE_URL=postgresql://localhost/mydb \
  -e DEBUG=true \
  --name myapp \
  myimage

# Verify env vars inside container
$ docker exec myapp env

방법 4: 네트워크 문제 해결

# Check network settings
$ docker inspect myapp --format='{{json .NetworkSettings.Networks}}' | jq

# Run with network troubleshooting
$ docker run -it --network host myapp ping database

# Create custom network
$ docker network create mynetwork
$ docker run -d --network mynetwork --name database postgres:15
$ docker run -d --network mynetwork --name myapp myimage

방법 5: 리소스 부족 해결

# Check system resources
$ docker system df
$ docker stats --no-stream

# Run with resource limits
$ docker run -d \
  --memory="512m" \
  --cpus="1.0" \
  --name myapp \
  myimage

# Clean up unused resources
$ docker system prune -a
$ docker volume prune

Advanced: Docker Compose 문제 해결

# docker-compose.yml
version: '3.8'

services:
  app:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://db:5432/mydb
    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  db:
    image: postgres:15
    environment:
      - POSTGRES_DB=mydb
      - POSTGRES_PASSWORD=secret
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

volumes:
  pgdata:
# Debug compose services
$ docker-compose ps
$ docker-compose logs app
$ docker-compose exec app /bin/bash

# Rebuild without cache
$ docker-compose build --no-cache app
$ docker-compose up -d

Troubleshooting Checklist

# 1. 컨테이너 상태 확인
$ docker ps -a

# 2. 로그 확인
$ docker logs --tail 100 

# 3. 상세 정보 확인
$ docker inspect 

# 4. 이벤트 확인
$ docker events --filter container=

# 5. 리소스 확인
$ docker stats --no-stream

# 6. 이미지 빌드 테스트
$ docker build -t test .

# 7. 수동 실행 테스트
$ docker run -it test /bin/bash

Lessons Learned

  1. Exit Code 이해: 각 exit code는 다른 문제를 나타냅니다. 0=성공, 1=일반 에러, 137=OOM Killed 등.

  2. 로그 우선 확인: 컨테이너 시작 실패 시 먼저 docker logs로 에러 메시지를 확인하세요.

  3. 빌드 캐시 활용: Dockerfile에서 자주 변경되지 않는 레이어를 먼저 작성하여 빌드 시간을 줄이세요.

  4. healthcheck 설정: 의존성이 있는 서비스 간에 healthcheck를 설정하면 순서대로 시작됩니다.

  5. 리소스 모니터링: 컨테이너가 OOM으로 종료되지 않도록 메모리 제한을 설정하고 모니터링하세요.


This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.