Stan 기술블로그

프로젝트

회사에서 맡은 일과 그 전에 한 프로젝트입니다. 과정은 각 글에 자세히 적었습니다.

회사에서 맡은 일 세무 데이터 SaaS 인프라 엔지니어, 2026.07 ~

self-hosted Sentry

2026.07 ~Docker Compose, Keycloak OIDC, Nginx Proxy Manager, Slack

세무 데이터를 외부 클라우드로 보낼 수 없어서, 에러 수집 서버를 사내망 안에 직접 세웠다.

  • Docker Compose로 개발 서버를 세우고 Keycloak SSO와 HTTPS 리버스 프록시를 붙였다. 도메인을 붙이자 터진 CSRF 오류를 여섯 단계에 걸쳐 풀었다.
  • 에러가 나면 Slack으로 알림이 가게 했다. 사내로 들어오는 콜백이 필요한 기능 세 가지는 일부러 접고 알림만 남겼다.
  • 모바일 앱이 보내는 이벤트 수집 경로만 별도 서브도메인으로 외부에 열고, 관리 화면은 내부망에 그대로 뒀다.
  • 리플레이 용량을 DB가 아니라 파일시스템에서 직접 재서 디스크 여유를 판단했다.

관련 글

사내 모니터링 콘솔

2026.07 ~Java 8 서블릿, Tomcat, MariaDB, SVN

인수받은 레거시 콘솔이다. SVN 커밋이 곧 운영 배포이고 스테이징이 없으며, 나는 서버에 들어갈 수 없다.

  • 켜 두는 대시보드가 20~30분마다 로그아웃되던 원인을 찾았다. 실시간 스트리밍(SSE)이 세션 갱신 요청을 멈추게 한 것이었다. 로컬에 전체 스택을 띄워 재현하고, 재연결 8번 동안 세션이 유지되는 걸 확인한 뒤 배포했다.
  • 코드만 있고 꺼져 있던 Slack 알림을 운영에 켰다. 그 과정에서 2주 전 내 커밋이 남긴 회귀를 찾았고, 운영 DB 상태를 로컬에 복제해 검증한 마이그레이션으로 고쳤다.
  • 인수 전에는 로그인 루프를 급히 다른 realm으로 우회했다가 원래 realm으로 되돌렸다. 커밋이 곧 배포인 곳이라 커밋이 여섯 번 필요했다.

관련 글

리버스 프록시로 realm별 접근제어

2026.08 ~ 09Nginx Proxy Manager, nginx, Keycloak, Docker

Keycloak 하나에 realm이 여럿일 때, 리버스 프록시만으로 realm마다 내부와 외부 노출을 다르게 할 수 있는지 확인하는 과제였다.

  • whoami 백엔드를 뒤에 세워 프록시가 볼 수 있는 것(도메인, 경로, 헤더)과 못 보는 것(토큰 안의 정보)의 경계를 확인했다.
  • 실습용 Keycloak 앞에 규칙을 걸어 공개 realm 200, 내부 realm 403, master 403을 확인했다.
  • 끝이 슬래시인 location에서 nginx가 301을 먼저 보내 deny를 건너뛰는 우회를 찾아 규칙을 고쳤다.
  • 서버 권한 없이 응답 코드만으로 운영 프록시 구조를 추정해 보고했고, 6일 뒤 재검증에서 그 결론을 스스로 뒤집었다.

관련 글

사내 코딩 어시스턴트 (TabbyML)

2026.07 ~ 08TabbyML, Docker Compose, Ollama, vLLM

망분리 때문에 Copilot 같은 외부 코딩 어시스턴트를 쓸 수 없어서, 사내망 안에서 도는 도구를 세웠다.

  • GPU 없는 서버에서 Tabby가 CUDA를 찾다 재시작을 반복했다. 임베딩까지 사내 Ollama 서버로 넘겨서 띄웠다.
  • VS Code, IntelliJ, Eclipse에서 자동완성과 채팅이 되는 걸 확인하고, 팀원이 가이드만 보고 설치할 수 있게 했다.
  • 파일럿 온보딩 가이드를 쓰면서, 예측되는 함정은 트러블슈팅 절이 아니라 설치 단계 안에 바로 적었다.

관련 글

그 전에 한 프로젝트

모여볼 (moball)

2026.06 ~팀, 백엔드 2명Java 21, Spring Boot, PostgreSQL, Playwright, GitHub Actions

KBO 경기를 중계하는 펍을 지도에서 찾는 서비스. 펍 조회와 필터 도메인, KBO 크롤러, 자동 배포를 맡았다. 8개 축 필터를 쿼리 하나로 처리했고, 크롤러는 파싱에 실패해도 예정 경기 데이터가 지워지지 않게 UPSERT 규칙을 짰다. 배포하는 동안만 러너 IP 하나를 보안 그룹에 열고 끝나면 반드시 닫는다.

BangCheck

2026.04 ~ 05팀, 백엔드 3명Java 17, Spring Boot, JPA, MySQL, GitHub Actions, EC2

매물을 보러 갈 때 쓰는 체크리스트 서비스. 체크리스트 도메인 설계, 운영 버그 추적, GitHub Actions와 EC2 자동 배포를 맡았다. 두 번째 저장마다 나던 409를 Hibernate ActionQueue의 flush 순서까지 따라가 찾았다.

Shopping Mall API

2026 상반기개인Java 21, Spring Boot, JPA, Spring Security, MySQL

의류 쇼핑몰 백엔드(REST API 19개)를 혼자 설계하고 구현했다. 장바구니 조회의 N+1을 쿼리 22개에서 1개로 줄였고, Hibernate Statistics 테스트로 측정해 회귀하면 바로 잡히게 했다.

EKS GitOps 인프라

2023.03 ~ 05카카오클라우드스쿨 팀 프로젝트AWS EKS, Terraform, Jenkins, ECR, ArgoCD, Prometheus, Grafana

CI/CD, GitOps, 모니터링을 맡았고 Terraform은 팀원과 페어로 했다. Jenkins에서 ECR을 거쳐 ArgoCD로 가는 배포 흐름을 만들고, 모니터링을 호스트, 컨테이너, 애플리케이션, 쿠버네티스 네 층으로 나눴다. 학습용 EC2 메모리 안에서 돌려야 해서 Spinnaker 대신 ArgoCD를 골랐다.