처음 서버 배포 체크리스트: 반드시 확인할 8가지

이거 빠뜨리면 나중에 고생한다. 서버 배포 체크리스트 8가지를 처음 배포할 때 가장 많이 놓치는 순서로 정리했다. 코드만 올리면 된다고 생각하기 쉽다. 실제로는 설정 하나 빠진 게 새벽 2시에 터진다.

서버 배포 과정에서 실행하는 명령어들을 보여주는 터미널 화면

1. 환경 변수 분리했는가

빠뜨리면: 로컬 localhost DB에 연결하거나 개발용 API 키로 운영 환경이 돌아간다.

.env 파일은 git에 올리지 않는다. 서버에는 운영용 값을 직접 설정한다.

# 서버에서 환경 변수 설정 확인
printenv | grep -E "DB_HOST|DB_PASSWORD|JWT_SECRET|API_KEY"

# .env 파일로 관리한다면
cat /app/.env

반드시 바꿔야 할 값:

  • DB_HOST: localhost → RDS 엔드포인트 또는 내부 IP
  • DB_PASSWORD: 운영 DB 비밀번호로 교체
  • JWT_SECRET: 로컬 개발용 값 그대로 쓰면 보안 취약
  • NODE_ENV: developmentproduction

2. 포트와 방화벽 열려 있는가

빠뜨리면: 서버는 살아 있는데 브라우저에서 접속이 안 된다.

AWS라면 보안 그룹, GCP라면 방화벽 규칙에서 아래 포트를 열어야 한다.

# 열려 있는 포트 확인 (Linux)
ss -tlnp

# ufw 방화벽 사용 시
sudo ufw status
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 22

최소 개방 포트: 80 (HTTP), 443 (HTTPS), 22 (SSH).

Node.js 앱이 3000번 포트에서 뜬다면 직접 3000을 열 필요는 없다. Nginx가 80/443을 받아서 내부 3000으로 프록시하는 방식을 쓰는 게 낫다.

# /etc/nginx/sites-available/myapp
server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

설정 후 Nginx 재시작: sudo systemctl restart nginx

3. 프로세스 매니저 설정했는가

빠뜨리면: 터미널을 닫으면 서버도 꺼진다. 서버가 크래시해도 자동으로 안 살아난다.

node app.js로 직접 실행하면 안 된다. PM2를 쓰자.

# PM2 설치
npm install -g pm2

# 앱 시작
pm2 start app.js --name myapp

# 서버 재부팅 시 자동 시작
pm2 startup
pm2 save

Docker를 쓴다면 restart: always 옵션을 확인한다.

# docker-compose.yml
services:
  app:
    image: myapp
    restart: always
    ports:
      - "3000:3000"

4. HTTPS 적용했는가

빠뜨리면: 브라우저가 “안전하지 않은 연결” 경고를 표시한다. 로그인, 쿠키, API 통신이 평문으로 전송된다.

Let’s Encrypt로 무료 SSL 인증서를 발급한다.

# Certbot 설치 (Ubuntu/Debian)
sudo apt install certbot python3-certbot-nginx

# 인증서 발급 + Nginx 자동 설정
sudo certbot --nginx -d example.com -d www.example.com

# 자동 갱신 확인 (90일마다 갱신 필요)
sudo certbot renew --dry-run

자동 갱신 크론잡 등록:

# crontab -e 에 추가
0 12 * * * certbot renew --quiet

5. 로그 수집 경로 잡혀 있는가

빠뜨리면: 배포 후 문제가 생겨도 원인을 찾을 방법이 없다.

기본 로그 위치를 파악해둔다.

# PM2 로그
pm2 logs myapp

# Nginx 로그
sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log

# systemd 서비스 로그
journalctl -u myapp --since "1 hour ago"

로그 파일이 무한히 커지지 않도록 로테이션을 설정한다. PM2는 pm2-logrotate 모듈로 처리한다.

pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7

6. DB 마이그레이션 실행했는가

빠뜨리면: 로컬에서 잘 돌아가던 코드가 운영 DB에서 테이블을 못 찾아서 500 에러를 뱉는다.

배포 후 반드시 마이그레이션을 실행한다.

# Prisma
npx prisma migrate deploy

# Sequelize
npx sequelize-cli db:migrate

# Django
python manage.py migrate

마이그레이션을 배포 스크립트에 넣어두면 매번 기억하지 않아도 된다.

#!/bin/bash
# deploy.sh
git pull origin main
npm install --production
npx prisma migrate deploy
pm2 restart myapp

7. 도메인 DNS 연결했는가

빠뜨리면: 서버 IP로는 접속이 되는데 도메인으로는 안 된다.

DNS 변경은 전파에 최대 48시간이 걸린다. 배포 당일에 설정하면 늦다. 도메인 DNS는 배포 전날 미리 설정해야 한다.

레코드 타입이름
A@서버 공인 IP
Awww서버 공인 IP
CNAMEwww@ (루트 도메인 가리킴)

DNS 전파 확인:

# 전파 상태 확인
dig example.com +short
nslookup example.com 8.8.8.8

8. 배포 후 헬스체크 했는가

빠뜨리면: 실제로 살아 있는지 모른 채 배포가 끝났다고 착각한다.

배포 직후 반드시 응답을 확인한다. 가장 빠른 방법은 curl이다.

# HTTP 응답 코드 확인
curl -I https://example.com

# 헬스체크 엔드포인트가 있다면
curl https://example.com/health

# 예상 응답
# HTTP/2 200

앱에 /health 엔드포인트를 만들어두면 모니터링 도구 연결이 쉬워진다.

// Express 예시
app.get('/health', (req, res) => {
  res.json({ status: 'ok', timestamp: new Date().toISOString() });
});

처음 서버 배포 자주 묻는 질문

8가지 중 반드시 먼저 해야 하는 순서가 있나?

DNS 설정은 전파 시간 때문에 제일 먼저 해야 한다. 나머지는 배포 직전에 순서 무관하게 확인해도 된다. 단, DB 마이그레이션은 앱 시작 직전에 실행해야 순서 오류가 없다.

GitHub Actions 같은 CI/CD 없이 배포할 때 이 체크리스트로 충분한가?

처음 배포라면 충분하다. 매번 수동으로 체크하는 게 번거롭다면 deploy.sh 스크립트에 마이그레이션, PM2 재시작, 헬스체크를 묶어두는 것부터 시작하자.

배포 직후 서버가 바로 죽으면 어떻게 진단하나?

pm2 logs --lines 50 또는 journalctl -u myapp --since "5 minutes ago" 로 즉시 로그를 확인한다. 가장 많은 원인은 환경 변수 누락, DB 연결 실패, 포트 충돌이다.

한눈에 보는 서버 배포 체크리스트

항목확인 포인트빠뜨리면
환경 변수운영용 DB, API 키, 시크릿 값로컬 DB에 연결, 보안 취약
포트/방화벽80, 443, 22 포트 개방접속 자체가 안 됨
프로세스 매니저PM2 또는 Docker restart: always터미널 종료 시 서버 꺼짐
HTTPSSSL 인증서 발급 및 자동 갱신브라우저 보안 경고
로그로그 경로 확인, 로테이션 설정장애 원인 파악 불가
DB 마이그레이션운영 DB 스키마 최신 상태테이블 없음 500 에러
DNSA 레코드, CNAME 설정 및 전파도메인으로 접속 불가
헬스체크curl로 응답 코드 확인배포 성공 여부 불명

한줄 정리: 서버 배포 체크리스트 8가지 중 DNS는 배포 전날, DB 마이그레이션은 앱 시작 직전, 헬스체크는 배포 직후 — 순서를 지키면 새벽 긴급 대응을 피할 수 있다.

댓글 남기기