From a6604fb956540eb2c05cd89e0e64f03b829e16c4 Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 13:39:43 +0900 Subject: [PATCH 01/13] refactor(image): Change env variable ENV to NODE_ENV --- .env.sample | 2 +- src/services/imageUpload.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.env.sample b/.env.sample index 40e23ad..96988c6 100644 --- a/.env.sample +++ b/.env.sample @@ -14,7 +14,7 @@ AWS_S3_ACCESS_KEY_ID='access key' AWS_S3_SECRET_KEY_ID='secret access key' #ENV -ENV='production | develop' +NODE_ENV='production | develop' #Using .env list # .env diff --git a/src/services/imageUpload.ts b/src/services/imageUpload.ts index c30b653..5ddbf56 100644 --- a/src/services/imageUpload.ts +++ b/src/services/imageUpload.ts @@ -8,7 +8,7 @@ import multerS3 from 'multer-s3' let storage -if (process.env.ENV === 'production') { //배포 환경일 때는 AWS로 +if (process.env.NODE_ENV === 'production') { //배포 환경일 때는 AWS로 const s3ClientParams = { region: process.env.AWS_S3_REGION ?? '', credentials: { @@ -84,7 +84,7 @@ function uploadImage(req: Request, res: Response) { // 유효성 검사 실패 } console.log(file) - if (process.env.ENV === 'production' && 'location' in file) { // Express.MulterS3.File 타입에 있는 location이 있는지 확인 + if (process.env.NODE_ENV === 'production' && 'location' in file) { // Express.MulterS3.File 타입에 있는 location이 있는지 확인 res.json({ message: 'Finish Upload', path: file.location }) } else { res.json({ message: 'Finish Upload', path: `/images/${file.filename}` }) From 37cbede22670be023c7188ca51528959d34938fa Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 13:40:06 +0900 Subject: [PATCH 02/13] feat(docker): Add docker related files --- .dockerignore | 20 ++++++++++++++++++ Dockerfile | 21 +++++++++++++++++++ docker-compose.yaml | 50 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yaml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..7d0fa80 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,20 @@ +# Dependencies +node_modules + +# Environment +.env +.env.test + +/generated/prisma +uploads/ +.dest +coverage + +# sprint sub +infra +http + +# Docker +Dockerfile +.dockerignore +docker-compose.yaml \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e789cc5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +# node js 환경 준비 +FROM node:22.16.0 + +# 소스코드 다운로드 +COPY . /panda-market + +# 소스코드 디렉토리 이동 +WORKDIR /panda-market + +# 의존성 패키지 설치 (npm ci) +RUN npm ci + +# 소스코드 빌드 +RUN npm run build + +# 환경 변수 정의 +ENV PORT=3000 +ENV NODE_ENV='develop' + +# 서버 실행 +CMD sh -c "npm run prisma:migrate && npm run start" \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..cd06930 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,50 @@ +name: panda-market +services: + panda-market-app: + image: seracine/panda-market-app:1.0.0 + restart: always # 에러 발생시 재시작 + build: + tags: + - seracine/panda-market-app:1.0.0 + - seracine/panda-market-app:latest + dockerfile: Dockerfile + pull: true + context: . + container_name: panda-market-app + ports: + - "3000:3000" + networks: + - panda-network + volumes: + - panda-app-volume:/panda-market/uploads + env_file: # env 파일로 환경변수 주입 + - .env + depends_on: + panda-market-postgres-db: + condition: service_healthy + panda-market-postgres-db: + image: postgres + restart: always # 에러 발생시 재시작 + container_name: panda-market-postgres + volumes: + - panda-db-volume:/var/lib/postgresql/data + networks: + - panda-network + environment: # 환경변수 파라미터 직접 전달 + - POSTGRES_PASSWORD=1234 + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 1m30s + timeout: 30s + retries: 5 + start_period: 30s + +networks: + panda-network: + name: panda-network + +volumes: + panda-app-volume: + name: panda-app-volume + panda-db-volume: + name: panda-db-volume From 031dcb83519353bca773f3b879a3c5d55c18a635 Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 14:42:58 +0900 Subject: [PATCH 03/13] feat(ci/cd): Add ci.yml --- .github/workflows/ci.yml | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a1180f9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,53 @@ +name: ci + +on: + push: + branches: main + pull_request: + branches: main + +jobs: + test: + runs-on: ubuntu-latest + # 테스트용 환경 변수 설정 + environment: TEST + env: + DATABASE_URL: ${{ secrets.DATABASE_URL }} + JWT_SECRET: ${{ secrets.JWT_SECRET }} + PORT: ${{ secrets.PORT }} + NODE_ENV: develop #production만 아니면 로직은 동일 + + services: + postgres: + image: postgres + env: + POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} + POSTGRES_DB: ${{ secrets.DB_NAME }} + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + + steps: + - name: Checkout code + - uses: actions/checkout@v5 + + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: 22 + + - name: Install dependencies + - run: npm ci + + - name: Type Check + - run: npx tsc --noEmit + + - name: Prisma migrate + - run: npm run prisma:migrate + + - name: Run Tests + - run: npm run test \ No newline at end of file From ffdbe6a7603165c6ceb903a39d3a94bad838a5b6 Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 14:54:38 +0900 Subject: [PATCH 04/13] fix(ci/cd) Add CI branch --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1180f9..3871c4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: ci on: push: - branches: main + branches: [main, 천수-sprint11] pull_request: - branches: main + branches: [main, 천수-sprint11] jobs: test: From acff147aa733144674492b1eb8c589c46b9232cf Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 15:00:33 +0900 Subject: [PATCH 05/13] fix(ci/cd): Fix indent --- .github/workflows/ci.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3871c4c..1ce6370 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,22 +32,22 @@ jobs: - 5432:5432 steps: - - name: Checkout code - - uses: actions/checkout@v5 + - name: Checkout code + uses: actions/checkout@v5 - - name: Setup Node.js - uses: actions/setup-node@v5 - with: - node-version: 22 + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: 22 - - name: Install dependencies - - run: npm ci + - name: Install dependencies + run: npm ci - - name: Type Check - - run: npx tsc --noEmit + - name: Type Check + run: npx tsc --noEmit - - name: Prisma migrate - - run: npm run prisma:migrate + - name: Prisma migrate + run: npm run prisma:migrate - - name: Run Tests - - run: npm run test \ No newline at end of file + - name: Run Tests + run: npm run test \ No newline at end of file From a57c9902dcdecbe2a474fd2ee0bbb6fd4cb23199 Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 15:03:01 +0900 Subject: [PATCH 06/13] fix(ci/cd): Fix test command --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ce6370..1cffbda 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,4 +50,4 @@ jobs: run: npm run prisma:migrate - name: Run Tests - run: npm run test \ No newline at end of file + run: npm run jest:test \ No newline at end of file From 1cdfb965a6f924b322120d4f5d9b85a30ca52882 Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 15:27:54 +0900 Subject: [PATCH 07/13] fix(ci/cd): Divide github action condition --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1cffbda..e4ec4d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: ci on: push: - branches: [main, 천수-sprint11] + branches: [천수-*] pull_request: - branches: [main, 천수-sprint11] + branches: [main] jobs: test: From 9279a2b85123db3cfe2d3118c4558c8330158b40 Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 17:05:10 +0900 Subject: [PATCH 08/13] feat(ci/cd: Add AWS_Deploy cd --- .github/workflows/cd.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/cd.yml diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..745725b --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,28 @@ +name: cd + +on: + push: + branches: + - main + +jobs: + AWS_deploy: + runs-on: ubuntu-latest + environment: AWS_Deploy + steps: + # EC2 배포 + - name: Deploy to EC2 + uses: appleboy/ssh-action@v1.2.2 + with: + host: ${{ secrets.EC2_HOST }} + username: ${{ secrets.EC2_USER }} + key: ${{ secrets.EC2_PRIVATE_KEY }} + port: 22 + script: | + cd ~/3-sprint-mission # EC2 인스턴스 내 프로젝트 경로로 진입 + git pull origin main # 코드 최신화 + npm install + npm run build # ts -> js + npm run prisma:migrate # Prisma 마이그레이션 + pm2 restart codeit-sprint10 # 이전 스프린트10때 프로세스 이름을 codeit-sprint10으로 설정했음 + echo "✅ Deployment successful!" \ No newline at end of file From 70953efbf696e0ed1d11006427ba7c401f3ff696 Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 17:27:29 +0900 Subject: [PATCH 09/13] docs(README.md): Add sprint11 info --- README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 21fd51f..0974674 100644 --- a/README.md +++ b/README.md @@ -308,4 +308,31 @@ - 환경변수를 통해, 운영 환경이라면 multer-s3를 이용하여 운영 환경시에는 aws를 사용하도록 수정하였습니다. - AWS 프리티어 사용이 불가하여 제출을 최대한 늦게 하였습니다. - 요구사항 자체는 프리티어에서 사용 가능한 인스턴스 유형을 사용하였습니다 -- pm2의 ecosystem.config.js는 강의 시간에 다루지 않았던 내용이라 간단하게 찾아보고 적용을 해보았습니다. 적절하지 않은 설정이 있거나 보완할 수 있는 내용이 있는지 궁금합니다. \ No newline at end of file +- pm2의 ecosystem.config.js는 강의 시간에 다루지 않았던 내용이라 간단하게 찾아보고 적용을 해보았습니다. 적절하지 않은 설정이 있거나 보완할 수 있는 내용이 있는지 궁금합니다. + +--- +# 스프린트 미션 11 + +## ✅ 요구사항 + +### Github Actions 활용 + +- [x] 브랜치에 pull request가 발생하면 테스트를 실행하는 액션을 구현해 주세요. +- [x] main 브랜치에 push가 발생하면 AWS 배포를 진행하는 액션을 구현해 주세요. +- [x] 개인 Github 리포지터리에서 Actions 동작을 확인해 보세요. + +### Docker 이미지 만들기 + +- [x] Express 서버를 실행하는 Dockerfile을 작성해 주세요. +- [x] Express 서버가 파일 업로드를 처리하는 폴더는 Docker의 Volume을 활용하도록 구현해 주세요. +- [x] 데이터베이스는 Postgres 이미지를 사용해 연결하도록 구현해 주세요. +- [x] 실행된 Express 서버 컨테이너는 호스트 머신에서 3000번 포트로 접근 가능하도록 구현해 주세요. + +--- + +## 멘토에게 +- CI/CD에서 사용하는 환경 변수는 github의 enviroment secret기능을 활용하여 원하는 환경에 맞게 변수를 구분하였습니다. +- CI에서 push시 테스트를 실행하는 액션에 대해 브랜치 조건이 없었기에 제 이름이 들어간 브랜치는 모두 수행되도록 작성하였습니다. +- Docker-compose.yaml에서 depend_on과 service_healthy를 추가하여 postgres가 정상적으로 동작이 확인 되었을때 백엔드 서버가 실행되도록 구현하였습니다. +- 학습을 위해 Docker-compose.yaml에서 env_file과 environment를 사용하는 방법을 구성해보았습니다. 보안을 위해서라면 env_file에 전부 넣는게 맞다는 생각이 드는데 이부분은 어떻게 생각하시는지 궁금합니다. +- CD시 docker를 활용해서 배포하는 방법이 궁금합니다. (ec2에서 docker를 설정하는 등) \ No newline at end of file From 80c83efc20e4d36486c390c65247bb500ed04a93 Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 17:29:37 +0900 Subject: [PATCH 10/13] docs(README.md): Update sprint11 info --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 0974674..5127497 100644 --- a/README.md +++ b/README.md @@ -313,6 +313,11 @@ --- # 스프린트 미션 11 +## 미션 목표 + +- Github Actions로 테스트, 배포 자동화 +- Docker 이미지 만들기 + ## ✅ 요구사항 ### Github Actions 활용 @@ -323,6 +328,7 @@ ### Docker 이미지 만들기 +다음을 만족하는 Dockerfile과 docker-compose.yaml을 작성해 주세요. - [x] Express 서버를 실행하는 Dockerfile을 작성해 주세요. - [x] Express 서버가 파일 업로드를 처리하는 폴더는 Docker의 Volume을 활용하도록 구현해 주세요. - [x] 데이터베이스는 Postgres 이미지를 사용해 연결하도록 구현해 주세요. From 60becbcf3d3c0ac0511e16f634493f7cc556f6b9 Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 17:34:58 +0900 Subject: [PATCH 11/13] feat(ci/cd): Add pr branch on ci --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4ec4d0..120446a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: push: branches: [천수-*] pull_request: - branches: [main] + branches: [main, 천수] jobs: test: From 818ddeafa5ea28c576b680129a229b61f1eacef0 Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 17:43:47 +0900 Subject: [PATCH 12/13] refactor(ci/cd): Change secret to hardcode on ci --- .github/workflows/ci.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 120446a..98a9c43 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,20 +9,18 @@ on: jobs: test: runs-on: ubuntu-latest - # 테스트용 환경 변수 설정 - environment: TEST env: - DATABASE_URL: ${{ secrets.DATABASE_URL }} - JWT_SECRET: ${{ secrets.JWT_SECRET }} - PORT: ${{ secrets.PORT }} + DATABASE_URL: postgresql://postgres:test_password@localhost:5432/test_db?schema=public + JWT_SECRET: test_secret + PORT: 3000 NODE_ENV: develop #production만 아니면 로직은 동일 services: postgres: image: postgres env: - POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }} - POSTGRES_DB: ${{ secrets.DB_NAME }} + POSTGRES_PASSWORD: test_password + POSTGRES_DB: test_db options: >- --health-cmd pg_isready --health-interval 10s From 30bdc0cfa1af786744ffe5b123a7cf7eee7a87bc Mon Sep 17 00:00:00 2001 From: Seracine Date: Thu, 16 Oct 2025 17:48:50 +0900 Subject: [PATCH 13/13] refactor(ci/cd): Remove ci on push condition --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 98a9c43..438365d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,6 @@ name: ci on: - push: - branches: [천수-*] pull_request: branches: [main, 천수]