3편에서 어드민을 집 맥북에 두기로 했다. 서버를 빌리지 않기로 한 이상 글을 쓰는 쪽은 어딘가 내 기계에 있어야 했다. 이 편은 그 한 대를 어떻게 서버처럼 쓰게 만들었는지와, 그러면서 데인 곳을 적는다. 공유기 포트는 하나도 열지 않았다.
1. 서버가 아니라 그냥 맥북이다
1.1 꺼지면 글을 못 쓴다, 하지만 독자는 모른다
이 구조의 약점은 3편에 이미 적었다. 맥북이 꺼져 있으면 나는 아무것도 못 한다.
그런데 독자 쪽은 다르다. 블로그는 클라우드플레어에 올라간 정적 파일이라 내 기계와 끊어져 있다. 맥북이 꺼져도 글은 그대로 서비스된다.
| 맥북이 꺼지면 | |
|---|---|
| 독자가 글을 읽는 것 | 영향 없음 |
| 내가 글을 쓰는 것 | 못 함 |
| 발행·배포 | 못 함 |
잃는 쪽이 나 하나뿐이라, 이 정도면 감당할 만하다고 봤다.
1.2 32일째 켜져 있다
막상 해보니 맥북은 생각보다 잘 버틴다. 지금 이 글을 쓰는 시점에 32일 연속 켜져 있다. 그동안 재부팅은 없었다.
전원 관리를 손댄 것은 없다. 잠자기 설정도 맥OS 기본값 그대로다. 그러니까 이건 "서버로 쓰려고 맞춰 둔 상태"가 아니라 평소 쓰던 노트북이 그냥 계속 켜져 있는 것에 가깝다.
2. 켜지면 저절로 서는 상태로 만들었다
2.1 손으로 띄우고 있었다
한동안은 터미널에서 직접 명령을 쳐서 서버를 띄웠다. 돌아가는 동안은 문제가 없었다.
문제는 재부팅 다음이다. 맥북을 껐다 켜면 어드민도 블로그 서버도 안 뜬다. 모르고 지나가면 공개 사이트가 옛 빌드에 멈춰 있고, 글을 써도 발행이 안 된다. 고장 났다는 신호조차 없다.
2.2 네 개를 등록했다
맥OS에 "켜지면 이걸 띄워라"라고 등록해 두는 장치가 있다. 네 개를 올렸다.
| 등록한 것 | 하는 일 | 언제 |
|---|---|---|
| 어드민 | 글 쓰는 화면 | 켜지면 바로 |
| 블로그 서버 | 빌드된 정적 파일 서빙 | 켜지면 바로 |
| 터널 | 밖에서 들어오는 통로 | 켜지면 바로 |
| 새벽 배치 | 지표·피드백 수집 | 매일 04:30 |
죽으면 되살아나게 해뒀다. 셋 다 프로세스가 사라지면 20초 간격으로 다시 띄운다.
실제로 kill -9로 강제 종료해 보고 새 프로세스 번호로 다시 뜨는 것까지 확인했다. 재부팅은 굳이 해보지 않았다 — 같은 경로로 띄워 보는 명령이 있어서 그걸로 대신했다.
3. 밖에서 들어가기
3.1 포트를 열지 않았다
처음에 떠올린 방법은 공유기에서 포트를 열고 공인 IP로 들어가는 것이었다. 하지만 그건 집 네트워크에 문을 하나 내는 일이고, IP도 바뀐다.
터널은 반대로 동작한다. 맥북이 클라우드플레어로 나가는 연결을 먼저 맺고, 그 연결을 타고 요청이 들어온다. 바깥에서 집으로 들어오는 문은 없다.
flowchart LR
me(("폰")) --> cf["Cloudflare<br/>Access 인증"]
cf --> tun["터널"]
mac["맥북<br/>어드민 3000"] -.나가는 연결.-> tun
tun --> mac
3.2 순서를 틀리면 그 순간 열린다
여기에 함정이 하나 있었다. 터널을 만들고 주소를 연결하는 것과, 그 앞에 인증을 거는 것은 별개의 작업이다.
주소부터 연결하면 그 순간 어드민이 인터넷에 그대로 노출된다. 인증을 나중에 걸 생각이었어도, 그 사이에 열려 있다.
그래서 순서를 고정했다. 터널 생성 → 인증 정책 먼저 → 주소 연결. 설치 스크립트와 문서에도 이 순서로 적어 뒀다.
3.3 문이 두 개다
들어가려면 둘을 지나야 한다.
- 클라우드플레어 인증 — 어드민 화면에 닿기 전에 클라우드플레어가 먼저 신원을 확인한다
- 어드민 로그인 — 비밀번호 + 2단계 인증
인증 없이 /admin, /api/posts, /api/users를 찔러 보면 전부 로그인 화면으로 넘어가고, 어드민 내용은 한 글자도 나오지 않는다.

4. 개발 모드로 돌리다가 데였다
처음엔 어드민을 개발 모드로 띄워 뒀다. 코드를 고치면 화면이 알아서 갱신되니 편했다.
집에서는 멀쩡했다. 밖에서 폰으로 들어가면 이상했다. 화면이 옛 버전에 멈춰 있고, 버튼을 누르면 엉뚱한 오류가 났다.
원인은 자동 갱신이 터널 너머에서 잘 붙지 않는 것이었다. 코드가 바뀌면 브라우저에 알려주는 연결이 끊긴 채로, 화면만 열려 있었던 것이다.
지금은 빌드된 결과를 띄운다. 자동 갱신이 없으니 어긋날 일도 없다. 대신 코드를 고치면 다시 빌드해야 하는데, 띄우는 스크립트가 소스가 더 새로우면 알아서 빌드하고 시작한다.
5. 깃허브는 배포를 하지 않는다
이건 중간에 착각하고 있던 부분이다. 보통 이런 구조면 깃허브에 올리면 클라우드플레어가 받아서 빌드한다고 생각하기 쉽다. 여기선 그렇게 안 된다.
블로그를 빌드하려면 글을 읽어와야 하는데, 글은 맥북의 어드민 안에 있다. 클라우드플레어의 빌드 서버는 거기에 닿을 수 없다 — 인증 뒤에 있기 때문이다. 닿게 하려면 글을 꺼내 주는 공개 통로를 따로 내야 하는데, 그건 지금 막아 둔 것을 여는 일이다.
그래서 역할을 나눴다.
| 하는 일 | |
|---|---|
| 깃허브 | 코드 보관·버전 관리만 |
| 맥북 | 글을 읽어 빌드하고, 결과를 올림 |
| 클라우드플레어 | 올라온 정적 파일을 서비스 |
6. 지금까지
발행이나 수정이 생기면 맥북이 블로그를 다시 빌드해서 올린다. 지금까지 181번 돌았다.
| 값 | |
|---|---|
| 배포 실행 | 181건 |
| 실패 | 2건 |
| 걸린 시간 | 1~14초 |
글이 네 편뿐이라 빌드가 빠른 것이고, 쌓이면 늘어날 것이다. 다만 이 숫자가 늘어도 내가 기다리는 시간은 아니다 — 발행 버튼을 누르면 저장은 바로 끝나고, 빌드는 뒤에서 돈다.
여기까지가 만들면서 정한 것들이다. 다음 편은 정하지 못하고 틀렸던 것들 — 이 시리즈를 쓰는 동안 실제로 겪은 삽질을 모아 적는다.
