AWS 기반 배포 환경 구축과 테스트 경험 정리
최근 프로젝트를 진행하면서 단순히 기능 개발만 하는 것이 아니라, 실제 서비스처럼 “배포 가능한 환경”을 직접 구축해보는 경험을 하게 되었습니다.
특히 AWS를 활용한 서버 배포, 환경 설정, 배포 도구 구성, 그리고 최종 테스트 과정까지 경험하면서 단순한 로컬 개발과는 전혀 다른 영역이라는 것을 느낄 수 있었습니다.
이번 글에서는 제가 진행했던 AWS 활용 계획부터 배포 환경 설정, 배포 도구 구성, 그리고 테스트 과정까지 전체 흐름을 정리해보려고 합니다.
왜 배포 환경이 중요한가?
처음 프로젝트를 시작하면 대부분은 로컬 환경에서 개발을 진행합니다.
예를 들어:
- localhost:3000
- localhost:5173
- localhost:8080
이런 형태로 실행하게 됩니다.
하지만 실제 서비스는 로컬 환경에서 동작하지 않습니다.
실제 서비스는 다음과 같은 요소들이 필요합니다.
- 외부 사용자가 접속 가능한 서버
- 데이터베이스 운영 환경
- 보안 설정
- HTTPS
- 로그 관리
- 장애 대응
- 배포 자동화
- 서버 재시작 및 프로세스 관리
즉, 개발만 잘한다고 끝나는 것이 아니라 “운영 가능한 형태”로 만드는 과정이 반드시 필요합니다.
그리고 이 과정을 담당하는 대표적인 클라우드 플랫폼 중 하나가 바로 AWS입니다.
AWS를 사용하는 이유
AWS(Amazon Web Services)는 현재 가장 많이 사용되는 클라우드 플랫폼 중 하나입니다.
대표적으로 다음과 같은 장점이 있습니다.
1. 높은 확장성
서비스 규모가 커지면 서버도 함께 확장할 수 있습니다.
예를 들어:
- 사용자가 많아짐
- 트래픽 증가
- 이미지 업로드 증가
- 실시간 소켓 통신 증가
이런 상황에서 AWS는 서버를 유연하게 확장할 수 있도록 도와줍니다.
2. 다양한 서비스 제공
AWS는 단순히 서버만 제공하는 것이 아닙니다.
대표적인 서비스는 다음과 같습니다.
| EC2 | 가상 서버 |
| RDS | 데이터베이스 |
| S3 | 파일 저장 |
| CloudFront | CDN |
| Route53 | DNS |
| IAM | 권한 관리 |
| CloudWatch | 로그/모니터링 |
| ElastiCache | Redis 캐시 |
즉, 실제 서비스를 구성하는 대부분의 요소를 AWS 안에서 해결할 수 있습니다.
3. 실제 현업에서 많이 사용
많은 기업들이 AWS 기반으로 인프라를 운영합니다.
따라서 프로젝트 단계에서 AWS를 경험해보는 것은 단순한 학습 이상의 의미가 있습니다.
특히:
- 서버 배포
- 인프라 구조
- 환경 변수 관리
- 보안 그룹
- 운영 로그
- 장애 대응
같은 경험은 이후 실무에서도 매우 도움이 됩니다.
AWS 활용 계획
프로젝트 초기에는 어떤 구조로 서비스를 배포할 것인지 먼저 계획을 세워야 했습니다.
단순히 “서버 하나 띄우기”가 아니라 전체 구조를 생각해야 했습니다.
예를 들어:
- 프론트엔드 배포 위치
- 백엔드 서버 위치
- 데이터베이스 운영 방식
- Redis 사용 여부
- 이미지 저장 위치
- 도메인 연결 방식
등을 고려해야 했습니다.
전체 배포 구조 설계
저희 프로젝트는 대략 다음과 같은 흐름으로 설계했습니다.
사용자 브라우저
↓
프론트엔드 서버
↓
백엔드 API 서버
↓
DB / Redis
그리고 각각의 역할을 나누었습니다.
프론트엔드
프론트는 React + Vite 기반으로 구성되어 있었습니다.
배포 시에는:
pnpm build
를 통해 정적 파일을 생성하고 이를 배포했습니다.
백엔드
백엔드는:
- Node.js
- Express 또는 NestJS
- TypeScript
기반으로 구성되었습니다.
실제 서버에서는:
- PM2
- Node 실행 환경
- 환경 변수
- 포트 관리
등이 필요했습니다.
데이터베이스
PostgreSQL 기반으로 운영했습니다.
로컬에서는 Docker 기반으로 실행했지만 운영 환경에서는 별도 서버 또는 클라우드 DB 환경을 고려했습니다.
Redis
실시간 기능과 캐싱 처리를 위해 Redis도 함께 사용했습니다.
특히:
- 랭킹 캐시
- 오늘 목표 조회 캐시
- 타이머 상태
- 실시간 데이터 처리
등에서 Redis가 중요한 역할을 했습니다.
배포 환경 설정
실제 배포를 진행하면서 가장 먼저 해야 했던 것은 서버 환경 설정이었습니다.
EC2 서버 생성
AWS에서 가장 대표적인 서버 서비스는 EC2입니다.
EC2는 가상 서버를 생성할 수 있는 서비스입니다.
처음에는 다음과 같은 작업을 진행했습니다.
1. 인스턴스 생성
운영체제를 선택합니다.
보통:
- Ubuntu
- Amazon Linux
등을 많이 사용합니다.
저는 Ubuntu 환경을 사용했습니다.
2. 키 페어 생성
EC2 접속을 위해 .pem 키 파일을 생성합니다.
이 파일은 SSH 접속에 사용됩니다.
예:
ssh -i key.pem ubuntu@ip주소
3. 보안 그룹 설정
보안 그룹은 AWS의 방화벽 개념입니다.
여기서:
- 22번 포트 (SSH)
- 80번 포트 (HTTP)
- 443번 포트 (HTTPS)
- 서버 포트
등을 열어야 합니다.
예를 들어:
22 → SSH 접속
80 → HTTP
443 → HTTPS
3000 → Node 서버
서버 초기 세팅
서버에 접속한 이후에는 개발 환경을 구성해야 했습니다.
Node.js 설치
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install nodejs
pnpm 설치
프로젝트에서 pnpm을 사용했기 때문에 설치가 필요했습니다.
npm install -g pnpm
Git 설치
sudo apt install git
이후 GitHub 저장소를 clone 했습니다.
git clone repository-url
환경 변수 설정
실제 배포에서 가장 중요한 부분 중 하나가 환경 변수입니다.
예를 들어:
DATABASE_URL=
JWT_SECRET=
REDIS_URL=
AWS_ACCESS_KEY=
AWS_SECRET_KEY=
같은 값들은 절대로 코드에 직접 올리면 안 됩니다.
따라서 .env 파일을 통해 관리했습니다.
환경 변수 관리가 중요한 이유
환경 변수는 다음과 같은 민감한 정보를 포함합니다.
- DB 비밀번호
- JWT Secret
- AWS 키
- Redis 주소
- API Key
만약 GitHub에 잘못 업로드되면 큰 문제가 발생할 수 있습니다.
따라서:
.env
설정도 반드시 필요했습니다.
배포 도구 설정
서버에서 단순히:
node server.js
로 실행하는 것은 매우 위험합니다.
왜냐하면:
- 서버가 꺼질 수 있음
- SSH 종료 시 프로세스 종료 가능
- 로그 관리 어려움
- 재시작 불가능
등의 문제가 있기 때문입니다.
PM2 사용
그래서 PM2를 사용했습니다.
PM2는 Node.js 프로세스 매니저입니다.
설치:
npm install -g pm2
실행:
pm2 start dist/main.js
PM2의 장점
1. 서버 자동 재시작
프로세스가 죽으면 자동 복구됩니다.
2. 로그 확인 가능
pm2 logs
를 통해 로그를 쉽게 확인할 수 있습니다.
3. 상태 확인
pm2 status
현재 서버 상태를 확인할 수 있습니다.
4. 재부팅 후 자동 실행
pm2 startup
pm2 save
를 통해 서버 재부팅 이후에도 자동 실행됩니다.
Nginx 설정
실제 서비스에서는 Nginx도 매우 중요했습니다.
Nginx는:
- Reverse Proxy
- HTTPS 처리
- 로드 밸런싱
- 정적 파일 처리
등을 담당합니다.
Reverse Proxy 구조
예를 들어:
사용자 → 80포트
Nginx → Node 서버 3000포트
이런 구조로 연결됩니다.
Nginx 설정 예시
server {
listen 80;
location / {
proxy_pass http://localhost:3000;
}
}
HTTPS 적용
실제 서비스에서는 HTTPS가 매우 중요합니다.
이를 위해 Let's Encrypt를 사용했습니다.
대표적으로:
sudo certbot --nginx
를 사용하여 HTTPS 인증서를 적용할 수 있습니다.
Redis 운영 경험
프로젝트에서는 Redis를 적극적으로 사용했습니다.
특히 캐시 처리에서 Redis의 효과를 체감할 수 있었습니다.
예를 들어:
- 목표 리스트 조회
- 랭킹 조회
- 타이머 상태
등을 캐싱했습니다.
캐시의 장점
DB를 직접 조회하는 대신 Redis에서 데이터를 가져오기 때문에 훨씬 빠릅니다.
예:
DB 조회 → 느림
Redis 조회 → 매우 빠름
하지만 Redis도 장애가 발생한다
실제로 운영 환경에서는 Redis 연결 오류도 경험했습니다.
예를 들어:
SocketClosedUnexpectedlyError
ClientClosedError
같은 문제들이 발생했습니다.
처음에는 당황했지만 이를 통해 중요한 점을 배웠습니다.
운영 환경에서는 장애 대응이 중요하다
단순히 기능만 구현하는 것이 아니라:
- Redis 장애 시 fallback
- DB fallback 처리
- timeout 처리
- reconnect 처리
등이 매우 중요했습니다.
예를 들어:
try {
return await redis.get(key);
} catch {
return dbData;
}
같은 방식으로 안정성을 높였습니다.
캐시 전략 고민
모든 데이터를 무조건 캐싱하면 오히려 문제가 생길 수도 있었습니다.
예를 들어:
- 실시간성이 중요한 데이터
- 자주 변경되는 데이터
- 사용자별 데이터
는 캐시 정합성 문제가 발생할 수 있었습니다.
특히:
- 오늘 목표 리스트
- 타이머 상태
는 캐싱 전략을 매우 신중하게 설계해야 했습니다.
배포 환경 테스트
배포 이후에는 반드시 테스트가 필요했습니다.
단순히 “배포 성공”이 끝이 아닙니다.
테스트 항목
실제로 다음과 같은 부분들을 확인했습니다.
1. API 정상 동작 여부
- 로그인
- 회원가입
- 목표 생성
- 타이머 시작
- 타이머 종료
등이 정상 동작하는지 확인했습니다.
2. 환경 변수 적용 여부
운영 환경에서 .env 값이 정상 반영되는지 테스트했습니다.
3. Redis 연결 상태
Redis가 정상 연결되는지 확인했습니다.
로그를 통해:
Redis Connected
Redis Ready
등을 확인했습니다.
4. DB 연결 확인
Prisma 연결 상태도 확인했습니다.
5. 서버 재시작 테스트
PM2 재시작 이후 정상 복구되는지 확인했습니다.
6. 캐시 동작 테스트
동일 요청 시:
- 첫 요청은 DB 조회
- 두 번째 요청은 Cache Hit
가 되는지 확인했습니다.
실제 운영 환경에서 느낀 점
배포를 직접 경험하면서 가장 크게 느낀 것은:
개발과 운영은 완전히 다른 영역이라는 점입니다.
로컬에서는 잘 동작하던 코드가 운영 환경에서는 예상치 못한 문제를 만들기도 했습니다.
예를 들어:
- 환경 변수 누락
- 포트 충돌
- Redis 연결 실패
- CORS 문제
- HTTPS 문제
- 서버 재시작 이슈
등이 발생했습니다.
가장 어려웠던 부분
개인적으로 가장 어려웠던 부분은:
“정합성 유지”
였습니다.
특히 캐시를 사용할 때:
데이터 수정
→ 캐시 삭제
→ 새로운 데이터 생성
흐름을 제대로 관리하지 않으면 오래된 데이터가 보여질 수 있었습니다.
이 과정에서:
- 캐시 무효화
- TTL 설정
- fallback 처리
등의 중요성을 크게 느꼈습니다.
배포 경험을 통해 얻은 것
이번 경험을 통해 단순히 코드를 작성하는 것 이상의 것들을 배우게 되었습니다.
예를 들어:
- 서버 운영 흐름
- 클라우드 구조
- 보안 설정
- 환경 변수 관리
- 장애 대응
- 캐시 전략
- HTTPS 적용
- 프로세스 관리
등을 실제로 경험할 수 있었습니다.
마무리
처음에는 AWS와 배포 환경이 굉장히 어렵게 느껴졌습니다.
하지만 직접 서버를 만들고, 환경을 구성하고, Redis와 DB를 연결하고, 실제 API를 운영해보면서 단순한 “기능 개발” 이상의 경험을 얻을 수 있었습니다.
특히:
- 실제 서비스 구조를 이해하게 되었고
- 운영 환경의 중요성을 체감했으며
- 안정적인 서비스를 만들기 위해 어떤 고민이 필요한지 배우게 되었습니다.
앞으로는 단순히 기능 구현만 하는 개발자가 아니라:
“운영까지 고려할 수 있는 개발자”
가 되는 것을 목표로 계속 경험을 쌓아가고 싶습니다.
'pgms' 카테고리의 다른 글
| [19주차] - [9기] 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 10회차 - 85 (0) | 2026.05.21 |
|---|---|
| [19주차] - [9기] 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 10회차 - 84 (0) | 2026.05.18 |
| [18주차] - [9기] 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 10회차 - 82 (0) | 2026.05.14 |
| [18주차] - [9기] 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 10회차 - 81 (0) | 2026.05.13 |
| [18주차] - [9기] 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js) 10회차 - 80 (0) | 2026.05.12 |