온프레미스 서버 블로그 구축기
프로젝트 소개
왜 Blog를 구축하게 되었는가?
취업 준비를 하며 간단한 프로젝트를 하나 진행해볼까 고민했지만, 막상 시작하려니 쉽게 손이 가지 않았다. 혼자서 풀스택 프로젝트를 진행하는게 부담스럽기도 했고, 뚜렷한 목적 없이 만드는 프로젝트는 하기가 싫었다.
막연하게 'SRE나 IT 인프라 관련 직무로 취업해야겠다.' 라는 생각은 있었지만, 장기현장실습에서 쿠버네티스 클러스터를 구축했던 경험 외에는 뭔가 내세울게 부족하다는 느낌이 들었다. 그렇다고 AWS로 뭔가 해보자니 비용도 부담되고, 사람들이 흔히 하는 방식 그대로 따라가고 싶지 않았다.
그래서 직접 온프레미스 서버를 구성해보는 것으로 방향을 틀었다. 당근 마켓에서 라즈베리파이를 저렴하게 구입하고, 도메인도 부담 없는 가격에 구매하면서 온프레미스 블로그 구축 프로젝트를 시작하게 되었다.
진행 개요
오픈 소스 기반의 헤드리스 CMS인 Ghost를 블로그 플랫폼으로 선정했다. 하드웨어는 라즈베리파이 4B (4GB RAM) 모델과 128 GB SD카드를 사용하였고, 소프트웨어 인프라는 Docker Compose를 활용해 구성하였다.
Docker 컨테이너로 Ghost와 Nginx를 각각 올리고, 가비아에서 도메인을 구매하였으며, Nginx를 통해 리버스 프록시 및 SSL 인증서(HTTPS) 설정까지 진행하였다.
구성 요소 선정 이유
라즈베리파이 4B 4GB
- 익숙하고 친숙했다.
연구실에서 BLE 프로젝트를 진행하며, 라즈베리파이를 엣지 디바이스로 사용했다. 손바닥만한 크기에 리눅스가 돌아가고, 다양한 포트를 갖춘 모습이 인상 깊었다. 그때부터 관심이 생긴 것 같다. - 가격이 저렴했다.
당근마켓에서 4만원에 해당 모델을 구매할 수 있었다. 일반적인 서버나 미니 PC를 비교하면 굉장히 저렴한 가격이여서, 충동구매를 해버렸다. - 전력 소모가 적다.
이 부분에 대해서 자세히는 모르지만, 라즈베리파이가 저전력이 강점이라는 점이 인터넷에서 많이 보였다. - 직접 서버를 운영해보고 싶었다.
물론 AWS나 다른 클라우드 환경에서도 블로그를 띄울 수 있었지만, 금전적인 부담도 있었고, 무엇보다 실제 하드웨어를 만지며 운영해보고 싶은 욕구가 컸다. 특히 향후 라즈베리파이 여러 대를 활용한 쿠버네티스 클러스터 구축까지 염두에 두고 있었기에, 이번 기회에 온프레미스 환경을 제대로 경험해보고 싶었다.
Ghost
처음에는 Hugo나 Jerkyll 같은 정적 블로그 생성기를 사용할까 고민했다. 실제로 Hugo를 올리기도 하였다. 하지만, 글을 쓸 때마다 로컬에서 빌드를 해야된다는 점은 불편했다. 그리고 어차피 온프레미스 서버를 구축했기 때문에, 정적인 사이트를 만든다는 것은 큰 장점도 아니었다.
그러던 중 Ghost라는 CMS를 알게 되었고, 다음과 같은 장점들이 마음에 들어 선택하게 되었다:
- 웹 기반 관리자 페이지
Markdown으로 글을 작성할 수 있으면서도, 웹 기반 관리자 페이지에서 바로 글을 쓰고 관리할 수 있어 매우 편리했다. Velog를 사용하는 느낌과 비슷했지만, 모든 데이터가 내 서버에 있다는 점에서 훨씬 만족스러웠다. - 깔끔한 기본 UI
기본 제공되는 테마가 매우 깔끔해서 별도로 테마를 설치하지 않아도 충분히 쓸 만했다. 관리자 페이지에서는 기본적인 커스터마이징이 가능하고, 추가 스크립트를 삽입할 수 있어 향후 기능 확장도 용이하겠다는 확신이 들었다. - 간편한 배포 방식
공식 Docker 이미지를 제공하고, Docker Compose 예제가 문서에 포함되어 있어 배포가 상대적으로 쉬웠다. 물론 문서대로만 했을 때는 약간의 삽질이 있었지만, 기본적인 구조는 잘 되어 있어 금방 안정적인 환경을 구성할 수 있었다.
Docker Compose
Ghost 도입 전, Hugo와 Nginx를 라즈베리파이에 직접 올려서 돌렸었다. 하지만 이 방식은 내가 어떤 설정을 했는지 알기가 어렵고, 실수라도 하면 서버를 포맷하고 처음부터 다시 시작하는 식의 반복이었다. 말 그대로 Snowflake 서버처럼 관리되지 않는 환경이 되어버렸었다.
이런 경험을 바탕으로, Ghost를 도입할 때는 처음부터 컨테이너화를 염두에 두고 구성했다. Ghost와 Nginx를 각각 도커 컨테이너로 분리하고, 전체 구성을 docker-compose.yml로 코드화하니 구조가 훨씬 명확해졌다. 덕분에 유지보수나 재배포도 훨씬 간편했다.
진행 과정
라즈베리파이 구축
운영체제 설치
운영체제는 Ubuntu Server 대신, Raspberry Pi OS를 사용하였다. Ubuntu에 비해 더 가볍고, apt, snap 등 패키지 매니저들을 다 지원하기 때문에, 크게 문제가 없을거라고 판단하였다.
설치법은 구글에 치면 바로 나오니, 생략하도록 하겠다.
SSH 및 네트워크 설정
SSH는 보안을 위해서 비밀번호 로그인보다는 rsa 공개키를 사용하여 접속하도록 하였다. 또한, 공유기 관리자 페이지에서 외부 접속을 위해 80번, 443번과 그리고 ssh 접속용 2222번 포트를 열어주었다. 또한, 라즈베리파이의 IP가 유동적으로 바뀌지 않도록 DHCP에서 고정 IP로 할당하였다.
서비스 구축
도메인
도메인은 가비아에서 구매했다. 구매 후에 자취방의 IP 주소를 A 레코드로 등록하여 외부에서도 도메인으로 접속할 수 있도록 했다.
Docker Compose
Ghost를 컨테이너로 실행하기 위해 공식 Docker 이미지를 사용했고, Nginx Proxy + Let’s Encrypt + Ghost + MySQL 조합으로 docker-compose.yml을 구성했다.
Nginx
jwilder/nginx-proxy 이미지를 사용하여 Nginx 컨테이너를 구성하고, 자동 리버스 프록시 기능을 활용하였다.
마치며...
마무리 및 느낀 점
매번 github 블로그나, velog와 같은 플랫폼을 쓰다가 직접 이렇게 온프레미스 서버로 블로그를 구축해보니 꽤 흥미로웠다. 어려운 작업은 아니었지만, 다시 도커 컴포즈 파일도 작성해보고, 처음 공유기 NAT 설정, 포트포워딩 등을 해보니 재미있었다.
추후 할 일
현재는 단일 라즈베리파이에서 Docker Compose로 구동 중이지만, 향후 라즈베리파이를 여러 대 추가하여 Kubernetes 클러스터로 확장할 계획이다.
Ghost, Nginx, DB 등의 서비스를 Pod로 구성하고, Helm Chart를 이용해 관리해볼 예정이다.
그 외에도 ArgoCD를 이용한 GitOps, PV 설정, Ingress Controller, Github Actions Self-host runner 설정, 모니터링 시스템 구축 등등 할 것이 정말 많다.