[Circle CI] Circle CI에서 서버에 배포하기

Circle CI에서 TEST를 다 통과하면 원하는 서버에 배포하도록 해보자


환경

  • Cricle CI
  • Github Repository
  • Remote Server(Ubuntu 14.04) with SSH key


사전 준비사항

  • yml 설정을 하고 Circle CI를 통해 빌드한 경험이 있어야 합니다.
  • Github를 통해서 Merge하고 Deploy까지 할 예정이기에 Github에 프로젝트가 있어야 합니다.
  • 배포할 서버가 있어야하며 서버에 접속할 수 있는 SSH Key가 있어야 합니다.


배포과정

배포하는 과정은 크게 나누면 아래와 같습니다. 위에 있는 사전 준비사항에 있는 과정들을 다 진행해본 경험이 있어야합니다.

  1. 원하는 프로젝트를 특정 branch에 merge(이 글에서는 develop branch에 merge함을 통해서 진행 할 예정)
  2. CI에서 빌드
  3. CI에서 yml코드에 있는 쉘 스크립트를 통해서 서버에 접속 및 배포 코드 실행
  • Merge(in Github) -> Build(in Circle CI) -> Deploy(in Circle CI and Server)


배포 세팅 과정

위에서는 배포 세팅이 완료되었을 때 어떠한 순서로 배포가 이루어졌는지에 대한 과정이었다면, 이제는 우리가 어떠한 순서로 배포 세팅을 할지에 대해서 입니다.

  1. Github와 연결된 Circle CI project setting에서 PERMISSIONS에 서버 SSH Key를 복사해서 추가합니다.
  2. circle.yml에 deployment를 추가하고 관련된 코드들을 입력합니다.
  3. 원격 서버에 설치 스크립트를 추가합니다.


배포 세팅 과정

Circle CI에 연결된 프로젝트에 SSH Key를 추가

서버에 SSH 접속을 할 때 사용하는 Key를 Circle CI에 추가하도록 합시다.

Circle CI에 들어가서 로그인 하고 대시보드에서 좌측에 보면 프로젝트 목록이 있는데 옆에 있는 톱니바퀴 모양을 클릭해 설정에 들어가도록 합니다.

Circle CI Project Setting Icon


프로젝트에 들어가면 아래 보이는 바와 같이 SSH Permissions를 클릭합니다.

SSH Permissions


그러면 메인 화면에 아래와 같이 SSH Key를 추가 할 수 있는 창이 나오며 여기서 가장 우측에 파란 버튼인 Add SSH Key를 선택합니다.

Add SSH Key


아래와 같은 다이얼로그 창이 나오면 Hostname에 해당서버 이름을 Private Key에 해당 서버에 대한 개인키를 넣습니다.

여기서 개인키를 넣을 때 -----BEGIN RSA PRIVATE KEY-----부터 -----END RSA PRIVATE KEY-----까지 모두 복사해서 붙여넣으셔야 인식을 합니다!

Add SSH Dialog


이제 Circle CI에 Key를 추가하는 부분은 완료 되었습니다. 위의 과정을 제대로 추가하셨다면 Circle CI에서 자동으로 ~/.ssh폴더에 id_[Hostname]의 형태로 키를 저장해줍니다.


circle.yml에 branch 추가 및 커맨드 추가

이제 circle.yml에 특정 branch에 Merge되면 Deplyment를 진행하는 코드를 추가하겠습니다. 코드는 아래와 같이 매우 간단합니다.

circle.yml

...

deployment:
    [name]:
        branch: [branch name]
        commands:
            - [command for deployment]

...


LinkU 서비스의 같은 경우 개발환경에 대한 배포는(branch도 develop 브랜치) 아래처럼 만들었습니다.

circle.yml


...

deployment:
    development:
        branch: develop
        commands:
            - ./deploy_to_development_server.sh

...


배포 스크립트 작성

이제 스크립트를 실행시켜서 원격 서버에 접속해 배포하는 과정을 해봅시다.

원격 서버에 접속하고 명령어들을 실행하는 법부터 보면 아래와 같습니다.

#!/bin/bash
ssh [user]@[domain] -i [ssh private key file] -o StrictHostKeyChecking=no <<'ENDSSH'
...
commands
...
ENDSSH
  • <<'ENDSSH' 부터 아래 있는 ENDSSH까지 있는 명령어들을 원격서버에서 실행합니다. 이때 << 다음에 오는건 꼭 ENDSSH일 필요는 없고 원하시는대로 입력해도 되지만 마지막에는 꼭 같아야합니다.
  • StrictHostKeyChecking=no는 ssh key fingerprint를 무시하고(서버에 키를 무조건 저장하고) 진행한다는 의미이며, ssh로 원격 서버에 접속할 때 yes or no룰 묻지 않습니다.


이제 원격서버의 유저 Root Directory에(cd ~) ./set_up_server.sh라는 스크립트가 있다면 아래처럼 실행 할 수 있습니다.

#!/bin/bash
ssh -p [port number] [user]@[domain] -i [ssh private key file] -o StrictHostKeyChecking=no <<'ENDSSH'
./set_up_server.sh
exit
ENDSSH


링쿠 서비스의 경우 다음처럼 스크립트를 작성하였습니다. 다만 보안상 포트 번호만 가리겠습니다. Circle CI에서 저장한 SSH key Host 이름이 linku-dev라면 ~/.ssh/폴더에 접미사 id_가 붙어서 id_linku-dev로 저장되어있습니다!

#!/bin/bash
ssh -p [port number] linku@dev.linkuniversity.me -i ~/.ssh/id_linku-dev -o StrictHostKeyChecking=no <<'ENDSSH'
./set_up_server.sh
exit
ENDSSH


원격 서버에 배포 스크립트 추가

위의 글에서 ./set_up_server.sh라는 쉘 스크립트 파일을 통해서 서버에 서버를 세팅합니다. 해당 sh파일에 원하는 서버 세팅 코드를 추가해주시면 됩니다.

예제로 저희 프로젝트 코드를 보여드리겠습니다.

set_up_server.sh

#!/bin/bash
cd /home/linku
./set_up_frontend.sh
./set_up_backend.sh

다음은 set_up_backend.sh의 코드입니다. 불필요한 부분도 있기에 중간은 생략하겠습니다.

set_up_backend.sh

#!/bin/bash
source ~/.bash_profile
cd /home/linku/LinkU;
git pull origin master;
cd /home/linku/LinkU/linku_backend;
pyenv activate LinkU;
pip install -r requirements.txt;
python manage.py makemigrations;
python manage.py migrate;
UWSGI_COUNT=$(pgrep -c uwsgi)
if [ $UWSGI_COUNT -ge 1 ]
then
        ...
else
        ...
fi
pyenv deactivate;


마무리

이제 develop 브랜치에 merge가 되면 자동으로 서버에 배포가 되게 됩니다! :)