[목표]
CI/CD를 구축합니다.
프로젝트 상세 페이지 구상합니다.
지금까지의 CURD 작업물들을 모두 Merge합니다. [중요]
멘토님과 디스코드로 뵙기.
nginx 적용하기
배포를 위해 배포시 포트번호 변환 적용하기
어제 하다 못한 병합을 하고 있다.먼저 권호형과 내 코드의 병합은 마쳤다.
프론트엔드 전체적인 파일 구조 리펙토링, NEXTjs 기준으로 라우팅되는 URL 폴더별로 정렬, 각 URL에 페이지불러오는 page.tsx와 그 페이지의 구성요소 _components폴더로 구성하고 최상단의 components는 전역적으로 사용하는 header나 footer와 같은 요소만 포함했다.
윤호형이랑 권호형이랑 이야기 해서 백앤드 이슈부분을 통합했다. 아무문제없이 병합되어서 다행이다.
→ 현재 태용, 명석, 권호, 윤호 백앤드 병합 완료.
→ 태용, 명석, 권호 프론트앤드 병합 완료.
식사를 하고 왔습니다.

식사를 하고, 2시에 멘토님 뵙기 전에 질문 리스트 뽑아야함. 근데 병합하느라 정신 없어서 못했다.
멘토님이랑 이야기를 했다.
AI를 어떻게 쓸지?
AI를 어떤식으로 쓸지?
Ai를 도전해보고
파이프라인 작성하기
MCP정도 사용하는 건 어떤가?
LLM정도는 프로젝트의 모듈 도입?
조금더 생각을 많이 해보면 재밌는거 많이 할 수 있을 것 같다.
정글하면서 중장기적으로
프러덕트에 대한 오너쉽
월요일(아무때나 상관 없음)과 목요일 멘토님
중간에 이슈가 있으면 연락도 가능하다고 함.
너무 아쉬운 멘토링이었다. 우리가 준비가 덜 된것 같았다. 사실 일목요연하게 말씀 드려야하는데 졸리고 정신이 없어서 못했다… 그래도 멘토님이 좋은 피드백을 주셔서 감사했다.
멘토님과 이야기를 나누고, 병합관련 공지, 각자 기능구현 완료되면 머지하고 후위 사람이 충돌나면 책임지고 해당 사람과 합의
(Merge를 할때 날짜 + 커밋로그에 어떤 기능 구현했는지 다 설명하기)
백앤드와 프론트앤드 파일 구조도 설명, 앞으로 각자의 폴더에 편집하면 되서 충돌날 위험이 없을거다라고 설명.
지금 파일구조 꼬여있는 진혁이형과 윤호형은 각자 풀 당겨와서 해결하기로 했음.
명석이 형의 JWT 토큰 관련 이야기
깃허브 API 설계
유저 - 프로젝트 - 이슈 매핑
요약(명석), 코드(), 설정(기본정보, 데이터 삭제, 팀관리), 내 이슈(윤호) 추가
CI/CD
어느정도 역할배분에 대한 이야기를 했다. 나같은 경우 개발보다는 프로젝트 운영에 초점을 맞추도록 하겠다. 프로젝트 디테일을 올려서 견고하게 구현해 나가는 것이 좋을 것 같다.
동생 게임 QA
dev 모든 파일 종합 완료.
병합후 Swagger 패키지 설치 관련 오류 수정 완료.
현재 진혁, 윤호 형이 dev에 있는 풀을 당겨서 문제사항들을 확인중에 있다. 나, 명석, 권호 병합된 것들에 대해 파일구조도가 완성되어서 그에 맞게 각자 교정하고 있다. 완료가 되면 이야기 하겠다.
식사를 하고 복귀를 했다. 동생 게임에 대해 리뷰를 기윤님과 성광이형과 함께 했다. 나중에 명석이 형도 해보는걸 부탁했다.
DB 프로젝트 설명 영문 오타 수정
권호형 칸반보드 위치처리 Position부분 DB에 왕복을하면 서버 리소스 낭비되지 않는가?
벨로그 28, 29일자 내용을 정리를 했다. 개발이 먼저라 금방 정리해서 올렸다.
저번에 CI/CD 이어서 구축하기로 해봤다. 오늘안에 끝내보도로 하겠다.
깃허브 액션과 EC2, SES를 사용해본다.
디렉토리와 Git프로젝트가 없다는 오류가 나와서 EC2에 연결하여 클론하여 프로젝트 파일을 가져왔다. 백엔드 먼저 구축하기 때문에 codeplanner 폴더에 새로 깃 클론 받아 왔다.
EC2에서 NestJS으로 빌드된 백엔드 어플리케이션을 PM2패키지를 이용해 실행합니다.
다음 코드를 EC2 프로젝트 폴더에서 실행하면 됩니다.
pm2 start dist/main.js --name codeplanner-backend
다음 코드를 이어서 실행하면 부팅시 자동 실행으로 등록됩니다.
pm2 save && pm2 startup
pm2 list
근데 해당 사항에는 문제가 있다. 현재 개발 때문에 localhost:5000으로 되어 있어서 배포는 되어도 인터넷에 뜨지 않는다. 그러므로 개발할땐 localhost로 배포시엔 EC2ip로 작업하게끔 설정해보겠다.
네, 배포 환경(EC2)과 개발 환경(localhost)에서 각각 다른 CORS 설정과 포트, 환경변수를 자동으로 적용하려면 .env 파일과 환경변수 관리가 필요합니다. NestJS에서는 @nestjs/config 패키지를 사용해 환경변수를 쉽게 관리할 수 있습니다.
아래와 같이 진행하면 됩니다:
1. @nestjs/config 설치
npm install @nestjs/config
2. .env 파일 만들기
프로젝트 루트에 .env.development, .env.production 파일을 각각 만듭니다.
예시:
PORT=5000
CORS_ORIGIN=http://localhost:3000,http://localhost:5000PORT=5000
CORS_ORIGIN=http://<EC2_IP>:50003. AppModule에 ConfigModule 추가
src/app.module.ts에서 ConfigModule을 import하고 설정합니다.
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
// ... 기존 import
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
envFilePath: process.env.NODE_ENV === 'production' ? '.env.production' : '.env.development',
}),
// ... 기존 모듈
],
// ... 나머지 코드
})
export class AppModule {}
4. main.ts에서 환경변수 사용
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const corsOrigin = process.env.CORS_ORIGIN?.split(',') || ['http://localhost:3000'];
app.enableCors({
origin: corsOrigin,
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
credentials: true,
});
const port = process.env.PORT || 5000;
await app.listen(port);
console.log(`🚀 Listening on ${port}`);
}
bootstrap();
5. Github Actions에서 환경설정 (이건 main 브런치의 .github/workflows/deplay.yml에 추가)
예시 (Github Actions yml):
- name: Run app
run: |
export NODE_ENV=production
npm run start:prod
요약
궁금한 점 있으면 언제든 질문해주세요!
필요하다면 위 단계별로 코드 적용도 도와드릴 수 있습니다.
→ 위와 같은 순서로 구현했습니다. 중간에 EC2 SSH 이름 오류가 있었으나 금방 해결하고 배포 확인을 하였습니다.
지금 상태에선 웹브라우저로 조회가 되지 않는다. 그래서 찾아보았더니 EC2에서 보안그룹으로 차단해서 그런것 같아 인바운드 허용으로 허용해보았다.
포트 연결을 위해 Nginx 설정도 했다. 밑의 GPT 설명대로 실행했다.
/etc/nginx/sites-enabled/codeplanner.conf 파일이 없다면 Nginx가 현재 어떤 서비스도 리버스 프록시하거나 서빙하지 않는 상태입니다.
따라서 직접 설정 파일을 생성해야 합니다.
sudo nano /etc/nginx/sites-available/codeplanner.conf
예시 설정 (NestJS: 3000번 포트 기준, 도메인 codeplanner.kr):
server {
listen 80;
server_name codeplanner.kr www.codeplanner.kr;
location / {
proxy_pass http://localhost:3000; # NestJS가 3000에서 실행 중
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
sudo ln -s /etc/nginx/sites-available/codeplanner.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
http://codeplanner.kr 또는 EC2 퍼블릭 IP 접속 확인certbot --nginx로 HTTPS 설정 진행| 항목 | 내용 |
|---|---|
| 파일 없음 | 기본적으로 sites-available → sites-enabled로 링크를 만들어야 동작 |
| 설정 필요 | NestJS나 Next.js 서버 포트에 맞춰 리버스 프록시 구성 필요 |
| reload 필요 | 설정 적용 시 반드시 nginx -t 후 systemctl reload nginx |
pm2 logs codeplanner-backend 해당 코드로 지금 실행중인 백앤드 서버를 확인할 수 있다.
사실 SQL이 없는데 실행시켜서 브라우저에 안뜬거였다. 그래서 연결을 해보겠다.
숙소에 갔다 왔습니다.
RDS를 이어서 설정해보겠습니다.
RDS 설정
EC2에서 PostgreSQL(RDS) 연결할 수 있게 보안 그룹 설정
EC2에 PostgreSQL 설정(설치) → 이게 기본으로 16.9가 최대인데 라이브러리를 수동으로 가져왔다.
PostgreSQL 17은 아직 정식 안정 버전으로 Ubuntu 기본 저장소에는 포함되지 않았습니다 (2025년 6월 기준). 그러나 공식 PostgreSQL APT 저장소를 추가하면 Ubuntu EC2 인스턴스에도 PostgreSQL 17 클라이언트 및 서버를 설치할 수 있습니다.
sudo apt update
sudo apt install wget ca-certificates gnupg lsb-release -y
sudo mkdir -p /etc/apt/keyrings
wget -qO - https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/keyrings/postgresql.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | \
sudo tee /etc/apt/sources.list.d/pgdg.list
sudo apt update
sudo apt install postgresql-client-17 -y
postgresql-client-17만 설치하면 서버 설치 없이도 psql 명령을 사용할 수 있습니다.
psql --version
예상 출력:
psql (PostgreSQL) 17.x
psql -h <RDS_엔드포인트> -U <사용자명> -d <DB명>
예시:
psql -h codeplanner-db.xxxxxx.ap-northeast-2.rds.amazonaws.com -U codeplanner -d codeplanner1234
→ 비밀번호 입력 후 접속되면 성공
| 항목 | 확인 필요 |
|---|---|
| 보안 그룹 설정 | RDS 보안 그룹에 EC2 인스턴스의 보안 그룹 허용 (TCP 5432) |
| RDS 퍼블릭 액세스 여부 | "퍼블릭 액세스 가능" 설정이 되어 있어야 함 (또는 EC2가 같은 VPC) |
필요하시면 PostgreSQL 17 클라이언트 설치 스크립트 또는 RDS와 NestJS 연동 설정 예시도 제공 가능합니다.
EC2 SSH를 통해 연결한후
psql -h [codeplannerdb.cjyeyk2qmmx3.ap-northeast-2.rds.amazonaws.com](http://codeplannerdb.cjyeyk2qmmx3.ap-northeast-2.rds.amazonaws.com/) -U root -d codeplanner
DDL, DML 쿼리문 EC2에 추가 완료.
EC2에선 정상적으로 연결되니, NestJS 다시 시작
밑의 방식이 기본임.
AWS 콘솔 > RDS > 인스턴스 선택 후 아래 정보 확인:
| 항목 | 예시 |
|---|---|
| 호스트명 | codeplanner-db.xxxxxxxxxxxx.ap-northeast-2.rds.amazonaws.com |
| 포트 | 5432 (기본값) |
| DB 이름 | codeplanner |
| 사용자 | codeplanner |
| 비밀번호 | 생성 시 설정한 비밀번호 |
.env 설정.env 파일 또는 환경변수에 아래와 같이 입력:
DB_HOST=codeplanner-db.xxxxxxxxxxxx.ap-northeast-2.rds.amazonaws.com
DB_PORT=5432
DB_USERNAME=codeplanner
DB_PASSWORD=your-password-here
DB_DATABASE=codeplanner
AppModule 또는 database.module.ts 등에서 TypeOrmModule.forRoot()를 아래와 같이 구성:
TypeOrmModule.forRoot({
type: 'postgres',
host: process.env.DB_HOST,
port: +process.env.DB_PORT,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
autoLoadEntities: true,
synchronize: false, // 운영 환경에서는 false
})
타입: PostgreSQL
프로토콜: TCP
포트 범위: 5432
소스: EC2의 보안 그룹 ID (예: sg-xxxxxxx)
이 설정을 해야 EC2 → RDS로 접속 가능
psql -h <DB_HOST> -U codeplanner -d codeplanner
비밀번호 입력 후 접속 가능하면 성공
없으면:
sudo apt install postgresql-client -y
pm2 restart codeplan
pm2 logs codeplan
오류 없이 실행되면 정상 연결 완료
| 단계 | 설명 |
|---|---|
| RDS 인스턴스 정보 확인 | 호스트, 포트, 사용자, 비밀번호 |
.env에 DB 정보 설정 | DB_HOST 등 |
| TypeORM 설정 반영 | TypeOrmModule.forRoot() |
| 보안 그룹 연결 허용 | EC2 → RDS 보안 그룹 설정 |
| 서비스 재시작 및 로그 확인 | pm2 logs |
필요하시면 TypeOrmModule 설정 코드 전체, .env 파일 샘플, 보안 그룹 설정 캡처 예시도 제공해 드릴 수 있습니다.
자동으로
ecosystem.config.js 파일을 백앤드 폴더에 추가 했다.
// ⚠️⚠️⚠️배포환경 관련 설정 주의 필요!!!⚠️⚠️⚠️
module.exports = {
apps: [
{
name: 'codeplanner-backend',
script: 'dist/main.js',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'development',
},
env_production: {
NODE_ENV: 'production',
},
},
],
};
EC2 Nodejs버전이 22로 동일한데, 다음과 같은 로그가 뜬다. GPT가 추천한대로 프로젝트 파일에 main.ts에 crypto 모듈 정의 추가해보기로 했다.
main.ts에 다음과 같은 내용을 추가했다.
import * as crypto from 'crypto';
// crypto 모듈을 전역으로 설정
(global as any).crypto = crypto.webcrypto;
ssh -i "C:\aws_key\codeplanner.pem" ubuntu@43.201.107.10
다음과 같은 오류가 난다.
0|codeplanner-backend | error: no pg_hba.conf entry for host "172.31.38.111", user "codeplanner", database "codeplanner", no encryption
0|codeplanner-backend | at Parser.parseErrorMessage (/home/ubuntu/codeplanner/Codeplanner_Backend/node_modules/pg-protocol/src/parser.ts:369:69)
0|codeplanner-backend | at Parser.handlePacket (/home/ubuntu/codeplanner/Codeplanner_Backend/node_modules/pg-protocol/src/parser.ts:187:21)
0|codeplanner-backend | at Parser.parse (/home/ubuntu/codeplanner/Codeplanner_Backend/node_modules/pg-protocol/src/parser.ts:102:30)
0|codeplanner-backend | at Socket.<anonymous> (/home/ubuntu/codeplanner/Codeplanner_Backend/node_modules/pg-protocol/src/index.ts:7:48)
0|codeplanner-backend | at Socket.emit (node:events:517:28)
0|codeplanner-backend | at addChunk (node:internal/streams/readable:368:12)
0|codeplanner-backend | at readableAddChunk (node:internal/streams/readable:341:9)
0|codeplanner-backend | at Socket.Readable.push (node:internal/streams/readable:278:10)
0|codeplanner-backend | at TCP.onStreamRead (node:internal/stream_base_commons:190:23)
0|codeplanner-backend | [Nest] 41882 - 06/30/2025, 6:10:01 PM ERROR [TypeOrmModule] Unable to connect to the database. Retrying (4)...
자꾸 연결이 되다 만다. 내가 RDS 보안 그룹 설정과 사용자 권한 삽질을 한 1시간정도 한것 같다.
그러다가 해당 글을 확인했다.
https://velog.io/@doohyunlm/error-no-pghba.conf-entry-for-host-user-database-no-encryption
postgreSQL이 15버전 이상부턴 SSL인증이 필수란다…
이걸 끌라고 파라미터 그룹도 수정했는데, 안되서 확인해보니 15이상부터는 내부에서 또 막는단다…
쉽지 않다. 그래도 해결법이 될수 있으니 설정해보겠다.
먼저, 아마존에서 글로벌 인증서pem 파일을 다운로드 받아서 백앤드 루트에 저장했다.
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html
.env.production에 다음과 같이 SSL인증 내용을 추가 했다.
DB_SSL=true
DB_SSL_CA_PATH=./global-bundle.pem
database.module.ts의 일부분을 수정했다. 전체 내용은 커밋 내용 참고.
useFactory: (config: ConfigService) => {
const isSSL = config.get('DB_SSL') === 'true';
const sslOptions = isSSL
? {
ca: fs.readFileSync(config.get('DB_SSL_CA_PATH') || './global-bundle.pem').toString(),
rejectUnauthorized: false,
}
: false;
제발 되길…
된다! ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ
근데 이게 끝이 아니다. 프론트엔드가 남았다. 힘내서 해보겠다.
프론트엔드는 벡엔드와 비슷해서 금방할 것 같다. (못했다.)
내일 프론트엔드 관련 설정 하기
추후 사항
https를 위해 Let’s 머시기 적용하기
Redis 적용하기(캐싱)
내가 오늘 할건 CI/CD랑 프로젝트 흐름 정리.
다음주 멘토님 미팅 요청 드리기!! (월,목)