디버깅 실전 · 환경 문제 구분 · 이론
우리 서버에서는 되는데요
한 줄 요약
같은 코드가 여기서만 안 될 때 범인은 대개 환경변수, 인코딩, 권한, 그리고 셸의 값과 프로세스의 값이 다르다는 사실 중 하나다.
왜 이게 필요했나
FDE 가 가장 자주 듣는 문장이 "우리 서버에서는 되는데요" 입니다. 그리고 대개 그 말은 사실입니다. 코드는 같고, 환경이 다릅니다.
환경 차이는 코드 결함보다 찾기 어렵습니다. 코드는 읽으면 보이지만 환경은 읽을 것이 없기 때문입니다. 그래서 순서가 필요합니다.
어떻게 동작하나
현장에서 실제로 자주 나오는 순서대로 네 가지를 봅니다.
첫째, 환경변수. 없으면 실패한다는 것을 알려 주는 것은 대개 에러 메시지 자신입니다. missing env API_TOKEN 처럼. 문제는 이 메시지를 보고도 "설정했는데요" 라는 답이 돌아오는 경우인데, 거의 항상 설정한 곳과 읽는 곳이 다릅니다. 셸에서 export 한 값은 그 셸의 자식 프로세스에만 갑니다. systemd 로 뜬 서비스는 그 값을 보지 못합니다.
둘째, 인코딩. 한글 고객 데이터에서 압도적으로 자주 터집니다. 윈도우 환경에서 만들어진 CSV 는 UTF-8 이 아니라 EUC-KR(CP949)인 경우가 많고, 이 파일을 UTF-8 로 읽으면 글자가 깨지거나 디코딩 오류로 죽습니다. file 명령이 인코딩을 항상 정확히 맞히지는 못하므로, 한글이 깨져 보이면 iconv -f EUC-KR -t UTF-8 로 변환을 시도해 보는 것이 가장 빠릅니다.
여기서 함정은 자동 변환에 기대는 것입니다. 잘못된 인코딩으로 읽힌 문자열은 조용히 통과해서 데이터베이스에 저장되고, 몇 주 뒤 검색이 안 된다는 신고로 돌아옵니다. 인코딩은 읽는 시점에 확정해야 합니다.
셋째, 권한. 특히 자격 증명 파일이 그렇습니다. 토큰 파일이 644 로 놓여 있으면 같은 서버의 다른 사용자가 전부 읽을 수 있고, 보안 점검에서 이것 하나로 프로젝트 전체의 신뢰가 깎입니다. FDE 는 남의 집 열쇠를 다루는 사람이라 여기가 특히 무겁습니다. 최소 권한은 예의가 아니라 생존 규칙입니다.
넷째, 셸의 값과 프로세스의 값이 다르다는 것. 이게 가장 자주 사람을 속입니다. 파일 열기 한도를 예로 들면, 셸에서 ulimit -n 이 1048576 을 보여 줘도 실제로 도는 서비스의 한도는 1024 일 수 있습니다. 확인해야 할 곳은 셸이 아니라 /proc/<PID>/limits 입니다.
같은 함정이 여러 겹으로 반복됩니다. /etc/security/limits.conf 는 PAM 로그인 세션에만 적용되고 systemd 서비스에는 적용되지 않습니다. 컨테이너 안의 free 와 nproc 은 호스트 값을 보여 주는데 실제 제한은 cgroup 에 있습니다. 원칙은 하나입니다 — 설정 파일이 아니라 실행 중인 프로세스에서 실측하라.
현장에서 만나는 모습
환경 점검 스크립트를 하나 만들어 두는 것이 이 전부를 대신합니다. 필요한 환경변수, 파일 존재와 권한, 로캘, 데이터 접근 가능 여부를 순서대로 확인하고 첫 번째 실패에서 이유를 말하며 멈추는 스크립트입니다.
이런 스크립트의 가치는 진단 시간이 아니라 대화의 질에 있습니다. "안 되는데요" 대신 "envcheck 가 API_TOKEN 없다고 합니다" 라는 문장이 오가면, 고객사 담당자와의 왕복이 세 번에서 한 번으로 줄어듭니다.
다음 실습에서 할 것
환경 점검 스크립트가 실패하는 상태에서 시작해, 실패 원문을 확보하고, 누락된 환경변수를 특정하고, EUC-KR 한글 CSV 를 UTF-8 로 되살리고, 토큰 파일에 최소 권한을 적용해 점검을 통과시킵니다.