-
Notifications
You must be signed in to change notification settings - Fork 7
[유진호] sprint11 #81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
The head ref may contain hidden characters: "\uC720\uC9C4\uD638-sprint11"
Merged
[유진호] sprint11 #81
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # Node & TypeScript | ||
| node_modules | ||
| dist | ||
| npm-debug.log | ||
| yarn-debug.log | ||
| yarn-error.log | ||
|
|
||
| # Environment | ||
| .env | ||
| .env.* | ||
| !env.example # 예시 파일 허용 | ||
|
|
||
| # Git / Actions | ||
| .git | ||
| .gitignore | ||
| .github | ||
|
|
||
| # Prisma | ||
| src/prisma/*.db | ||
| src/prisma/migrations/dev.db-journal | ||
| src/prisma/dev.db | ||
|
|
||
| # Docker | ||
| Dockerfile | ||
| docker-compose.yaml | ||
| docker-compose.prod.yaml | ||
|
|
||
| # OS / IDE | ||
| .DS_Store | ||
| .vscode | ||
| .idea | ||
| *.swp | ||
| *.swo | ||
| *.bak | ||
| Thumbs.db |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| name: CD | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
|
|
||
| jobs: | ||
| deploy: | ||
| name: Deploy to EC2 | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up SSH | ||
| uses: webfactory/ssh-agent@v0.9.0 | ||
| with: | ||
| ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} | ||
|
|
||
| - name: Deploy to EC2 | ||
| run: | | ||
| ssh -o StrictHostKeyChecking=no ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} << 'EOF' | ||
| # 작업 디렉토리로 이동 또는 생성 | ||
| mkdir -p ~/app | ||
| cd ~/app | ||
|
|
||
| # docker-compose.prod.yaml 생성 | ||
| cat > docker-compose.prod.yaml << 'YML' | ||
| version: "3.9" | ||
| services: | ||
| web: | ||
| image: ${{ secrets.IMAGE }} | ||
| env_file: | ||
| - .env.prod | ||
| ports: | ||
| - "3000:3000" | ||
| restart: unless-stopped | ||
| YML | ||
|
|
||
| # .env.prod 생성 | ||
| cat > .env.prod << 'ENV' | ||
| DATABASE_URL=${{ secrets.DATABASE_URL }} | ||
| ACCESS_TOKEN_SECRET=${{ secrets.ACCESS_TOKEN_SECRET }} | ||
| REFRESH_TOKEN_SECRET=${{ secrets.REFRESH_TOKEN_SECRET }} | ||
| BASE_URL=${{ secrets.BASE_URL }} | ||
| AWS_REGION=${{ secrets.AWS_REGION }} | ||
| AWS_S3_BUCKET=${{ secrets.AWS_S3_BUCKET }} | ||
| AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }} | ||
| AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
| NODE_ENV=production | ||
| PORT=3000 | ||
| UPLOAD_STRATEGY=s3 | ||
| ENV | ||
|
|
||
| # Docker compose 재시작 | ||
| docker compose -f docker-compose.prod.yaml pull | ||
| docker compose -f docker-compose.prod.yaml up -d | ||
| EOF |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| name: CI (PR) | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: ["**"] | ||
|
|
||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| services: | ||
| postgres: | ||
| image: postgres:16-alpine | ||
| env: | ||
| POSTGRES_DB: panda_market_test | ||
| POSTGRES_USER: app | ||
| POSTGRES_PASSWORD: app | ||
| ports: | ||
| - 5432:5432 | ||
| options: >- | ||
| --health-cmd="pg_isready -U app -d panda_market_test" | ||
| --health-interval=5s --health-timeout=3s --health-retries=10 | ||
|
|
||
| env: | ||
| NODE_ENV: test | ||
| DATABASE_URL: postgres://app:app@localhost:5432/panda_market_test | ||
| ACCESS_TOKEN_SECRET: test-access | ||
| REFRESH_TOKEN_SECRET: test-refresh | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 20 | ||
| cache: npm | ||
|
|
||
| - run: npm ci | ||
|
|
||
| - name: Prisma generate & migrate | ||
| run: | | ||
| npx prisma generate --schema=src/prisma/schema.prisma | ||
| npx prisma migrate deploy --schema=src/prisma/schema.prisma | ||
|
|
||
| - name: Test | ||
| run: CI=true npm test |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| # deps / build | ||
| FROM node:20-alpine AS deps | ||
| WORKDIR /app | ||
| COPY package*.json ./ | ||
| RUN npm ci | ||
| COPY tsconfig.json ./ | ||
| COPY src ./src | ||
| RUN npx prisma generate --schema=src/prisma/schema.prisma | ||
| RUN npm run build | ||
|
|
||
| # runtime | ||
| FROM node:20-alpine | ||
| WORKDIR /app | ||
| ENV NODE_ENV=production | ||
| ENV PORT=3000 | ||
| ENV UPLOAD_DIR=/app/uploads | ||
|
|
||
| # Prisma 및 bcrypt 등 네이티브 모듈 호환성을 위한 보강 | ||
| RUN apk add --no-cache openssl libc6-compat | ||
|
|
||
| # non-root | ||
| RUN addgroup -S app && adduser -S app -G app | ||
| RUN mkdir -p /app/uploads && chown -R app:app /app | ||
| USER app | ||
|
|
||
| COPY --from=deps /app/node_modules ./node_modules | ||
| COPY --from=deps /app/dist ./dist | ||
| COPY --from=deps /app/src/prisma ./src/prisma | ||
| COPY package*.json ./ | ||
|
|
||
| EXPOSE 3000 | ||
| # Prisma 마이그레이션 후 서버 기동 | ||
| CMD sh -c "npx prisma migrate deploy --schema=src/prisma/schema.prisma && node dist/app.js" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,50 +1,47 @@ | ||
| ## 미션 목표 | ||
| - 판다마켓 서비스를 AWS로 배포하기 | ||
| - AWS S3 적용 | ||
| - AWS RDS 적용 | ||
| - AWS EC2에 Express 서버 배포하기 | ||
| - (심화) 프로세스 매니저 적용 | ||
| - (심화) 리버스 프록시 적용 | ||
| - Github Actions로 테스트, 배포 자동화 | ||
| - Docker 이미지 만들기 | ||
|
|
||
| ## 요구사항 | ||
|
|
||
| ### 기본 요구사항 | ||
| - [x] 프로젝트에 프로덕션 배포를 위한 환경 변수 설정을 해 주세요. | ||
| ### Github Actions 활용 | ||
| - [x] 브랜치에 pull request가 발생하면 테스트를 실행하는 액션을 구현해 주세요. | ||
| - [x] `main` 브랜치에 push가 발생하면 AWS 배포를 진행하는 액션을 구현해 주세요. | ||
| - [x] 개인 Github 리포지터리에서 Actions 동작을 확인해 보세요. | ||
|
|
||
| ### AWS S3 적용 | ||
| - [x] AWS S3 버킷을 생성하고, 퍼블릭 액세스를 허용해 주세요. | ||
| - [x] 일반 사용자가 S3 업로드된 파일에 접근할 수 있도록 S3 버킷 정책을 설정해 주세요. | ||
| - [x] AWS EC2에서 AWS S3를 사용하기 위한 액세스 키를 AWS IAM에서 발급하세요. | ||
| - [x] 프로덕션 환경에서는 파일 업로드에 AWS S3를 사용하도록 구현을 수정해 주세요. | ||
| - [x] 데이터베이스는 Postgres 이미지를 사용해 연결하도록 구현해 주세요. | ||
| - [x] 실행된 Express 서버 컨테이너는 호스트 머신에서 3000번 포트로 접근 가능하도록 구현해 주세요. | ||
|
|
||
| ### AWS RDS 적용 | ||
| - [x] AWS RDS 프리티어에 해당하는 인스턴스를 생성합니다. | ||
| - [x] RDS 인스턴스에 대한 보안 그룹을 설정합니다. | ||
| - [x] 프로덕션 환경에서는 Prisma에 프로젝트 데이터베이스와 연결하도록 합니다. | ||
|
|
||
| ### AWS EC2에 Express 서버 배포하기 | ||
| - [x] AWS EC2 프리티어에 해당하는 인스턴스를 생성합니다. | ||
| - [x] SSH를 사용해 EC2 인스턴스에 접속해 Express 서버를 배포해 주세요. | ||
| ### Docker 이미지 만들기 | ||
| 다음을 만족하는 Dockerfile과 docker-compose.yaml을 작성해 주세요. | ||
|
|
||
| ### 심화 요구사항 | ||
| - [x] EC2 인스턴스에서 pm2 프로세스 매니저를 사용하여 애플리케이션을 실행해 주세요. | ||
| - [x] EC2 인스턴스에서 nginx 리버스 프록시를 설정해 서버를 80번 포트로 서비스합니다. | ||
| - [x] Express 서버를 실행하는 Dockerfile을 작성해 주세요. | ||
| - [x] Express 서버가 파일 업로드를 처리하는 폴더는 Docker의 Volume을 활용하도록 구현해 주세요. | ||
| - [x] 프로덕션 환경에서는 Prisma에 프로젝트 데이터베이스와 연결하도록 합니다. | ||
|
|
||
| --- | ||
|
|
||
| ## 멘토에게 | ||
| - AWS 프리티어 사용이 불가하여, 비용 문제로 다른 서버에 배포하였습니다. | ||
| - AWS 관련 설정은 캡쳐한 후 인스턴스 및 스토리지 삭제하는 방식으로 미션 진행하였습니다. | ||
| - 제출한 이미지 업로드 코드는 S3 기반으로 작성하였지만, 실제 배포 환경에서는 이미지 파일을 로컬 스토리지에 업로드합니다. | ||
| - 엔드포인트는 https://pandamarket.mimu.live 입니다. | ||
| - 요구사항에는 없지만, PM2 및 Nginx 환경 설정을 일부 보강하여 적용하였습니다. | ||
| - PM2 | ||
| - 프로세스 안정성을 고려하여, 메모리 300MB 초과 시에 자동 재시작하도록 설정했습니다. | ||
| 중급 프로젝트 시에 메모리 문제로 서비스가 종료된 적이 있어 추가 설정하였습니다. | ||
| - TS 기반으로 작성되었으며, 배포 환경에서 불필요한 재시작 루프를 방지하기 위해 | ||
| watch 옵션을 명시적으로 비활성화했습니다. | ||
| - Nginx | ||
| - 파일 업로드 용량 제한을 2MB로 명시적으로 설정했습니다. | ||
| - `real_ip_header CF-Connecting-IP` 및 Cloudflare IP 대역을 지정하여, | ||
| 프록시 환경에서도 실제 클라이언트 IP를 확인할 수 있도록 구성했습니다. | ||
| - 단순 IP가 아닌 실제 도메인으로 접근 가능하도록 설정하여 구현했습니다. | ||
| - 기본 요구사항은 모두 충족하였으며, 추가 구현한 내용을 아래에 기재합니다. | ||
|
|
||
| ### 헬스체크 | ||
| - `docker-compose.yaml` 내에서 Postgres 컨테이너의 상태를 `pg_isready`로 주기적으로 확인하도록 설정했습니다. | ||
| - 애플리케이션 컨테이너는 DB 서비스가 정상 상태(`healthy`)일 때만 기동되도록 의존성을 설정했습니다. | ||
|
|
||
| ### Volume 구성 강화 | ||
| - 업로드 파일을 컨테이너 외부에서도 보존할 수 있도록 `/app/uploads` 경로를 호스트와 Volume으로 연결했습니다. | ||
| - 애플리케이션 실행 시 업로드 폴더가 자동 생성되도록 Dockerfile 내에 디렉터리 생성 및 권한 설정을 추가했습니다. | ||
|
|
||
| ### Prisma 마이그레이션 자동화 | ||
| - 배포 시 Prisma 마이그레이션이 자동으로 반영되도록 Dockerfile의 CMD 단계에 `migrate deploy` 명령어를 포함했습니다. | ||
|
|
||
| ### 보안 및 권한 관리 | ||
| - 컨테이너 내에서 애플리케이션이 root 권한으로 실행되지 않도록 `USER app`을 설정했습니다. | ||
| - 이미지 빌드 시 불필요한 파일 및 비공개 설정이 포함되지 않도록 `.dockerignore`를 구성했습니다. | ||
|
|
||
| ### upload 미들웨어 | ||
| - `.env`의 실행 환경 설정에 따라 로컬 스토리지 또는 AWS S3 중 하나를 선택하여 파일 업로드를 처리하도록 수정했습니다. | ||
| - 이에 따라 `.env.example`에 `UPLOAD_STRATEGY` 항목을 추가했습니다. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| version: '3.9' | ||
|
|
||
| services: | ||
| # PostgreSQL 데이터베이스 서비스 | ||
| db: | ||
| image: postgres | ||
| restart: always | ||
| ports: | ||
| - '5432:5432' | ||
| volumes: | ||
| - db:/var/lib/postgresql/data | ||
| env_file: | ||
| - .env | ||
| healthcheck: | ||
| test: ['CMD-SHELL', 'pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB'] | ||
| interval: 5s | ||
| timeout: 3s | ||
| retries: 10 | ||
|
|
||
| # Node.js 애플리케이션 서비스 | ||
| web: | ||
| build: . | ||
| restart: always | ||
| ports: | ||
| - '3000:3000' | ||
| depends_on: | ||
| db: | ||
| condition: service_healthy | ||
| env_file: | ||
| - .env | ||
| volumes: | ||
| - ./uploads:/app/uploads | ||
|
|
||
| volumes: | ||
| db: | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bind mounts보다는 named volumes를 사용하는 것을 좀 더 권장합니다.