forked from banhogu/Moaguide-Project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'Moaguide-develop:main' into main
- Loading branch information
Showing
187 changed files
with
4,989 additions
and
2,005 deletions.
There are no files selected for viewing
This file contains 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,100 @@ | ||
name: AWS CD | ||
|
||
on: | ||
workflow_run: | ||
workflows: ['AWS CI'] | ||
types: | ||
- completed | ||
|
||
jobs: | ||
deploy: | ||
if: ${{ github.event.workflow_run.conclusion == 'success' }} | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Add SSH key | ||
run: echo "${{ secrets.EC2_SSH_KEY }}" > /tmp/ssh_key && chmod 600 /tmp/ssh_key | ||
|
||
- name: Determine deployment target | ||
id: determine-target | ||
run: | | ||
frontend_target=$(ssh -i /tmp/ssh_key -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=10 ec2-user@${{ secrets.LIVE_SERVER_IP }} "cat /home/ec2-user/frontend_target.txt || (echo 'front_green' > /home/ec2-user/frontend_target.txt && cat /home/ec2-user/frontend_target.txt)") | ||
if [ "$frontend_target" = "front_blue" ]; then | ||
new_target="front_green" | ||
else | ||
new_target="front_blue" | ||
fi | ||
echo "frontend_target=$frontend_target" >> $GITHUB_OUTPUT | ||
echo "new_target=$new_target" >> $GITHUB_OUTPUT | ||
ssh -i /tmp/ssh_key -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=10 ec2-user@${{ secrets.LIVE_SERVER_IP }} "echo '$new_target' > /home/ec2-user/frontend_target.txt" | ||
- name: Login to Docker Hub on EC2 instance | ||
run: | | ||
ssh -i /tmp/ssh_key -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=10 ec2-user@${{ secrets.LIVE_SERVER_IP }} "echo '${{ secrets.DOCKERHUB_PW }}' | docker login -u '${{ secrets.DOCKERHUB_USERNAME }}' --password-stdin" | ||
- name: Pull latest image and deploy new version | ||
run: | | ||
ssh -i /tmp/ssh_key -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=10 ec2-user@${{ secrets.LIVE_SERVER_IP }} " | ||
docker pull moaguide/moaguide:front_last | ||
cd /home/ec2-user | ||
docker-compose -f docker-compose-front.yml up -d --no-deps \${{ steps.determine-target.outputs.new_target }} | ||
" | ||
- name: Health check new environment | ||
id: health-check | ||
run: | | ||
ssh -i /tmp/ssh_key -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=10 ec2-user@${{ secrets.DOMAIN }} " | ||
health_url='' | ||
if [ "$frontend_target" = 'front_blue' ]; then | ||
health_url='http://${{ secrets.DOMAIN }}:3000' | ||
else | ||
health_url='http://${{ secrets.DOMAIN }}:3001' | ||
fi | ||
for i in {1..10}; do | ||
http_status=\$(curl -s -o /dev/null -w '%{http_code}' \$health_url) | ||
if [ \"\$http_status\" -eq \"200\" ]; then | ||
echo 'Health check passed!' | ||
exit 0 | ||
fi | ||
echo 'Waiting for healthy status...' | ||
sleep 30 | ||
done | ||
echo 'Health check failed!' | ||
exit 1 | ||
" | ||
- name: Update frontend target file on failure | ||
if: failure() | ||
run: | | ||
frontend_target=$(ssh -i /tmp/ssh_key -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=10 ec2-user@${{ secrets.LIVE_SERVER_IP }} "cat /home/ec2-user/frontend_target.txt || (echo 'front_green' > /home/ec2-user/frontend_target.txt && cat /home/ec2-user/frontend_target.txt)") | ||
if [ "$frontend_target" = "front_blue" ]; then | ||
new_target="front_green" | ||
else | ||
new_target="front_blue" | ||
fi | ||
echo "frontend_target=$frontend_target" >> $GITHUB_OUTPUT | ||
echo "new_target=$new_target" >> $GITHUB_OUTPUT | ||
ssh -i /tmp/ssh_key -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=10 ec2-user@${{ secrets.LIVE_SERVER_IP }} "echo '$new_target' > /home/ec2-user/frontend_target.txt" | ||
- name: Update NGINX configuration and reload | ||
if: success() | ||
run: | | ||
ssh -t -i /tmp/ssh_key -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=10 ec2-user@${{ secrets.LIVE_SERVER_IP }} " | ||
if [ '${{ steps.determine-target.outputs.new_target }}' = 'front_blue' ]; then | ||
sed -i 's/server front_green:3000/server front_blue:3000/' /home/ec2-user/nginx/nginx.conf | ||
else | ||
sed -i 's/server front_blue:3000/server front_green:3000/' /home/ec2-user/nginx/nginx.conf | ||
fi | ||
docker-compose -f docker-compose-back.yml exec nginx nginx -s reload | ||
" | ||
- name: Stop old environment | ||
if: success() | ||
run: | | ||
ssh -i /tmp/ssh_key -o StrictHostKeyChecking=no -o ServerAliveInterval=60 -o ServerAliveCountMax=3 -o ConnectTimeout=10 ec2-user@${{ secrets.LIVE_SERVER_IP }} " | ||
if [ '${{ steps.determine-target.outputs.new_target }}' = 'front_blue' ]; then | ||
docker-compose -f docker-compose-front.yml stop front_green | ||
else | ||
docker-compose -f docker-compose-front.yml stop front_blue | ||
fi | ||
" |
This file contains 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,40 @@ | ||
name: AWS CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
build_and_push: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v3 | ||
|
||
- name: Set up Node.js | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: '20.17.0' | ||
|
||
- name: Install dependencies | ||
run: yarn install | ||
|
||
- name: Build frontend | ||
run: yarn build | ||
|
||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v2 | ||
|
||
- name: Login to Docker Hub | ||
run: echo "${{ secrets.DOCKERHUB_PW }}" | docker login -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin | ||
|
||
- name: Build and push Docker image | ||
run: | | ||
docker build \ | ||
--build-arg NEXT_PUBLIC_MAP_KEY=${{ secrets.NEXT_PUBLIC_MAP_KEY }} \ | ||
--build-arg NEXT_PUBLIC_BACKEND_URL=${{ secrets.NEXT_PUBLIC_BACKEND_URL }} \ | ||
--build-arg NEXT_PUBLIC_GOOGLE_ANALYTICS=${{ secrets.NEXT_PUBLIC_GOOGLE_ANALYTICS }} \ | ||
-t moaguide/moaguide:front_last . | ||
docker push moaguide/moaguide:front_last |
This file contains 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,64 @@ | ||
# Multi-stage build | ||
|
||
# 1단계: 환경 설정 및 dependancy 설치 | ||
FROM node:18-alpine AS deps | ||
RUN apk add --no-cache libc6-compat | ||
|
||
# 명령어를 실행할 디렉터리 지정 | ||
WORKDIR /app | ||
|
||
# Dependancy install을 위해 package.json, package-lock.json, yarn.lock 복사 | ||
COPY package.json yarn.lock ./ | ||
|
||
# Dependancy 설치 (새로운 lock 파일 수정 또는 생성 방지) | ||
RUN yarn --frozen-lockfile | ||
|
||
########################################################### | ||
|
||
# 2단계: next.js 빌드 단계 | ||
FROM node:18-alpine AS builder | ||
|
||
# 명령어를 실행할 디렉터리 지정 | ||
WORKDIR /app | ||
|
||
# Build-time arguments | ||
ARG NEXT_PUBLIC_MAP_KEY | ||
ARG NEXT_PUBLIC_BACKEND_URL | ||
ARG NEXT_PUBLIC_GOOGLE_ANALYTICS | ||
|
||
|
||
|
||
|
||
# node_modules 등의 dependancy를 복사함. | ||
COPY --from=deps /app/node_modules ./node_modules | ||
COPY . . | ||
|
||
RUN yarn build | ||
|
||
########################################################### | ||
|
||
# 3단계: next.js 실행 단계 | ||
FROM node:18-alpine AS runner | ||
|
||
# 명령어를 실행할 디렉터리 지정 | ||
WORKDIR /app | ||
|
||
# container 환경에 시스템 사용자를 추가함 | ||
RUN addgroup --system --gid 1001 nodejs | ||
RUN adduser --system --uid 1001 nextjs | ||
|
||
# next.config.js에서 output을 standalone으로 설정하면 | ||
# 빌드에 필요한 최소한의 파일만 ./next/standalone로 출력이 된다. | ||
# standalone 결과물에는 public 폴더와 static 폴더 내용은 포함되지 않으므로, 따로 복사를 해준다. | ||
COPY --from=builder /app/public ./public | ||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ | ||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static | ||
|
||
# 컨테이너의 수신 대기 포트를 3000으로 설정 | ||
EXPOSE 3000 | ||
|
||
# node로 애플리케이션 실행 | ||
CMD ["node", "server.js"] | ||
|
||
# standalone으로 나온 결과값은 node 자체적으로만 실행 가능 | ||
# CMD ["npm", "start"] |
This file contains 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 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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.