블로그를 이전 중이라 완료되기 전까지는 벨로그에 작성할 계획입니다.
이후 모든 글은 https://weekwith.me 에 작성 예정이니 다른 글이 궁금하시다면 해당 링크를 통해 방문해주세요.이번 해커톤 관련 전체 소스 코드는 gdg-16에서 확인 가능하며 제작한 서비스 자체는 이리ON 웹 페이지에서 확인 가능합니다.
이 자리를 통해 함께 고생해주신 팀원과 이런 자리를 마련해주는 여러 후원사와 심사위원 분들, 그리고 무엇보다 진행자 분들께 감사하다는 말씀드리고 싶습니다.
어제와 오늘(6월 25일 토요일부터 26일 일요일) GDG Campus Korea에서 주최한 2022 여름 해커톤에 참여했다.
총 100명을 선발하여 프론트엔드 2명, 백엔드 2명, 디자이너 1명으로 당일 무작위 팀 구성을 해준 다음 20팀이 마찬가지로 당일 주어진 주제 중에 한 가지를 선정해서 서비스를 개발하는 해커톤이었다.
팀원 분들에게는 부끄러워 말하지 못했지만 사실 나는 처음에 떨어졌다가 참가 못하는 분을 대신해서 충당된, 추가합격생이었다.
처음 지원했을 때 많은 개발자 분들을 만날 수 있다는 생각에 무엇보다 설렜다. 다른 잘하는 사람을 만나면 늘 긍정적인 동기부여도 받고 그들을 동경하며 나도 함께 성장할 수 있기 때문이다.
사실 이런 걸 다 떠나서 늘 사이드 프로젝트 하는 게 재밌었기 때문에 또 재미난 걸 기획하고 만들 수 있다는 것 자체가 설렜다.
그런데 한편으론 무척 두려웠다. 추가합격 되었다는 이야기를 들었기에 이미 떨어졌던 사람이 참여해봤자 다른 실력 좋은 사람들과 협업할 수 있을까란 의문을 떨쳐버릴 수 없었기 때문이다. 그래서 사실 당일 일정이 생겨 못할 것 같다고 말씀드릴까 말까 고민했다.
하지만 개발 실력이 부족해 큰 도움이 못될 것 같으면 기획이나 자료조사 부분이라도 더 도와드릴 수 있게 노력하기로 결정하고 참가했다.
팀 선정이 완료되고 주어진 주제를 오프닝 키노트를 통해 알게 되고나서 우리 팀은 신속하게 아이데이션에 들어갔다.
주제는 아래와 같이 크게 네 가지였다.
각 주제별로 여러 가지 의견이 오갔고 내가 팀원에게 제시한 아이디어는 유기동물 매칭 및 입양 희망자에 대한 퀴즈 등을 활용한 온라인 교육인증 서비스였다.
여러 과정을 거쳐 결국에는 내 아이디어가 선정되어 이를 발전시켜 나갔는데 무엇보다도 팀원 중 한명이 문제를 조금 더 날카롭게 만드는 게 중요할 것 같다고 이야기한 게 큰 도움이 되었다.
그래서 우리 팀은 유기동물에 있어 가장 큰 문제점이 되는 입양절차의 복잡성과 입양자에 대한 신뢰도, 그리고 입양동물에 대한 정보부족에 초점을 맞췄고 이외에 제시되었던 함께 돌보는 기능 등 유기동물의 사회화 및 일종의 커뮤니티 형성에 대한 부분은 구현 가능성 등을 함께 고려 했을 때 시간 내에 힘들 것 같다는 생각이 들어 과감하게 뺐다.
정해진 컨셉에 맞춰 본격적인 API 작업을 하기 이전에 프론트엔드 배포 자동화를 먼저 구축했다.
배포 자체를 따로 하지 않고 로컬에서 테스트하고 시연해도 괜찮았지만 디자이너 입장에서 실시간으로 바뀌는 걸 -자리가 떨어져 있더라도- 본인 컴퓨터에서 확인할 수 있으면 훨씬 효율적인 협업이 가능하고 결론적으로 결과물 공유 때도 도메인을 통해 청취자들이 직접 접속해서 확인하며 발표를 들으면 좋을 것 같았기 때문이다.
배포 자동화는 GitHub Actions를 활용하여 아래와 같이 CI/CD를 구축했는데 최근에 CircleCI만 써서 그런지 jobs
부분에 environments
가 존재하는 걸 몰랐다.
name: Irion CI/CD
on:
push:
branches: [main, jeje]
jobs:
continuous-deployment:
runs-on: ubuntu-latest
environment: AWS Deployment
steps:
- name: Git Checkout
uses: actions/checkout@v2
- name: Use Node.js version 16.x
uses: actions/setup-node@v1
with:
node-version: 16.x
- name: Build
run: |
npm install -g yarn
yarn install --frozen-lockfile
yarn build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Deploy to S3
run: aws s3 sync ./${{ secrets.BUILD_DIRECTORY }} ${{ secrets.AWS_S3_BUCKET_NAME }} --acl public-read --delete
- name: CloudFront Invalidate Cache
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CLOUDFRONT_DISTRIBUTION_ID }} --paths '/*'
조직 내에서 레포지토리 별로 이전처럼 여러 가지 비밀 키(Secret Key)를 저장할 수 있는데 이때 해당 비밀 키를 모아 관리할 수 있는 환경(Environment) 또한 함께 설정하여 관리해야 한다. 그리고 그때 설정한 이름을 바로 GitHub Actions에서 environment
부분에 작성해줘야 원하는 비밀 키를 정상적으로 사용할 수 있게 된다.
오랜만에 사용한 GitHub Actions여서 그런지 바뀐 부분을 새롭게 알게 되어서 좋았다.
문제는 이런 배포 이후 Certificate Manager를 활용하여 해당 도메인 HTTPS 작업을 하려 했는데 Certificate Manager가 해당 도메인을 찾지 못하는 오류가 계속 발생했다.
AWS EC2 인스턴스 등에 SSH를 통해 접속할 때는 해커톤 장소에서 제공해주는 와이파이를 사용하면 접속이 되지 않아서 핫스팟을 사용했는데 반대로 AWS 홈페이지 자체에 있는 서비스 콘솔을 사용할 때는 핫스팟이 문제를 일으켰다.
지금 와서 생각해보면 우선은 CNAME 값 자체를 수동으로 Route 53 도메인에 입력해서 인증이 되게 할 수 있었는데 급한 마음에 이 부분을 빨리 생각하지 못해 버린 시간이 좀 아깝다.
백엔드의 경우 Nginx 및 Certbot을 활용하여 포트 포워딩 및 SSL 작업을 했다. 이전에는 프로젝트할 때 간단하게 Certificate Manager 및 Elastic Load Balancing을 사용해서 해당 작업을 했는데 트랙픽이 별로 나오지 않더라도 월마다 2만원 가량의 금액이 청구되곤 했다.
해커톤은 물론 이후에 프로젝트를 진행할 때도 마찬가지로 제한적인 비용 또한 고민을 하는 게 중요하겠다는 걸 느꼈다. 무엇보다 Nginx 자체도 무조건 배워두면 좋은 기술이기 때문에 앞으로 자주 애용해야겠다는 생각을 했다.
사실 이전에 GitHub Actions 및 CodeDeploy를 활용하여 EC2 인스턴스에 연결되는 배포 파이프라인을 구축해본 적 있었는데 이상하게 저번부터 Ruby 버전에 오류를 발생시켰다.
하나씩 찾아보니 2021년 7월 CodeDeploy 관련 깃헙 레포지토리 이슈에 CodeDeploy agent is not supporting ruby v3.0.1라는 글이 하나 있었고 Ubuntu 22.04 버전에서 Ruby 3.x 버전을 사용하는데 CodeDeploy가 Ruby 2.7까지 지원을 해줘서 사용할 수 없다는 문제 제기였다. 참고로 Ubuntu 22.04 버전의 경우 OpenSSL 때문에 3.x 버전의 Ruby를 사용한다.
중요한 건 해당 문제가 결국 오늘까지 해결되지 않고 있다. 아래 이미지처럼 5월을 계획하던 배포는 결국 6월 말로 연기되었고 현재 7월이 거의 코앞으로 다가온 6월 말인데 아직까지 별다른 이야기가 없다.
CodeDeploy를 활용해서 CI/CD를 구축해놓고 비즈니스 로직에 집중하고 싶었는데 아쉬움이 남았다.
굳이 CodeDeploy를 선택한 이유는 도커와 같은 컨테이너 등의 개념에 대한 공부가 되어 있지 않은 것도 있고 도커나 쿠버네티스를 공부하기 이전에 다른 방법으로 배포 파이프라인을 구축하고 싶었기 때문이다.
최근에 FastAPI 및 MongoDB를 활용한 비동기 API 구축을 해왔어서 MySQL를 활용한 비동기 API를 구축하는데 애먹었다. 이를 테면 로컬 환경에서 제대로 되던 부분이 배포에서는 mysqlclient
패키지 때문에 오류가 발생했는데 경로 관련 문제일 수 있다는 스택오버플로우 글을 보고 수정을 해보다가 결국 관련 설정 파일은 정상적으로 서버에 존재하는 것을 확인해서 해당 패키지를 무시했더니 잘 됐다.
더 큰 문제는 기본 키(Primary Key)와 관련된 부분이었다. 나를 포함한 백엔드 개발자 2명의 기술 스택이 달라 API는 물론 서버를 FastAPI 및 Spring으로 나누어 구현하였고 데이터베이스는 RDS를 사용하여 동일한 MySQL을 사용했다.
그런데 작성된 테이블에 데이터를 입력할 때 기본 키 값이 계속 0으로만 저장이 되었다. 관련 문제를 찾아 해결하기 보다는 거의 목업 수준의 데이터만 저장하고 통신하는 목적이었기 때문에 급한 대로 직접 터미널 환경에서 쿼리를 활용해 값을 수정했다. 해당 부분은 리팩토링을 하면서 다시 무엇이 문제였는지 찾아볼 생각이다.
여유가 조금 생기면 만들었던 코드를 다시 수정해보고 싶다. 어쨌든 SQL을 사용한 기능도 결국은 다시 써야하기 때문에 SQLAlchemy, Alembic 등의 패키지도 다시 공부할 겸 코드를 다시 보고 수정하고 싶어졌다. 그래야 추후에 비슷한 상황이 발생했을 때 아무리 급하더라도 당황하지 않을 것 같았다.
또 상향선을 높이는 것보다 하한선을 낮추는 노력을 하려 했는데 그에 대한 결과가 이런 해커톤처럼 짧은 시간 내에 능률을 펼쳐야 할 때 잘 나타날 거라는 생각이 들었다. 하한선이 낮아질 수록 아무리 당황스러운 상황이 생기더라도 당황하지 않고 해결할 방법을 강구할 수 있을 것 같았기 때문이다.
다른 팀들의 발표와 심사위원 분들의 심사평을 통해서도 여러 가지 배운 점이 많았다. 아래는 발표 및 그에 대한 심사평을 들으며 적어 놓았던 몇 가지 이야기들이다.
습관과 관련된, 데일리 등의 반복적인 작업과 기록의 경우 일을 위한 일이 되지 않게 하기 위해 사용자의 부담감을 줄여줄 수 있는 노력이 필요하다. 예를 들어 투-두 리스트를 과감하게 없애는 것이다.
머신러닝을 활용한 분리수거를 한다고 했을 때 만약 그 학습의 결과가 뛰어나다면 굳이 앤드 유저까지 갈 필요가 없을 수도 있다. 공장 자체에서 분리 수거를 가능하게 하면 앤드 유저까지 안 가고 문제를 더 효율적으로 해결할 수 있기 때문이다.
사용자 여정을 구현 동와 식으로 설명을 하면 그 스토리로 인해 이탈율을 듣는 이가 더 쉽게 이해할 수 있다.
유기동물 관련 서비스나 동네 주민에게 본인의 시상이나 사생활이 노출되는 커뮤니티 서비스 등 실제로 서비스를 이용하는 사용자에 대한 관리나 검증이 필요한 경우가 꽤 많은데 이 경우 어떤 기준으로 명료하게 그들을 구분하고 관리 및 검증할 수 있을 지 고민이 필요하다. 가장 중요한 부분 중 하나인데 많은 팀과 서비스가 이를 놓치고 있다.
결론적으로 즐거운 해커톤이었고 많은 걸 배울 수 있었다. 그리고 3등으로 수상까지 하게 되었다.
문제와 그 해결방법을 정확히 찾아 연결한 것 같다는 심사평이 무척 기분 좋았는데 아쉬운 점은 위에 언급한 사용자 검증을 어떻게 할 수 있을지에 대한 문제와 오히려 오프라인 활동을 더 이끌어 낼 수 있는 매개체 역할로서의 온라인 서비스가 될 수 있을 것 같았다는 부분이었다.
두려움이 많았지만 굴하지 않고 도전해 얻어간 게 많았던 해커톤이었다. 다음에 또 참여할 수 있는 기회가 주어진다면 정말 행복할 것 같다. 앞으로도 문제의 핵심에 집중하고 나아가 내 하한선을 낮추는 데 노력하여 이처럼 긴박한 순간에 여러 상황을 마주할 때에도 당황하지 않고 내 몫을 다하는 개발자가 되어야겠다.
잘 읽었습니다. 해커톤 기간에 제 할 일만 하기도 바빠서 이런 일들을 하신 지 몰랐네요. 후기 남겨주셔서 감사합니다!