일단 무작정 배포하기
처음 프로젝트를 시작할 때는 프론트에서 API를 사용하기 위해 백엔드 레포지토리에서 코드를 받아 직접 로컬에서 서버를 실행시킨 뒤, localhost:8000 으로 요청을 보내는 방식을 사용해야했다.
하지만, 아무리 readme에 서버 구동 방법을 자세히 적어두어도 파이썬 설치, 가상환경 설정과 같은 개발환경 세팅을 장고를 학습해보지 않은 프론트가 따라하기에는 어려움이 있을 수 밖에 없었다.
프론트 멤버가 개발을 하기도 전에 백엔드 개발환경 세팅으로 고생하는 것을 보고 이건 아니다 싶어서 일단 빨리 서버에 배포부터 하자고 생각했다.
서버는 어떤 서버를 사용할 지 생각을 해봤는데, pythonanywhere 같은 호스팅 사이트를 사용하는 것도 괜찮은 듯 보였으나, 이번 기회에 직접 장고 서버를 배포해보고 싶은 생각에 내 개인 서버에 실배포 이전에 임시로 배포해보기로 했다.
처음에는 장고를 배포하는 방법을 몰라서 일단 수동으로 서버에서 장고 서버를 실행시킨 뒤, 개인 서버에 들어온 요청을 localhost:8000 으로 proxy_pass 시켜는 방법으로 서버를 배포했다.
우선 도메인 관리 페이지로 가서, pumasi.everdu.com 이라는 서브도메인을 설정해주었다.
처음엔 서브도메인 설정없이 everdu.com/api/ 이런 식으로 넘어간 경로에 대해 proxy_pass 를 해주었더니, 장고 내부적으로 /api/ 까지 url 로 받는 바람에 api 가 제대로 동작하지 않는 문제가 있어서 서브 도메인을 쓰기로 하였다.
다음으로는 nginx 설정파일에서 proxy_pass 를 해주었다.
이렇게 하면, 서버에서 직접 python manage.py runserver 을 해주는 순간 서버가 배포된다.
Github Action 으로 CI 구축하기
하지만 이렇게 했을 때 불편한 점이 있었다.
바로 수정된 코드가 github 에 push 될 때마다 일일히 서버를 들어가서 git pull 을 수동으로 입력해야 하는 점이다.
내 개인 웹사이트를 지금도 이런 방식으로 배포하고 있는데, 수정이 자주 되는 것도 아니고, github action 을 맨 처음 공부했을 때 너무 어렵고 무슨 말인지 몰라서 공부를 포기했었다.
하지만 이제는 다시 도전을 해봐야겠다고 생각을 했는데, 처음에 공부할 때는 봤던 이 영상 덕분에 블로그 글을 보면서 공부할 때 금방 이해할 수 있었다.
https://www.youtube.com/watch?v=iLqGzEkusIw&t=267s
다른 사람의 블로그 글을 참고하여 아래와 같이 작성해보았다.
github action ssh 라는 키워드로 검색해보니 내가 원하는 결과를 쉽게 찾을 수 있었다.
main 브랜치에 push, pull request 가 생길 때마다, deploy 라는 job 을 실행한다.
이 job 은 (아마 깃허브에서 제공하는) 최신 버전 리눅스 가상환경에서 돌아가는데 아래와 같은 스텝으로 실행된다.
1. actions/checkout@v3 라이브러리 기능을 수행한다.
uses 일종의 다른 사람이 미리 작성해둔 action 코드를 가져다 쓰는 거라고 이해했다.
(하지만 이 라이브러리?가 무슨 기능을 수행하는 것인지, checkout 은 무엇인지는 아직 이해하지 못했다.)
2. appleboy/ssh-action@master 라이브러리 기능을 수행한다.
appleboy 라는 유저가 만든 ssh-action 이라는 레포지토리의 master 브랜치에 있는 코드를 라이브러리 코드로 하여 실행한다는 의미였다.
이 기능을 수행할 때는 host, username, key, passphrase ... 등의 접속 정보를 입력받아서 (with) 실행한다.
ssh 접속에 성공하면 script 에 있는 내용을 실행하여 프로젝트 폴더로 이동한 뒤 git pull 을 실행한다.
이 2번 단계의 이름을 'execute remote ssh' 라고 명명한다.
접속 정보같이 민감한 값은 레포지토리 설정에서 secret 변수로 등록할 수 있었다.
이렇게 등록한 값은 수정할 때도 새로운 값을 입력해서 덮어쓰는 방식이라, 기존에 입력한 내 서버 설정값을 나를 포함한 아무도 볼 수 없어서 안심할 수 있었다.
(이 레포지토리는 다른 팀원과 같이 공동으로 관리중이기 때문이다)
이렇게 github action 을 설정한 이후에는 사진과 같이 push 가 들어올 때마다 자동으로 git pull 을 실행해준다.
여기까지 작업을 하고나니 이후부터는 서버를 키고 끄는 것만 신경쓰면 되고, git pull 에 대한 부분은 신경쓸 필요가 없어서 아주 편했다.
python manage.py runserver 를 하면, git pull 을 해서 코드가 수정되었을 때 자동으로 실행중인 서버를 다시 시작해줘서 git push 한 내용을 배포된 서버에서 거의 바로 확인할 수 있는 점도 편리했다.
서버 상시 배포 & Github Action 으로 CD 구축하기
하지만 여전히 불편한 점이 있었다.
서버 컴퓨터는 항상 켜져있지만, 서버 프로그램을 다른 사람이 요청할 때마다 내가 직접 서버에 들어가서 켜야 하는 점이다.
그래서 장고 배포를 제대로 공부하기 시작했다.
우선 장고를 배포할 때 uwsgi 라는 것을 사용한다고 한다.
uwsgi 는 장고 앱과 웹서버 사이에서 두 프로그램 사이 소통을 중계해주는 역할을 한다고 한다.
https://nerogarret.tistory.com/48
이 글 시리즈를 참고하면서 배포해보았다.
처음에는 내가 한 것처럼 uwsgi 명령어로 8000 포트에 서버를 실행시키고, nginx 에서 proxy_pass 로 로컬호스트 8000 포트에 요청을 넘기는 것으로 구현할 수 있었다.
하지만 그렇게 http 요청을 직접 넘기는 것보다, 소켓을 사용해 소통하는 것이 더 좋다고 하는 내용을 봤다.
구체적인 이유는 당장은 잘 모르겠다.
아마 네트워크 공부하면서 배우겠지..?
이 uwsgi 라는 친구는 전에 flask 배포할 때도 봤었던 친구다.
그때는 진짜 그냥 아무것도 이해하지 못한채로 코드를 따라치기만 했는데, 그래도 이제는 uwsgi 가 무슨 역할을 하는지 이해하고 쓰게 된 걸 보니 스스로 발전한 것 같아서 뿌듯하다.
위 글을 참고해서 이렇게 ini 파일을 작성했다.
uwsgi 명령어를 이 ini 파일을 넘기면서 실행하면 된다.
이 명령어를 매번 수동으로 실행할 수는 없으니, 백그라운드에서 자동으로 실행되도록 서비스를 등록했다.
이렇게 실행할 명령어를 ExecStart 에 입력해주면 된다.
이걸 하면서 또 한가지 깨달은 점이 있다.
지금 실행하는 uwsgi 명령어는 파이썬 가상환경에 설치된 uwsgi 명령어이다.
나는 처음에 파이썬 가상환경이 일종의 도커나, VMware 처럼 기존 OS 위에 또 하나의 다른 환경을 만드는 거라고 생각해서 서버 용량을 많이 차지 하지는 않을까 걱정했었다.
하지만 다행히도 메모리는 여유가 있었다.
uwsgi 가 어느 정도 비중을 차지하기는 하지만.. 이 정도는 아직 괜찮은 것 같다.
이제 uwsgi 를 데몬으로 백그라운드에서 실행시켜준 뒤, nginx 설정파일을 바꿔서
nginx 가 받은 요청을 uwsgi.sock 소켓으로 넘기도록 하면 배포가 끝난다.
이렇게 uwsgi_pass 를 이용해 요청을 uwsgi 로 넘겨주었다.
하지만 이렇게만 하면 코드가 수정되었을 때 수정사항이 자동으로 반영되지 않는다.
manage.py runserver 는 일종의 개발서버라서 수정사항이 생길 때마다 바로 반영해서 자동으로 재시작해주었지만 uwsgi 명령어로 실행한 서버 어플리케이션은 자동 재시작이 되지 않는다.
그래서 github action 에서 ssh 로 접속해 git pull 을 한 다음, 서버를 재시작하는 명령어도 한줄 추가해주었다.
이것으로 CD 까지 자동화가 완료되었다.
이렇게 하고나니 이제부터는 서버를 키고 끄는 것을 신경쓸 필요도 없고, 새로 개발한 기능이나 수정사항은 git push 되는 순간 자동으로 서버에 반영도 된다.
나 혼자할 때는 '그냥 내가 불편함을 감수하면 되니까' 라는 마음으로 깊게 공부를 안하게 됐었는데, 같이 협업으로 프로젝트를 하다보니 다른 사람의 불편함을 해소해주기 위해 더 깊게 공부할 의지가 생기게 된다.
역시 프로젝트는 팀으로 해야 더 많은 것을 얻어갈 수 있는 것 같다.
'팀 프로젝트 > [2024] GDSC 프로젝트 트랙' 카테고리의 다른 글
[GDSC 프로젝트 트랙] 6. 게시글 CRUD, 댓글 CRUD API 구현 (0) | 2024.02.16 |
---|---|
[GDSC 프로젝트 트랙] 4. 채팅 구현 방식 결정 & API 작성 (0) | 2024.02.01 |
[GDSC 프로젝트 트랙] 3. 로그인 API 구현 (2) | 2024.01.26 |
[GDSC 프로젝트 트랙] 2. 맡기 CRUD API 구현 & 배포 (0) | 2024.01.19 |
[GDSC 프로젝트 트랙] 1. 팀 빌딩 & 아이디어 수집 & 화면 설계 (3) | 2024.01.07 |