@@ -2,53 +2,95 @@ name: BE Deployment
22
33on :
44 push :
5- branches :
6- - main
7- paths :
8- - " server/**"
9- workflow_dispatch : # 수동 실행을 허용하는 이벤트
5+ branches : [main]
6+ paths : ["server/**", "docker-compose/**"]
7+ workflow_dispatch :
8+
9+ permissions :
10+ contents : read
11+ packages : write
12+
13+ env :
14+ IMAGE_NAME : ghcr.io/${{ github.repository }}/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+ - uses : docker/setup-buildx-action@v3
28+
29+ - name : GHCR 로그인
30+ uses : docker/login-action@v3
31+ with :
32+ registry : ghcr.io
33+ username : ${{ github.actor }}
34+ password : ${{ secrets.GHCR_GITHUB_TOKEN }}
35+
36+ - name : Docker 이미지 Build 및 Push
37+ uses : docker/build-push-action@v6
38+ with :
39+ context : ./server
40+ file : ./server/docker/Dockerfile.prod
41+ push : true
42+ tags : |
43+ ${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}
44+ ${{ env.IMAGE_NAME }}:latest
45+ cache-from : type=gha
46+ cache-to : type=gha,mode=max
47+
48+ deploy :
49+ runs-on : [self-hosted, prod]
50+ needs : build-and-push # Build 및 Push가 끝나면 시작
51+ steps :
52+ - name : 코드 체크아웃
53+ uses : actions/checkout@v4
54+
55+ - name : GHCR 로그인 (prod)
56+ uses : docker/login-action@v3
1857 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
58+ registry : ghcr.io
59+ username : ${{ github.actor }}
60+ password : ${{ secrets.GHCR_GITHUB_TOKEN }}
61+
62+ - name : 환경변수 최신화
63+ run : |
64+ sudo mkdir -p "$ENV_DIR"
65+ sudo install -m 600 /dev/null "$ENV_FILE"
66+ {
67+ echo "PORT=${{ secrets.PRODUCT_PORT }}"
68+ echo "DB_TYPE=mysql"
69+ echo "DB_DATABASE=${{ secrets.PRODUCT_DB_DATABASE }}"
70+ echo "DB_HOST=${{ secrets.PRODUCT_DB_HOST }}"
71+ echo "DB_PORT=${{ secrets.PRODUCT_DB_PORT }}"
72+ echo "DB_USERNAME=${{ secrets.PRODUCT_DB_USERNAME }}"
73+ echo "DB_PASSWORD=${{ secrets.PRODUCT_DB_PASSWORD }}"
74+ echo "REDIS_HOST=${{ secrets.REDIS_HOST }}"
75+ echo "REDIS_PORT=${{ secrets.REDIS_PORT }}"
76+ echo "REDIS_USERNAME=${{ secrets.REDIS_USERNAME }}"
77+ echo "REDIS_PASSWORD=${{ secrets.REDIS_PASSWORD }}"
78+ echo "EMAIL_USER=${{ secrets.EMAIL_USER }}"
79+ echo "EMAIL_PASSWORD=${{ secrets.EMAIL_PASSWORD }}"
80+ echo "JWT_ACCESS_SECRET=${{ secrets.JWT_ACCESS_SECRET }}"
81+ echo "JWT_REFRESH_SECRET=${{ secrets.JWT_REFRESH_SECRET }}"
82+ echo "REFRESH_TOKEN_EXPIRE=${{ secrets.REFRESH_TOKEN_EXPIRE }}"
83+ echo "ACCESS_TOKEN_EXPIRE=${{ secrets.ACCESS_TOKEN_EXPIRE }}"
84+ echo "GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}"
85+ echo "GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }}"
86+ echo "GITHUB_CLIENT_ID=${{ secrets.GIT_CLIENT_ID }}"
87+ echo "GITHUB_CLIENT_SECRET=${{ secrets.GIT_CLIENT_SECRET }}"
88+ } | sudo tee "$ENV_FILE" >/dev/null
89+
90+ - name : Docker 이미지 Pull & 서비스 재시작
91+ run : |
92+ docker pull "${IMAGE_NAME}:${IMAGE_TAG}" || true
93+ docker pull "${IMAGE_NAME}:latest" || true
94+ docker compose -f "$COMPOSE_FILE" pull "$SERVICE"
95+ docker compose -f "$COMPOSE_FILE" up -d --no-deps --force-recreate "$SERVICE"
96+ docker image prune -f || true
0 commit comments