서버 운영
서버에서만 터질 때 확인할 로그
로컬에선 완벽한데 배포 환경에서 실패한다. 컨테이너 로그가 답이다.
개발 중엔 문제없는데 서버에서만 에러가 난다. 이럴 땐 로컬과 배포 환경의 차이가 원인이다. 컨테이너 로그를 보자.
첫 번째: 컨테이너 로그를 본다
# 가장 최근 로그 100줄
docker logs --tail=100 container-name
# 실시간으로 보기
docker logs -f container-name
# 타임스탬프와 함께 보기
docker logs --timestamps container-name
# 특정 시간 이후 로그만
docker logs --since=10m container-name
브라우저에서 보이지 않는 에러 스택 트레이스나 초기화 메시지가 로그에 있을 수 있다.
두 번째: 환경변수가 제대로 전달되었는지 본다
# 컨테이너 환경변수 확인
docker inspect container-name | grep -A 20 'Env'
# 또는 ps aux로 프로세스와 함께
docker exec container-name ps aux
# 직접 환경변수 출력
docker exec container-name env | sort
배포 설정에서 환경변수를 빠뜨렸을 수 있다. 특히 .env 파일이 아닌 배포 설정에서만 정의하는 변수들이 문제가 될 수 있다.
세 번째: 네트워크 연결을 확인한다
# 컨테이너 내부에서 외부 서비스 연결 테스트
docker exec container-name curl -v https://external-api.com
# DNS 확인
docker exec container-name nslookup external-api.com
# 포트 확인
docker exec container-name netstat -tuln | grep LISTEN
배포 환경의 방화벽이나 네트워크 정책이 외부 API 호출을 막을 수 있다.
네 번째: 파일 시스템을 확인한다
# 컨테이너 내부 파일 구조
docker exec container-name ls -la /app
# 설정 파일이 있는지
docker exec container-name cat /app/.env
# 권한 확인
docker exec container-name ls -la /app/config/
# 디스크 공간
docker exec container-name df -h
배포된 이미지에 필요한 파일이 없거나, 읽기 권한이 없을 수 있다.
다섯 번째: 애플리케이션 메트릭을 본다
# 메모리 사용량
docker stats container-name
# 프로세스 목록
docker top container-name
# 컨테이너가 정상 실행 중인가
docker ps | grep container-name
# 컨테이너 재시작 횟수
docker inspect container-name | grep -i restart
OOM(Out of Memory) 에러로 프로세스가 종료될 수 있다. 메모리 제한을 확인하자.
여섯 번째: 표준 에러와 표준 출력을 모두 본다
// Node.js 앱에서 수동으로 로깅
console.log('[INFO]', new Date().toISOString(), 'Server starting');
console.error('[ERROR]', new Error('Something failed'));
// 파일로도 기록
const fs = require('fs');
const logStream = fs.createWriteStream('/app/logs/app.log');
process.stdout.pipe(logStream);
process.stderr.pipe(logStream);
console.log도 기록하고, 에러는 별도로 console.error로 출력해야 한다.
체크리스트
docker logs -f로 실시간 로그를 본다- 환경변수가 모두 제대로 전달되었는지 확인한다
- 컨테이너에서 외부 서비스에 연결되는지 테스트한다
- 필요한 설정 파일이 있는지, 권한은 있는지 확인한다
- 메모리, CPU, 디스크 사용량을 본다
- 컨테이너 재시작 상태를 확인한다
- 에러 메시지를 스택 트레이스까지 완전히 본다
서버에서만 터지는 문제의 90%는 로그에 답이 있다. 하지만 로그 레벨이 높거나 출력이 안 될 수도 있으니, 필요하면 애플리케이션 코드에 임시 로그를 추가해야 한다.