개발기

RAM 960MB VPS 구축기

제일 싼 VPS를 골랐습니다. RAM 960MB. 이 숫자가 이후 모든 결정을 지배하게 됩니다.

스펙

항목값
호스팅Cafe24 SSD VPS
OSUbuntu 24.04.4 LTS
CPU / RAM4 vCPU / 960MB
SWAP / DISK4GB / 29GB
스택Nginx 1.24 + PHP 8.3.6-FPM

vCPU는 4개인데 RAM이 960MB입니다. 기본 설정 그대로 두면 부팅만 해도 스왑을 먹기 시작합니다.

OS를 한 번 잘못 깔았다

처음에는 Rocky Linux 8.10으로 설치했습니다. 그러다 Ubuntu로 재설치했습니다. 기술적으로 Rocky가 나빠서가 아니라, 막히는 부분이 생겼을 때 검색해서 나오는 자료의 양이 압도적으로 차이 났기 때문입니다.

혼자 하는 프로젝트에서는 이게 생각보다 큽니다. 새벽 두 시에 막혔을 때 물어볼 사람이 없으면 결국 검색 결과가 동료입니다.

960MB에 맞춘 튜닝

항목설정이유
PHP-FPM pmondemand유휴 상태에서 프로세스를 안 띄움
pm.max_children5동시 처리 상한을 막아 메모리 방어
opcache96MPHP 코드 캐시
memory_limit256M요청 하나가 서버를 못 죽이게

가장 효과가 컸던 건 pm = ondemand였습니다. 기본값인 dynamic은 요청이 없어도 대기 프로세스를 띄워둡니다. 트래픽이 하루 몇 건인 사이트에서는 그냥 메모리 낭비입니다.

이렇게 잡아서 피크 931MB로 맞췄습니다. 여유는 거의 없지만 스왑으로 넘어가지는 않습니다.

삽질 ① 스크립트가 조용히 죽었다

셋업 스크립트가 아무 에러 메시지도 없이 중간에 멈췄습니다. 범인은 이 한 줄이었습니다.

wp --info --allow-root | head -n 5

무슨 일이 벌어지냐면 이렇습니다.

  1. head가 5줄을 읽고 파이프를 닫습니다.
  2. 앞 명령이 계속 쓰려다가 SIGPIPE를 받고 죽습니다.
  3. 종료 코드가 141이 됩니다.
  4. 스크립트 맨 위에 걸어둔 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 삽질도 정확히 같은 성격이었습니다.

이어서 읽기

개발기 전체 목록 보기 →