최근 heroku의 모든 plan이 유료화 되면서 백엔드용 무료 서버가 거이 사라졌습니다. 프론트엔드를 위한 무료 웹 호스팅 서버는 netlify, github page, vercel등 점점 많아지고 있는데 백엔드는 점점 사라지고 있죠.
AWS의 free tier를 사용해도 되지만 ec2에 s3, ssl, loadbalancer, rdb등을 추가하면 free tier 인데도비용이 꽤 나가는 것이 현실입니다.
Serverless나 Egde Computing쪽에는 무료 서비스가 많이 생겼으나, 백엔드 개발을 이제 막 시작한 개발자의 프로젝트를 Serverless 구조로 바꾸기엔 너무 어려운 것이 현실입니다.
이러한 문제 때문에 Heroku를 대체할 만한 무료 WAS(Web Application Service)서버를 찾다보니 Qoddi라는 서비스가 눈에 들어와 실제로 배포해 보았습니다.
Qoddi는 Heroku와 유사한 서비스로 Free tier로 node, spring, django, laravel, go 등의 WAS를 제공하고, mongoDB, mySql, Postgres의 DB 서버와 Redis memdb를 제공하는 서비스 입니다.
Free Tier로 WAS서버, RDS서버, Redis 서버를 한 앱에서 사용가능하고 ssl을 제공하며 서버가 sleep 되지 않는 것이 매우 맘에 들었습니다. custom domain이 안된다는 점은 약점이었습니다. 포트폴리오용 서버를 찾고 있었기에 트래픽이 많을 일은 없어 성능은 신경쓰지 않았습니다.
qoddi 사이트에서 signin을 눌러 가입을 합시다.
github id로 로그인이 가능합니다.
WAS서버를 만들려먼 신용카드를 등록해야 합니다. 등록해줍시다. 최초앱을 만들고 사용한지 두달정도 되었는데 아직 비용청구는 없었습니다.
로그인후 My apps에서 new를 눌러 새 앱을 만들어 봅시다. 이때 카드 등록이 나올 텐데 카드 정보를 입력합시다.
프로젝트 정보를 입력합시다. 프로젝트 이름과 사용할 Database 정보를 입력합니다.
App Type은 web server일 경우 port가 열리고 worker일 경우 서버 내부에서만 동작하는 worker를 생성합니다.
위치는 한국이 없기에 아무거나 누르고 next를 눌러봅시다.
git을 연결하는 단계입니다. 자신의 git 프로젝트를 연결해줍시다.
어떤 브랜치를 배포할지 정하는 부분입니다. 예제에서는 main 브랜치를 넣도록 합시다.
현재 서버를 2개만 사용하기 때문에 한달요금 0$가 나올 것입니다. 보통 프로젝트 하나에 db redis was를 사용하면 free tier가 끝입니다.
배포중이면 다음과 같은 화면이 나옵니다.
아래로 나오면 다음과 같은 화면이 나오는데 동작하는 머신의 환경 변수입니다.
JDBC_DATABASE_URL
에 password를 포함한 DB 접속 정보가 나옵니다.
git에 올릴 수 없는 비밀 번호등 Secure 정보를 환경변수로 올려 배포합시다.
qoddi 데이터베이스의 경우 외부에서 접속을 하지 못합니다. 로컬 개발 시에는 로컬 DB를 설치하여 진행하도록 합시다.
system.properties
는 배포 사양에 대해 기입하는 파일입니다. 해당 파일에 java 버전과 같은 정보를 넣으면 qoddi는 자동으로 버전을 인식합니다.java.runtime.version=17
Procfile
는 사용자가 직접 실행 스크립트를 집어넣는 기능입니다. root에 Procfile을 만들어 줍시다.web: ./run.sh
web: 뒤에 자신의 프로젝트 실행스크립트를 넣어주면 됩니다. Profile은 멀티라인을 지원하지 않기 떄문에 run.sh라는 파일을 따로 만들어 실행 시켰습니다.
echo ${SECURE_FILE} >> env.json
sed 's/*/"/g' env.json >> secureFile.json
java -Dserver.port=$PORT $JAVA_OPTS -Dspring.profiles.active=prod -jar ./build/libs/dive-log-0.0.1-SNAPSHOT.jar
git에 올라 가면 안되는 json 파일을 SECURE_FILE이라는 환경변수에 저장한 후 secureFile.json파일로 변경하였습니다. 이런식으로 git에 공개할 수 없는 파일은 2에서 소개한 환경변수에 저장하여 사용할 수 있습니다.
밑에는 gradle java project 실행 스크립트입니다. qoddi 기본 스크립트에 ./build/libs/*
로 실행하여 jar파일을 정확히 못잡는 버그가 있어 파일명을 제대로 명시해 주었습니다.
gradle build
를 통해 파일을 확인 할 수 있습니다.
spring.jpa.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=${JDBC_DATABASE_URL}
# common JPA update option
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
테스트 중인 프로젝트라 ddl-auto를 update로 진행 하였습니다.
로컬에선 내 컴퓨터의 환경변수 JDBC_DATABASE_URL에 로컬 DB URL을 넣어 로컬 DB로 테스트할 수 있습니다.
Qoddi는 기본적으로 github를 감지해서 배포해준다고 하지만, 제대로 동작하지 않을때가 많이 있습니다. 이러한 문제를 해결하기 위해 github actions와 webhook으로 배포해 봅시다.
다시 MyApp으로 가면
webhook URL이 있습니다. 해당 url로 호출하면 qoddi는 자동으로 배포하게 됩니다.
webhook url을 노출되지 않도록 조심합시다.
github 프로젝트의 settings에서 secrets -> actions WEBHOOK_URL을 추가해주시고 .github/workflows/depoly.yml에 다음과 같이 스크립트를 만들어줍시다.
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy
env:
WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}
run: |
curl -X GET $WEBHOOK_URL
main 브랜치가 갱신되면 WEBHOOK_URL을 호출하여 자동으로 배포되게 됩니다.
카우치코딩에서는 1:1 코딩 문제해결 멘토링 서비스입니다. 가르치는데 관심있는 멘토분들이나 문제해결이 필요한 멘티분들 방문해주세요~
또한 별도로 6주 포트폴리오 수업을 진행중에있습니다. 혼자 포트폴리오 준비를 하는데 어려움이 있으면 관심가져주세요~
카우치코딩 고동휘 멘토의 글입니다.
heroku 와 비슷한 배포방식일까요?