도메인, HTTPS, 세션, 그리고 쿠키.. 말 그대로 백엔드 배포 삽질기

김하은·2025년 3월 24일
0

완전히 죽어버린 백엔드 서버를 다시 살리기
NestJS + EC2 + RDS + Nginx + OAuth + Session + HTTPS

다시 살려보자!

코끼리 사이트 너무 아깝다.

진짜 이쁘고, 진짜 열심이 만들었는데, 이대로 사라지게 둘 수는 없었다.

다시 살려 보자! 라는 마음에서 시작했다.

근데 백엔드 서버가 완전히 죽었다는 것을 알게 됐다.

완전히 죽었다는 뜻은, 프리티어 기간이 끝나서 EC2 서버가 통째로 사라졌다는 것.

RDS 주소도, 도메인도, 아무것도 남아있지 않았다.

처음부터 다시 시작해야 했다.

  • 기존 NestJS 백엔드 코드를 레포로 받아오고,
  • AWS EC2에서 서버를 다시 세팅하고,
  • RDS로 DB도 새로 만들고,
  • HTTPS 적용을 위해 Certbot과 Nginx 설정을 직접 해주고,
  • OAuth 키도 새로 발급받고,
  • CORS와 쿠키 관련 문제를 고치면서

빌드만 거의 100번은 했다.

기존에는 프론트 코드만 다뤘고, 배포는 쉽게만 했었는데,

이번엔 서버 인프라 전체를 직접 구성했다.

결과 → https://co-kkiri-api.com/

기술 스택

항목내용
백엔드 프레임워크NestJS
배포 대상AWS EC2 (Ubuntu 22.04)
DBMySQL (AWS RDS)
세션 저장소Redis
인증OAuth (Google, GitHub, Kakao)
웹서버Nginx + HTTPS (Certbot)
배포 자동화PM2
프론트 호스팅Netlify (dev.co-kkiri-api.com)
도메인AWS Route 53에서 구매, 서브도메인 사용 (be.co-kkiri-api.com)

백엔드 배포 과정

1. 서버 환경 구성

EC2 인스턴스 생성 (Ubuntu 22.04)

  • 퍼블릭 IP 자동 할당
  • 키페어 생성: co-kkiri.pem

SSH 접속

chmod 400 co-kkiri.pem
ssh -i "co-kkiri.pem" ubuntu@<EC2 퍼블릭 IP>

필수 패키지 설치

sudo apt update
sudo apt install -y nodejs npm git nginx
sudo apt install -y mysql-client

2. 프로젝트 설정 및 빌드

git clone https://github.com/내레포/BE_co-KKIRI.git
cd BE_co-KKIRI
npm install
touch .env
vim .env

.env 파일에는 아래와 같은 설정을 추가함:

DB_HOST=<rds-endpoint>
DB_PORT=3306
DB_USERNAME=admin
DB_PASSWORD=***
DB_NAME=cokkiri
COOKIE_NAME=***
COOKIE_SECRET=***
SESSION_COOKIE_DOMAIN=co-kkiri-api.com
REDIS_HOST=<redis-host>
REDIS_PORT=6379
REDIS_PASSWORD=***

3. PM2로 백엔드 실행

npm run build  # NestJS 프로젝트를 TypeScript → JavaScript로 컴파일하여 dist/ 폴더에 저장

pm2 start dist/main.js --name main  
# PM2로 빌드된 서버(main.js)를 실행함
# --name main: 프로세스 이름을 'main'으로 지정 (관리하기 쉬움)

pm2 save  
# 현재 실행 중인 PM2 프로세스 목록을 저장함 (재부팅 시 복구용)

pm2 startup  
# EC2 재부팅 시 PM2가 자동으로 실행되도록 시스템에 등록함
# 출력되는 명령어 (sudo ... update...)를 복사해서 실행해야 적용됨

4. RDS 구성

  • 새로운 MySQL RDS 인스턴스 생성 (프리티어)
  • 보안 그룹 인바운드 설정:
TypePortSource
MySQL/Aurora3306EC2 보안 그룹

접속 테스트

mysql -h <rds-endpoint> -u admin -p

TypeORM 설정 예시

TypeOrmModule.forRootAsync({
  useFactory: () => ({
    type: 'mysql',
    host: process.env.DB_HOST,
    port: 3306,
    username: process.env.DB_USERNAME,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    synchronize: true,
    autoLoadEntities: true,
  }),
});

⚠️ synchronize: true는 테스트 때만!

배포 시에는 반드시 false로 변경할 것.


5. Redis로 세션 저장

sudo apt install redis-server
redis-cli ping

.env 설정 추가

REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=

NestJS main.ts에서 Redis 연결

const redisClient = createClient({
  socket: {
    host: configService.get('REDIS_HOST'),
    port: configService.get('REDIS_PORT'),
  },
});

6. CORS + 쿠키 설정

이 부분에서 가장 많은 삽질을 했다.

문제

  • Set-Cookie는 오지만, 브라우저에 저장이 안 됨
  • 프론트와 백엔드의 도메인이 달라서 SameSite 정책 충돌

해결

app.enableCors({
  origin: ['https://co-kkiri-api.com'],
  credentials: true,
});
cookie: {
	maxAge: 1000 * 60 * 60 * 24,
  domain: '.co-kkiri-api.com',
  httpOnly: true,
  sameSite: 'lax',
}

7. Nginx + HTTPS 설정

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d be.co-kkiri-api.com

/etc/nginx/sites-available/be.co-kkiri-api.com

server {
  listen 80;
  server_name be.co-kkiri-api.com;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl;
  server_name be.co-kkiri-api.com;

  location / {
      proxy_pass http://localhost:8080;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
  }

  ssl_certificate /etc/letsencrypt/live/be.co-kkiri-api.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/be.co-kkiri-api.com/privkey.pem;
}

배운 점

  • 진짜 웹 서비스가 돌아가려면, 코드만으로는 안 된다.
  • 배포 환경, 도메인, 인증서, 세션, CORS, 쿠키, DB, Redis 등 전부 직접 관리해야 한다.
  • 그리고 이건 혼자 삽질하면서 직접 해봐야 알 수 있다.

마무리 요약

항목했던 일
EC2Ubuntu 설치 + 서버 실행
PM2백엔드 프로세스 관리
Nginx리버스 프록시 + HTTPS
Route53A레코드로 도메인 연결
CertbotLet’s Encrypt 인증서 발급
RDSMySQL 생성 + 보안 그룹 설정
Redis세션 저장소
OAuth3종 연동 + 세션 기반 로그인
CORS쿠키 포함 설정
Sessionredis + cookie 기반 인증
profile
아이디어와 구현을 좋아합니다!

0개의 댓글

관련 채용 정보