
기간: 2026.03.16 - 2026.03.20
커리큘럼: 중간 프로젝트 (Articket 실전 배포 및 발표)
이번 주는 중간 프로젝트인 Articket을 마무리하고, 실제 배포 환경을 구성한 뒤 최종 발표를 진행했다.
Articket은 공연/티켓 예매를 위한 B2C 서비스로, 사용자가 공연을 조회하고 예매·결제까지 진행할 수 있는 흐름을 목표로 한 프로젝트였다.
이번 중간 프로젝트는 MSA 구조가 아니라, 실제로는 하나의 Spring Boot 백엔드 애플리케이션을 중심으로 한 모놀리식 구조로 진행했다. 백엔드는 AWS EKS에 배포했고, 프론트엔드는 정적 파일을 빌드한 뒤 S3와 CloudFront를 통해 제공하는 구조로 구성했다.
백엔드 배포에서는 Kubernetes Deployment, Service, Ingress, HPA, Secret, Redis 리소스를 구성했다. articket-deployment는 ECR에 push된 Docker 이미지를 사용하도록 했고, articket-service는 ClusterIP 타입으로 내부 통신을 담당했다. 외부 요청은 server.articket.cloud 도메인을 통해 Ingress로 진입하고, Ingress가 백엔드 Service로 라우팅하는 방식으로 구성했다.
프론트엔드는 GitHub Actions에서 npm install과 npm run build를 수행한 뒤, 빌드 결과물인 dist를 S3 버킷에 업로드하고 CloudFront invalidation을 실행하는 흐름으로 구성했다. 백엔드는 GitHub Actions에서 Docker 이미지를 빌드하고 ECR에 push한 뒤, EKS 클러스터의 Deployment를 rollout restart하는 방식으로 배포했다.
또한 HTTPS 적용을 위해 cert-manager 기반 ClusterIssuer와 Certificate 리소스를 구성했고, server.articket.cloud에 대한 TLS Secret을 발급받는 흐름을 정리했다. Redis는 별도 Deployment와 Service로 EKS 내부에 배포했으며, 백엔드에서 필요한 DB 정보, JWT Secret, OAuth, PortOne, AWS Key 등은 Kubernetes Secret을 통해 환경변수로 주입했다.
HPA도 구성했다. articket-backend-hpa는 articket-deployment를 대상으로 하며, CPU 평균 사용률 50%를 기준으로 최소 1개, 최대 3개 Pod까지 확장되도록 설정했다. 다만 실제 운영 수준의 부하 테스트나 모니터링까지 완성한 것은 아니고, 이번에는 배포 구조와 오토스케일링 기준을 매니페스트로 준비한 단계에 가까웠다.
발표에서는 Articket 서비스의 주요 기능뿐 아니라, 프론트엔드 정적 배포, 백엔드 EKS 배포, Ingress/TLS 구성, GitHub Actions 기반 배포 흐름을 중심으로 정리해 공유했다.

처음으로 프로젝트를 로컬 환경이 아니라 실제 클라우드 환경에 올리면서, “서비스를 만든다”는 것과 “서비스를 배포한다”는 것이 완전히 다른 일이라는 걸 느꼈다.
기능 개발을 할 때는 API가 동작하는지, 화면에서 요청이 잘 가는지가 가장 중요했는데, 배포 단계에서는 도메인, 인증서, Ingress, Secret, 이미지 빌드, 컨테이너 실행 상태까지 모두 맞아야 했다. 코드가 맞아도 설정 하나가 틀리면 서비스는 정상적으로 열리지 않았다.
처음에는 MSA, GitOps, 모니터링까지 모두 적용한 구조를 만들고 싶었지만, 실제 결과물을 돌아보니 이번 프로젝트는 모놀리식 백엔드 애플리케이션을 EKS에 안정적으로 올려보는 경험에 더 가까웠다. 그래서 오히려 내가 실제로 한 것과 하고 싶었던 것을 구분하는 것이 중요하다는 생각이 들었다.
SSL 인증서, Ingress 라우팅, Secret 환경변수, ECR 이미지 배포 같은 부분을 맞추면서 DevOps가 단순히 “서버에 올리는 일”이 아니라 서비스가 외부에서 안정적으로 접근 가능하도록 전체 흐름을 연결하는 작업이라는 걸 체감했다.
B2C 서비스는 사용자의 진입 경로가 명확해야 한다. 프론트엔드는 www.articket.cloud, 백엔드는 server.articket.cloud로 분리했고, 사용자가 브라우저에서 접근하는 흐름과 API 요청 흐름을 나눠서 생각하게 되었다.
발표를 준비하면서는 단순히 “기능을 만들었다”보다 “어떤 구조로 배포했고, 어떤 부분이 아직 개선 과제로 남았는가”를 설명하는 게 더 중요하다는 걸 느꼈다.
모놀리식 구조도 운영 환경에 올라가면 고려할 것이 많다.
하나의 백엔드 애플리케이션이라고 해서 단순한 배포가 되는 것은 아니었다. Deployment, Service, Ingress, Secret, HPA, Redis 같은 운영 리소스를 함께 구성해야 실제 서비스 형태가 된다.
프론트엔드와 백엔드 배포 흐름은 다르게 설계해야 한다.
프론트엔드는 S3와 CloudFront를 통한 정적 호스팅이 적합했고, 백엔드는 Docker 이미지 기반으로 ECR과 EKS에 배포하는 구조가 필요했다.
CI/CD는 자동화보다 재현성이 중요하다.
GitHub Actions를 통해 프론트엔드는 빌드 후 S3 업로드와 CloudFront invalidation, 백엔드는 Docker build/push와 EKS rollout restart 흐름을 정리했다. 누가 실행하더라도 같은 방식으로 배포되는 구조를 만드는 것이 핵심이었다.
Ingress와 TLS는 서비스 외부 노출의 핵심이다.
Service만 생성하면 클러스터 내부 통신은 가능하지만, 실제 사용자가 접근하려면 Ingress와 도메인, 인증서가 필요하다. cert-manager와 Let’s Encrypt를 통해 HTTPS 인증서를 발급받는 흐름을 이해할 수 있었다.
Secret 관리는 운영 환경의 기본이다.
DB 비밀번호, JWT Secret, OAuth Client 정보, 결제 Secret, AWS Key 같은 값은 코드나 YAML에 직접 노출하면 안 된다. Kubernetes Secret을 통해 환경변수로 주입하는 구조를 경험했다.
HPA는 설정만으로 끝나는 기능이 아니다.
CPU request/limit이 있어야 HPA가 기준을 잡을 수 있고, 실제로 scale-out이 적절히 되는지는 부하 테스트와 모니터링이 함께 필요하다. 이번에는 HPA 매니페스트를 구성했지만, 운영 수준의 검증까지는 다음 과제로 남았다.
하고 싶은 구조와 실제 구현한 구조를 구분해야 한다.
ArgoCD, Prometheus, Grafana, 완전한 MSA 구조는 당시 목표로 삼았거나 학습한 개념이었지만, 이번 Articket 배포의 실제 중심은 GitHub Actions, ECR, EKS, Ingress, TLS, S3/CloudFront였다.
다음 프로젝트에서는 처음부터 실제 구현 범위와 목표 범위를 명확히 나누고 싶다. “구현 완료”, “구성 준비”, “개선 예정”을 구분해서 문서화하면 발표나 회고에서도 더 정확하게 설명할 수 있을 것 같다.
Articket에서 경험한 EKS 배포 흐름을 바탕으로, 이후 프로젝트에서는 서비스 단위 분리와 운영 의존성 분리를 더 명확하게 가져가고 싶다.
HPA를 단순히 매니페스트로 작성하는 것에서 끝내지 않고, 실제 부하 테스트와 metrics-server 기반 동작 확인까지 함께 검증해보고 싶다.
Prometheus와 Grafana 같은 모니터링 스택은 이번 프로젝트에서 완성하지 못했지만, 실제 운영 환경에서는 꼭 필요한 요소라고 느꼈다. 다음에는 배포 이후의 상태를 관찰할 수 있는 구조까지 함께 설계하고 싶다.
HTTPS, Ingress, Secret, S3/CloudFront, ECR, GitHub Actions를 직접 연결해본 경험은 이후 MSA 아키텍쳐 최종 프로젝트에서 AWS EKS 기반 운영 배포를 이해하는 데 중요한 기반이 될 것 같다.
이번 프로젝트는 B2C 공연 예매 서비스였고, 다음 프로젝트에서는 B2B HR SaaS 플랫폼으로 넘어간다. 사용자가 직접 예매하는 서비스에서, 기업 내부 업무 흐름과 자동화를 다루는 서비스로 관점이 바뀌기 때문에 도메인 설계와 운영 구조를 더 깊게 고민해볼 예정이다.
“Articket은 완성된 운영 플랫폼이라기보다, 내가 처음으로 클라우드 배포와 서비스 운영 흐름을 직접 연결해본 프로젝트였다.”
중프 1등도 PR 해주세요~