Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 52 additions & 50 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build Docker and Upload to S3
name: Build and Deploy GDGOC WebPage FE App

on:
push:
Expand All @@ -10,52 +10,54 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v3

- name: Create .env file
run: |
echo "DOCKER_HUB_USERNAME=${{ secrets.DOCKER_HUB_USERNAME }}" > .env
echo "NEXT_PUBLIC_GOOGLE_REDIRECT_CLIENT_ID=${{secrets.NEXT_PUBLIC_GOOGLE_REDIRECT_CLIENT_ID}}" >> .env
echo "NEXT_PUBLIC_GOOGLE_REDIRECT_URI=${{secrets.NEXT_PUBLIC_GOOGLE_REDIRECT_URI}}" >> .env

- name: Login to DockerHub (Optional)
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Build and Push Docker Image
run: |
docker build -t ${{ secrets.DOCKER_HUB_USERNAME }}/gdgoc-fe-app:latest .
docker run --rm ${{ secrets.DOCKER_HUB_USERNAME }}/gdgoc-fe-app:latest ls -la /app
docker push ${{ secrets.DOCKER_HUB_USERNAME }}/gdgoc-fe-app:latest

- name: Create Deployment Package
run: |
cp scripts/deploy.sh ./deploy.sh
zip -r deploy.zip .env docker-compose.yml deploy.sh appspec.yml \
Dockerfile package.json package-lock.json next.config.mjs \
pages public .next

- name: Configure AWS credentials
run: |
aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }}
aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws configure set region ${{ secrets.AWS_REGION }}

- name: Upload Deployment Package to S3
run: |
aws s3 cp deploy.zip s3://${{ secrets.AWS_S3_BUCKET }}/deploy.zip

- name: Trigger CodeDeploy (CLI)
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ap-northeast-2
run: |
aws deploy create-deployment \
--application-name ${{ secrets.AWS_CODEDEPLOY_APP }} \
--deployment-group-name ${{ secrets.AWS_CODEDEPLOY_GROUP }} \
--s3-location bucket=${{ secrets.S3_BUCKET }},bundleType=zip,key=deploy.zip \
--file-exists-behavior OVERWRITE
- name: Checkout Code
uses: actions/checkout@v3

- name: Create .env file
run: |
mkdir -p gdgocinha-fe
echo "DOCKER_HUB_USERNAME=${{ secrets.DOCKER_HUB_USERNAME }}" > .env
echo "NEXT_PUBLIC_GOOGLE_REDIRECT_CLIENT_ID=${{ secrets.NEXT_PUBLIC_GOOGLE_REDIRECT_CLIENT_ID }}" >> .env
echo "NEXT_PUBLIC_GOOGLE_REDIRECT_URI=${{ secrets.NEXT_PUBLIC_GOOGLE_REDIRECT_URI }}" >> .env

- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

- name: Build and Push Docker Image
run: |
docker build -t ${{ secrets.DOCKER_HUB_USERNAME }}/gdgocinha-fe:latest .
docker push ${{ secrets.DOCKER_HUB_USERNAME }}/gdgocinha-fe:latest

- name: Create Deployment Package
run: |
mkdir -p deploy-package
cp scripts/deploy.sh deploy-package/
cp docker-compose.yml deploy-package/
cp appspec.yml deploy-package/
cp .env deploy-package/
zip -r deploy-gdgocinha-fe.zip deploy-package/

- name: Configure AWS credentials
run: |
aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID }}
aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws configure set region ${{ secrets.AWS_REGION }}

- name: Upload Deployment Package to S3
run: |
aws s3 cp deploy-gdgocinha-fe.zip s3://${{ secrets.AWS_S3_BUCKET }}/gdgocinha-fe/deploy-gdgocinha-fe.zip

- name: Trigger CodeDeploy
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ap-northeast-2
run: |
aws deploy create-deployment \
--application-name ${{ secrets.AWS_CODEDEPLOY_APP }} \
--deployment-group-name ${{ secrets.AWS_CODEDEPLOY_GROUP }} \
--s3-location bucket=${{ secrets.AWS_S3_BUCKET }},bundleType=zip,key=gdgocinha-fe/deploy-gdgocinha-fe.zip \
--file-exists-behavior OVERWRITE
47 changes: 16 additions & 31 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,36 @@ FROM node:18 AS builder
WORKDIR /app

# package.json과 package-lock.json을 먼저 복사하고, npm install 실행
COPY package.json package-lock.json ./
RUN npm install

# .env 파일을 먼저 복사
COPY .env ./
COPY package*.json ./
RUN npm ci

# 이후 전체 파일 복사
# 소스 코드 복사
COPY . .

# next.config.mjs 확인
RUN cat next.config.mjs

# 빌드 실행 (output: export가 있는지 확인)
# 명시적으로 next build 명령 사용
RUN npx next build

# 빌드 결과 확인
RUN ls -la /app
RUN ls -la /app/.next || echo ".next 디렉토리가 없습니다"
RUN ls -la /app/out || echo "out 디렉토리가 없습니다"
# 빌드 실행
RUN npm run build

# 2단계: 실행 환경
FROM node:18
FROM node:18-slim

WORKDIR /app

# 프로덕션 의존성만 가져오기
# 프로덕션 의존성만 설치
COPY package*.json ./
RUN npm install --omit=dev
RUN npm ci --only=production

# .env 파일 복사
COPY .env ./

# 빌드된 결과물 가져오기
# 빌드된 결과물과 필요한 파일들 복사
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/next.config.mjs ./next.config.mjs

# 실행환경 확인
RUN ls -la /app
RUN ls -la /app/.next || echo ".next 디렉토리가 없습니다"
COPY --from=builder /app/next.config.mjs ./
COPY --from=builder /app/.env ./
Copy link

Copilot AI May 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copying the .env file into the production image may expose sensitive configuration details. Consider injecting environment variables externally rather than including the .env file in the image.

Suggested change
COPY --from=builder /app/.env ./

Copilot uses AI. Check for mistakes.

# 헬스체크를 위한 포트 노출
EXPOSE 3000

# 컨테이너 헬스체크 설정
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/ || exit 1

# Next.js 서버 시작
CMD ["npm", "run", "start"]
11 changes: 10 additions & 1 deletion appspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@ version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/gdgoc-fe-app
destination: /home/ubuntu/gdgocinha-fe
overwrite: true

hooks:
BeforeInstall:
- location: deploy.sh
timeout: 300
runas: root
AfterInstall:
- location: deploy.sh
timeout: 300
runas: root
ApplicationStart:
- location: deploy.sh
timeout: 300
runas: root
12 changes: 9 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ version: "3.8"

services:
frontend:
image: "${DOCKER_HUB_USERNAME}/gdgoc-fe-app:latest"
container_name: gdgoc-fe-app
image: "${DOCKER_HUB_USERNAME}/gdgocinha-fe:latest"
container_name: gdgocinha-fe
restart: always
ports:
- "3000:3000"
environment:
NODE_ENV: production
- NODE_ENV=production
working_dir: /app
command: "npm run start"
networks:
- gdgocinha-network

networks:
gdgocinha-network:
driver: bridge

58 changes: 43 additions & 15 deletions scripts/deploy.sh
Original file line number Diff line number Diff line change
@@ -1,35 +1,63 @@
#!/bin/bash
cd /home/ubuntu/gdgoc-fe-app

# Docker & Docker Compose가 설치되어 있는지 확인
# Set the application directory
APP_DIR="/home/ubuntu/gdgocinha-fe"

# Create application directory if it doesn't exist
mkdir -p $APP_DIR

# Move to application directory
cd $APP_DIR

# Docker & Docker Compose installation check and setup
if ! [ -x "$(command -v docker)" ]; then
echo "Docker가 설치되어 있지 않습니다. 설치 중..."
echo "Installing Docker..."
sudo apt update
sudo apt install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker
echo "Docker 설치 완료"
sudo usermod -aG docker ubuntu
echo "Docker installation completed"
fi

if ! [ -x "$(command -v docker-compose)" ]; then
echo "Docker Compose가 설치되어 있지 않습니다. 설치 중..."
echo "Installing Docker Compose..."
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
echo "Docker Compose 설치 완료"
echo "Docker Compose installation completed"
fi

# 기존 컨테이너 중지 및 삭제
docker-compose down
# Stop and remove existing containers
echo "Stopping existing containers..."
docker-compose down || true

# 사용되지 않는 컨테이너, 이미지, 네트워크, 볼륨 정리
# Clean up unused Docker resources
echo "Cleaning up Docker resources..."
docker system prune -af

# 불필요한 Docker 볼륨도 정리 (옵션)
docker volume prune -f

# 최신 이미지 가져오기
export $(grep -v '^#' .env | xargs)
docker pull ${DOCKER_HUB_USERNAME}/gdgoc-fe-app:latest
# Load environment variables
if [ -f .env ]; then
echo "Loading environment variables..."
export $(grep -v '^#' .env | xargs)
else
echo "Error: .env file not found"
exit 1
fi

# Pull latest image
echo "Pulling latest Docker image..."
docker pull ${DOCKER_HUB_USERNAME}/gdgocinha-fe:latest

# 컨테이너 실행
# Start containers
echo "Starting containers..."
docker-compose --env-file .env up -d

# Verify deployment
echo "Verifying deployment..."
if [ $(docker ps -q -f name=gdgocinha-fe | wc -l) -eq 1 ]; then
echo "Deployment successful!"
else
echo "Deployment failed!"
Comment on lines +58 to +61
Copy link

Copilot AI May 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The current container verification only counts matching containers; consider checking the container's health status (e.g., via docker inspect or using the HEALTHCHECK result) to more reliably determine a successful deployment.

Suggested change
if [ $(docker ps -q -f name=gdgocinha-fe | wc -l) -eq 1 ]; then
echo "Deployment successful!"
else
echo "Deployment failed!"
CONTAINER_ID=$(docker ps -q -f name=gdgocinha-fe)
if [ -n "$CONTAINER_ID" ]; then
HEALTH_STATUS=$(docker inspect --format='{{.State.Health.Status}}' $CONTAINER_ID 2>/dev/null)
if [ "$HEALTH_STATUS" == "healthy" ]; then
echo "Deployment successful!"
else
echo "Deployment failed: Container is not healthy (status: $HEALTH_STATUS)"
exit 1
fi
else
echo "Deployment failed: Container not found"

Copilot uses AI. Check for mistakes.
exit 1
fi