@@ -2,53 +2,112 @@ name: BE Deployment
22
33on :
44 push :
5- branches :
6- - main
7- paths :
8- - " server/**"
9- workflow_dispatch : # 수동 실행을 허용하는 이벤트
5+ branches : [main]
6+ paths : ["server/**"]
7+ workflow_dispatch :
8+
9+ permissions :
10+ contents : read
11+ packages : write
12+
13+ env :
14+ IMAGE_NAME : ghcr.io/boostcampwm-2024/web05-denamu/server
15+ IMAGE_TAG : sha-${{ github.sha }}
16+ SERVICE : app
17+ ENV_DIR : /var/prod_config/server
18+ ENV_FILE : /var/prod_config/server/.env.prod
19+ COMPOSE_FILE : docker-compose/docker-compose.prod.yml
1020
1121jobs :
12- deployment :
22+ build-and-push :
1323 runs-on : ubuntu-latest
1424 steps :
15- # public 서버로 ssh 접속
16- - name : ssh connection
17- 25+ - uses : actions/checkout@v4
26+
27+ - name : QEMU 멀티 아키텍쳐 에뮬레이터
28+ uses : docker/setup-qemu-action@v3
29+
30+ - name : Buildx 멀티 아키텍쳐 빌더
31+ uses : docker/setup-buildx-action@v3
32+
33+ - name : GHCR 로그인
34+ uses : docker/login-action@v3
35+ with :
36+ registry : ghcr.io
37+ username : ${{ github.actor }}
38+ password : ${{ secrets.GHCR_GITHUB_TOKEN }}
39+
40+ - name : Docker 이미지 Build 및 Push
41+ uses : docker/build-push-action@v6
42+ with :
43+ context : ./server
44+ file : ./server/docker/Dockerfile.prod
45+ push : true
46+ platforms : linux/amd64,linux/arm64
47+ tags : |
48+ ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
49+ ${{ env.IMAGE_NAME }}:latest
50+ cache-from : type=gha
51+ cache-to : type=gha,mode=max
52+
53+ deploy :
54+ runs-on : [self-hosted, prod]
55+ needs : build-and-push # Build 및 Push가 끝나면 시작
56+ steps :
57+ - name : 코드 체크아웃
58+ uses : actions/checkout@v4
59+
60+ - name : GHCR 로그인 (prod)
61+ uses : docker/login-action@v3
1862 with :
19- host : ${{ secrets.CLOUD_PUBLIC_INSTANCE_HOST }}
20- username : ${{ secrets.CLOUD_PUBLIC_INSTANCE_USERNAME }}
21- key : ${{ secrets.CLOUD_PUBLIC_INSTANCE_SSH_KEY }}
22- port : ${{ secrets.CLOUD_PUBLIC_INSTANCE_PORT }}
23- script : |
24- cd /var/web05-Denamu
25- git pull origin main
26- cd /var/web05-Denamu/server
27-
28- mkdir -p env
29- echo "PORT=${{ secrets.PRODUCT_PORT }}" > env/.env.prod
30- echo "DB_TYPE=mysql" >> env/.env.prod
31- echo "DB_DATABASE=${{ secrets.PRODUCT_DB_DATABASE }}" >> env/.env.prod
32- echo "DB_HOST=${{ secrets.PRODUCT_DB_HOST }}" >> env/.env.prod
33- echo "DB_PORT=${{ secrets.PRODUCT_DB_PORT }}" >> env/.env.prod
34- echo "DB_USERNAME=${{ secrets.PRODUCT_DB_USERNAME }}" >> env/.env.prod
35- echo "DB_PASSWORD=${{ secrets.PRODUCT_DB_PASSWORD }}" >> env/.env.prod
36- echo "REDIS_HOST=${{secrets.REDIS_HOST }}" >> env/.env.prod
37- echo "REDIS_PORT=${{secrets.REDIS_PORT}}" >> env/.env.prod
38- echo "REDIS_USERNAME=${{secrets.REDIS_USERNAME}}" >> env/.env.prod
39- echo "REDIS_PASSWORD=${{secrets.REDIS_PASSWORD}}" >> env/.env.prod
40- echo "EMAIL_USER=${{secrets.EMAIL_USER}}" >> env/.env.prod
41- echo "EMAIL_PASSWORD=${{secrets.EMAIL_PASSWORD}}" >> env/.env.prod
42- echo "JWT_ACCESS_SECRET=${{secrets.JWT_ACCESS_SECRET}}" >> env/.env.prod
43- echo "JWT_REFRESH_SECRET=${{secrets.JWT_REFRESH_SECRET}}" >> env/.env.prod
44- echo "REFRESH_TOKEN_EXPIRE=${{secrets.REFRESH_TOKEN_EXPIRE}}" >> env/.env.prod
45- echo "ACCESS_TOKEN_EXPIRE=${{secrets.ACCESS_TOKEN_EXPIRE}}" >> env/.env.prod
46- echo "GOOGLE_CLIENT_ID=${{secrets.GOOGLE_CLIENT_ID}}" >> env/.env.prod
47- echo "GOOGLE_CLIENT_SECRET=${{secrets.GOOGLE_CLIENT_SECRET}}" >> env/.env.prod
48- echo "GITHUB_CLIENT_ID=${{secrets.GIT_CLIENT_ID}}" >> env/.env.prod
49- echo "GITHUB_CLIENT_SECRET=${{secrets.GIT_CLIENT_SECRET}}" >> env/.env.prod
50-
51- cd /var/web05-Denamu
52- docker-compose -f docker-compose/docker-compose.prod.yml up --build --no-deps --force-recreate -d app
53- docker image prune -f
54- docker builder prune -f
63+ registry : ghcr.io
64+ username : ${{ github.actor }}
65+ password : ${{ secrets.GHCR_GITHUB_TOKEN }}
66+
67+ - name : 환경변수 최신화
68+ run : |
69+ sudo mkdir -p "$ENV_DIR"
70+ sudo install -m 600 /dev/null "$ENV_FILE"
71+ {
72+ echo "PORT=${{ secrets.PRODUCT_PORT }}"
73+ echo "DB_TYPE=mysql"
74+ echo "DB_DATABASE=${{ secrets.PRODUCT_DB_DATABASE }}"
75+ echo "DB_HOST=${{ secrets.PRODUCT_DB_HOST }}"
76+ echo "DB_PORT=${{ secrets.PRODUCT_DB_PORT }}"
77+ echo "DB_USERNAME=${{ secrets.PRODUCT_DB_USERNAME }}"
78+ echo "DB_PASSWORD=${{ secrets.PRODUCT_DB_PASSWORD }}"
79+ echo "REDIS_HOST=${{ secrets.REDIS_HOST }}"
80+ echo "REDIS_PORT=${{ secrets.REDIS_PORT }}"
81+ echo "REDIS_USERNAME=${{ secrets.REDIS_USERNAME }}"
82+ echo "REDIS_PASSWORD=${{ secrets.REDIS_PASSWORD }}"
83+ echo "EMAIL_USER=${{ secrets.EMAIL_USER }}"
84+ echo "EMAIL_PASSWORD=${{ secrets.EMAIL_PASSWORD }}"
85+ echo "JWT_ACCESS_SECRET=${{ secrets.JWT_ACCESS_SECRET }}"
86+ echo "JWT_REFRESH_SECRET=${{ secrets.JWT_REFRESH_SECRET }}"
87+ echo "REFRESH_TOKEN_EXPIRE=${{ secrets.REFRESH_TOKEN_EXPIRE }}"
88+ echo "ACCESS_TOKEN_EXPIRE=${{ secrets.ACCESS_TOKEN_EXPIRE }}"
89+ echo "GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}"
90+ echo "GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }}"
91+ echo "GITHUB_CLIENT_ID=${{ secrets.GIT_CLIENT_ID }}"
92+ echo "GITHUB_CLIENT_SECRET=${{ secrets.GIT_CLIENT_SECRET }}"
93+ } | sudo tee "$ENV_FILE" >/dev/null
94+
95+ # 인프라용 환경변수 파일 생성 (Redis, MySQL 등)
96+ sudo mkdir -p /var/prod_config/infra
97+ sudo install -m 600 /dev/null /var/prod_config/infra/.env.prod
98+ {
99+ echo "REDIS_USER=${{ secrets.REDIS_USERNAME }}"
100+ echo "REDIS_PASSWORD=${{ secrets.REDIS_PASSWORD }}"
101+ echo "MYSQL_ROOT_PASSWORD=${{ secrets.PRODUCT_DB_PASSWORD }}"
102+ echo "MYSQL_DATABASE=${{ secrets.PRODUCT_DB_DATABASE }}"
103+ echo "MYSQL_USER=${{ secrets.PRODUCT_DB_USERNAME }}"
104+ echo "MYSQL_PASSWORD=${{ secrets.PRODUCT_DB_PASSWORD }}"
105+ } | sudo tee /var/prod_config/infra/.env.prod >/dev/null
106+
107+ - name : Docker 이미지 Pull & 서비스 재시작
108+ run : |
109+ docker pull "${IMAGE_NAME}:${IMAGE_TAG}" || true
110+ docker pull "${IMAGE_NAME}:latest" || true
111+ docker compose -f "$COMPOSE_FILE" pull "$SERVICE"
112+ docker compose -f "$COMPOSE_FILE" up -d --no-deps --force-recreate "$SERVICE"
113+ docker image prune -f || true
0 commit comments