배포를 자동화하고, 무중단 배포를 구현해보자 (2)
배포를 자동화하고, 무중단 배포를 구현해보자 (3)
배포를 자동화하고, 무중단 배포를 구현해보자 (4)
기존에 vercel에 배포를 전적으로 위임했던 것을 벗어나 AWS를 이용하여 서비스를 운영해 보고자 했다. 이유는 상업적 서비스는 private 레포로 관리되곤 하는데 private 레포에 대해서는 비용이 지불되기 때문이다. 어떻게 해도 서버리스보다 직접 서버를 운영하는 것이 비용이 저렴할 것이기 때문에 AWS를 이용하여 배포 해 보자고 생각했다. 사실 그렇게 어렵진 않기 때문에...
우선 처음 도입했던 방법은 github webhook을 이용한 방법이었다. 하지만 제목이 실패편이듯 이 방법은 대실패 했다.
일단 레포에서 webhook 설정을 통해 푸시가 되면 특정 주소로 post 요청이 발생하도록 하였다.
그리고 ec2 인스턴스에서 서버를 하나 돌려서 이 요청이 발생하면 빌드, 배포 스크립트를 실행하도록 하였다. 서버는 express로 간단하게 구현하였다.
app.post('/webhook/tp', (req, res) => {
if (port === 3001) {
exec('./tp.3002.sh', (err, stdout, stderr) => {
if (err) {
logToFile('error-log.txt', err);
}
if (stdout) {
logToFile('stdout-log.txt', stdout);
}
if (stderr) {
logToFile('stderr-log.txt', stderr);
}
});
port = 3002;
res.status(200).send('Switched to port 3002');
return;
}
if (port === 3002) {
exec('./tp.3001.sh', (err, stdout, stderr) => {
if (err) {
logToFile('error-log.txt', err);
}
if (stdout) {
logToFile('stdout-log.txt', stdout);
}
if (stderr) {
logToFile('stderr-log.txt', stderr);
}
});
port = 3001;
res.status(200).send('Switched to port 3001');
return;
}
});
app.listen(8080, () => {
console.log('Server is running on port 8080');
});
포트 번호 체크하는 것은 무중단 배포 때문이고, 해당 엔드포인트로 post 요청이 발생하면 exec로 스크립트 파일을 실행시키는 간단한 서버다. 스크립트 파일엔 git pull 땡기고 빌드하고, 서버를 시작하는 명령어가 들어있다.
하지만 이때 문제가 발생했다. ec2 인스턴스가 프리티어를 사용중이었기 때문에 컴퓨팅 자원이 아주 제한적이다. 그 때문에 nginx도 구동중이고 서비스도 돌아가고 있는 인스턴스에서 빌드를 돌렸을 때 인스턴스가 꺼져버리는 현상이 자주 발생했다.
그래서 빌드와 배포를 분리하는 작업이 필요해졌다. 나중에 알아보니 빌드와 배포를 분리하는 것이 당연한 거였음... 확장성과 안전성, 유연성 등에서 차이가 있음 ex) 동일한 빌드를 QA, 스테이징 및 프로덕션 환경에 배포하는 등..
일단 빌드 서버와 배포 서버를 분리하기로 결정하였다.