사실 만들기는 예전에 만들었는데, 회사 업무 때문에 바빠서 (사실 귀찮아서..) 만들기만 하고 냅둔 블로그를 오픈하기로 했다. 내 개인용 블로그 용도로 만들었기 때문에, 최대한 서버비용을 줄일 수 있을 때까지 줄이고 싶었다.
가장 좋아하는 언어인 코틀린으로 개발하고 싶었다. 프레임워크로는 Ktor를 고려해보기도 했지만, 결국 무난하고 익숙한 스프링부트로 하기로 결정했다. 그리고 ORM으로 JPA를 선택했다. JPA는 내가 지금껏 겪어본 ORM 중에서 가장 성숙하고 완성도가 높은 API이다. Exposed 를 고려하기도 하였지만, 러닝커브로 겪는 시간지체를 견디기에는 내가 성격이 급한 편이다. 다만 쿼리빌더를 선택하는 데에 있어서는 새로운 기술스택을 적용하기로 했다. 일반적으로 QueryDsl은 JPA와 연계하여 타입세이프한 쿼리를 작성하는데 최적의 툴이지만, 더 이상 유지보수가 진행이 안 되는 라이브러리이기도 하고, 무엇보다 별도의 컴파일 단계를 거친다는 게 불만사항이었다.
https://www.youtube.com/watch?v=-Kdr6qq6uJI
예전에 위의 영상을 우연히 보게 된 적이 있는데, 라인에서 개발한 오픈소스인 Kotlin-JDSL을 소개하는 영상이다. 몇번 테스트를 해보니, QueryDsl가 비교하여 여러가지 한계점이 존재하긴 하지만, 얼추 왠만한 건 다 되는 편이라 충분히 쓸 만하다고 판단했다. 별도의 빌드 스텝을 지니지 않는다는 점에서 가장 매력적이라 이 프로젝트에 적용했다. 프로젝트에 적용된 버전은 2 버전대로 최신 버전은 JPQL를 기반으로 다시 만들었다고 하니, 더욱 기대가 된다. 버전 3은 적용을 안 한 상태이다.
프론트엔드를 고려할 때는 이미 생각해둔 스택들이 있었다. React.js 및 기타 모던 JS 프레임워크를 쓰고 싶은 생각은 없었다. 내가 개발을 생각할 때 가장 크게 생각하는 부분 중 하나가 의존성의 최소화 와 생산성인데, 이러한 모던 JS 프레임워크는 현재 내 상황에서는 최적의 기술이 아니다. 그보다 최근 눈여겨 보고 있는 JVM 기반 템플릿 엔진인 JTE와 HTMX, 그리고 Alpine.js를 조합하여 사용하기로 결정했다. 예전부터 조금씩 사용해본 결과, 충분히 만족스럽고 생산성도 높았다. HTMX에 대한 나의 소견은 게시글에 몇 번 적어놓긴 했다.
나는 정말 React.js 가 싫다고요 (Feat. HTMX..)
CSS tool은 tailwindcss 를 사용, tailwindcss를 기반으로 한 daisy ui의 컴포넌트들을 사용했다. tailwind의 방식이 다소 지저분해 보인다는 단점이 있지만, 요새 개발방법이 한 번 컴포넌트들(내 경우에는 템플릿 조각)을 정의해두고, 컴포넌트를 조립하는 식으로 페이지를 구성하기 때문에, 별도의 CSS 파일을 정의하는 것보다, 하나의 공통된 클래스 네임을 정의한 CSS 파일을 기반으로 HTML에 직접 때려박는 방식이 더 편하며 사이드-이펙트가 적다. 귀찮은 클래스 이름 지정하는 데 많은 시간을 소모 안하고, 중복의 문제도 어차피 정의된 컴포넌트들을 반복하면 되므로 사라진다.
어떻게 보면 지금 내가 이 프로젝트를 개발하는 방식과 비슷하다. 별도의 서식과 컨텐츠를 분리하지 않고 하나로 합친 것처럼, 나도 별도의 프론트엔드와 벡엔드간 프로젝트를 나누지 않고, 하나로 유기적으로 합쳐지는 걸 원했다. 개인적인 예측(바람?) 으로는 앞으로는 이런 식의 방법론이 대세가 되지 않을까 싶다. 역사적으로 확인했다시피 유행은 돌고 도는 셈이니까.
가비아에서 할인을 하길래 싸게 구매했다. 원래 생각해둔 도메인이 따로 있었지만, 역시 내 차지는 아니었다. 조금 범용적인 호스트네임을 생각했으므로 freeapp은 적절해보인다.
개인이 호스팅하기에 클라우드 서비스만한 게 없다. 그 중에서도 AWS가 가장 래퍼런스도 많고 사용자도 많으니 안 쓸 이유가 없다. 대충 DNS 설정하고 프리티어 EC2 하나를 만든 다음 EIP를 할당하고 그 위에 올렸다.
다만 AWS에는 프리티어로 지원해주는 RDS 서비스가 없다. 대충 EC2에 Mysql를 쌩으로 설치해서 사용하는 방안도 생각해보았지만, 관리의 편의성을 생각하면, 다른 방안이 없나 찾아보다 이 녀석을 알게 되었다. 이 녀석의 기특한 점은 무료로 관계형 DB 중 하나인 postgresql 기반의 DB를 사용할 수 있다는 점이다. 파이어베이스는 관계형 DB를 제공해주지는 않는다. 새로운 좋은 서비스를 알게 되어서 참 기분이 좋다 ㅎ
다음 문제는 SSL 인증서인데, 나는 정상적인 서비스를 원했으므로, 인증서가 필요함은 물론이었다. AWS에도 ACM이라는 서비스 형태로 인증서를 제공해주긴 하지만 인증서를 달기 위해서 LB가 필수적이고, 최대한 돈이 덜 나오는 방향으로 진행을 하고 싶었기 때문에 선택사항에서 제외되었다. EC2에 Nginx를 깔고, Nginx에 Let's encrypt로 인증서를 설치하고, 내 블로그 서버를 바라보도록 설정해주었다.
그리고 이 모든 과정을 자동화하는 배포 파이프라인을 구축하고 싶어졌다. 내가 원하는 건 인프라만 갖춰져 있고 소스코드만 깃허브에 있으면, 버튼 딸깍만으로 이 모든 위의 기타 과정이 자동으로 설치되고 갱신되는 흐름을 원했다. 이렇게 하는 데 있어서, Docker Compose 만큼 적절한 툴이 없어보였다. 먼저 배포할 EC2에 Docker를 설치하고, Nginx 및 certbot, 내 블로그 코드를 도커 이미지로 말아서 함께 올릴 수 있는 Compose 파일과 이를 실행할 스크립트 파일을 작성하고 레파지토리에 푸쉬했다. 그리고 역시 제한이 있지만 무료로 사용가능한, 깃허브 액션을 이용하여 이 빌드한 JAR 파일과 스크립트 파일들을 SCP 명령어를 사용하여 EC2 인스턴스로 복붙해 실행하는 원격 스크립트를 액션에 작성하였다.
잡썰로 IDE는 Jetbrain이 최고존엄이다. 괜히 VSCode로 뭘 하려고 하지 말고, 돈 있든 없든 ultimate 질러라. 특히 JVM 기반으로 개발하려고 하면, 아직까지는 Intellij 만한 게 없다.
단순 게시판만 만들긴 좀 뭐해서, 이것저것 잡다한 거 붙이긴 했다. 웹 소켓을 이용한 채팅화면이라든지, velog에 유저네임을 입력하면, 해당 유저의 velog 글들을 md 파일들을 만들어 zip 형태로 다운받을 수 있게 하는 기능이라든가..
이러한 기능들은 스케일 아웃을 염두에 두고 만든 게 아니라, 단순 하나의 서버에 호스팅할 때 기점으로 만들어놓은 거라, 조금 아쉽긴 하다. 나중에 시간에 여유가 있으면 그때 여러가지 추가해볼려고 한다.
로그인은 깃허브 social login을 지원한다. login을 해야 게시판에 글을 작성하거나 todo 페이지에 들어가는 게 가능하다. 별거 없지만, 쓸 사람이 나말고 있기야 할까..?