스펙
| 항목 | 값 |
|---|---|
| 호스팅 | Cafe24 SSD VPS |
| OS | Ubuntu 24.04.4 LTS |
| CPU / RAM | 4 vCPU / 960MB |
| SWAP / DISK | 4GB / 29GB |
| 스택 | Nginx 1.24 + PHP 8.3.6-FPM |
vCPU는 4개인데 RAM이 960MB입니다. 기본 설정 그대로 두면 부팅만 해도 스왑을 먹기 시작합니다.
OS를 한 번 잘못 깔았다
처음에는 Rocky Linux 8.10으로 설치했습니다. 그러다 Ubuntu로 재설치했습니다. 기술적으로 Rocky가 나빠서가 아니라, 막히는 부분이 생겼을 때 검색해서 나오는 자료의 양이 압도적으로 차이 났기 때문입니다.
혼자 하는 프로젝트에서는 이게 생각보다 큽니다. 새벽 두 시에 막혔을 때 물어볼 사람이 없으면 결국 검색 결과가 동료입니다.
960MB에 맞춘 튜닝
| 항목 | 설정 | 이유 |
|---|---|---|
PHP-FPM pm | ondemand | 유휴 상태에서 프로세스를 안 띄움 |
pm.max_children | 5 | 동시 처리 상한을 막아 메모리 방어 |
| opcache | 96M | PHP 코드 캐시 |
memory_limit | 256M | 요청 하나가 서버를 못 죽이게 |
가장 효과가 컸던 건 pm = ondemand였습니다. 기본값인 dynamic은 요청이 없어도 대기 프로세스를 띄워둡니다. 트래픽이 하루 몇 건인 사이트에서는 그냥 메모리 낭비입니다.
이렇게 잡아서 피크 931MB로 맞췄습니다. 여유는 거의 없지만 스왑으로 넘어가지는 않습니다.
삽질 ① 스크립트가 조용히 죽었다
셋업 스크립트가 아무 에러 메시지도 없이 중간에 멈췄습니다. 범인은 이 한 줄이었습니다.
wp --info --allow-root | head -n 5
무슨 일이 벌어지냐면 이렇습니다.
head가 5줄을 읽고 파이프를 닫습니다.- 앞 명령이 계속 쓰려다가 SIGPIPE를 받고 죽습니다.
- 종료 코드가 141이 됩니다.
- 스크립트 맨 위에 걸어둔
set -o pipefail때문에 스크립트 전체가 중단됩니다.
그런데 head는 자기 할 일을 다 했으니 화면에는 정상 출력이 그대로 나옵니다. 에러처럼 보이지 않습니다.
wp --info --allow-root 2>&1 | head -n 5 || true
같은 패턴이 curl | head 형태로 세 군데 더 있어서 함께 고쳤습니다. | head를 쓰는 곳은 전부 의심하는 게 맞습니다.
삽질 ② 비밀번호를 날렸다
스크립트가 크론탭 설정 단계에서 또 죽었습니다. 하필 자동 생성한 관리자 비밀번호를 파일에 기록하는 코드가 스크립트 맨 끝에 있었습니다.
비밀번호는 메모리에서만 존재하다가 그대로 증발했습니다. 어디에도 안 남았습니다.
여기서 얻은 규칙은 단순합니다.
자격증명은 생성하는 즉시 기록한다. 스크립트가 끝까지 도는 걸 전제하지 않는다.
그리고 중단된 지점부터 이어서 실행할 수 있는 resume.sh를 따로 만들었습니다. 처음부터 다시 도는 스크립트는 이미 만들어진 것들과 충돌합니다.
삽질 ③ 터미널 붙여넣기가 깨진다
여러 줄짜리 스크립트를 터미널에 붙여넣으면 줄이 뒤섞였습니다. 자동 들여쓰기가 개입하거나, 윈도우의 줄바꿈 문자(CRLF)가 섞여 들어가서 그렇습니다.
결국 이 방식으로 정착했습니다.
cat > /root/x.sh << 'SCRIPT_END'
(여기에 붙여넣기)
SCRIPT_END
sed -i 's/\r$//' /root/x.sh
따옴표로 감싼 'SCRIPT_END'가 중요합니다. 따옴표가 없으면 스크립트 안의 $가 셸 변수로 해석돼 버립니다. 마지막 sed 한 줄은 CRLF 제거용인데, 이게 없으면 나중에 "분명히 맞는데 안 된다" 하며 한참 헤맵니다.
정리
이 단계에서 가장 많이 쓴 시간은 설정이 아니라 왜 죽었는지 모르는 상태를 해소하는 데 썼습니다. 셋 다 공통점이 있습니다.
- 파이프는 조용히 죽입니다
- 스크립트는 끝까지 안 돌 수 있습니다
- 윈도우와 리눅스의 줄바꿈은 눈에 안 보입니다
전부 화면에 아무것도 안 나오는 종류의 문제였습니다. 다음 글의 SSL 삽질도 정확히 같은 성격이었습니다.