Skip to content

Commit

Permalink
[#75] feat: 운영환경 분리
Browse files Browse the repository at this point in the history
  • Loading branch information
NaMinhyeok committed Feb 18, 2025
1 parent 1a126dc commit 9b0392f
Show file tree
Hide file tree
Showing 9 changed files with 420 additions and 100 deletions.
44 changes: 25 additions & 19 deletions .github/workflows/cd.yml → .github/workflows/cd-dev.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
name: CD Pipeline
name: CD Dev Pipeline

on:
push:
branches:
- main
- dev
- feature/**

env:
NCP_ACCESS_KEY: ${{ secrets.NCP_ACCESS_KEY }}
NCP_SECRET_KEY: ${{ secrets.NCP_SECRET_KEY }}
NCP_API_URL: https://ncloud.apigw.ntruss.com
NCP_VPC_ID: ${{ secrets.NCP_VPC_ID }}
NCP_AGC_ID: ${{ secrets.NCP_AGC_ID }}
SERVICE_NAME: jaknaeso
SERVICE_NAME: jaknaeso-dev
REGISTRY_URL: ${{ secrets.NCP_CONTAINER_REGISTRY_URL }}
NCP_SERVER_HOST: ${{ secrets.NCP_SERVER_HOST }}
NCP_SERVER_USERNAME: ${{ secrets.NCP_SERVER_USERNAME }}
Expand Down Expand Up @@ -56,8 +57,8 @@ jobs:
tags: |
${{ env.REGISTRY_URL }}/${{ env.SERVICE_NAME }}:${{ env.BUILD_NUMBER }}
${{ env.REGISTRY_URL }}/${{ env.SERVICE_NAME }}:latest
cache-from: type=registry,ref=${{ env.REGISTRY_URL }}/${{ env.SERVICE_NAME}}:buildcache,image-manifest=true,oci-mediatypes=true
cache-to: type=registry,ref=${{ env.REGISTRY_URL }}/${{ env.SERVICE_NAME}}:buildcache,mode=max,image-manifest=true,oci-mediatypes=true
cache-from: type=registry,ref=${{ env.REGISTRY_URL }}/${{ env.SERVICE_NAME}}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY_URL }}/${{ env.SERVICE_NAME}}:buildcache

- name: Setting NCP CLI & Credentials
run: |
Expand All @@ -78,16 +79,19 @@ jobs:
- name: Create .env file
run: |
echo "DATABASE_NAME=${{ secrets.DATABASE_NAME }}" >> .env
echo "DATABASE_USER=${{ secrets.DATABASE_USER }}" >> .env
echo "DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}" >> .env
echo "DATABASE_ROOT_PASSWORD=${{ secrets.DATABASE_ROOT_PASSWORD }}" >> .env
echo "JWT_SECRET=${{ secrets.JWT_SECRET }}" >> .env
echo "ACCESS_TOKEN_EXPIRATION=${{ env.ACCESS_TOKEN_EXPIRATION }}" >> .env
echo "REFRESH_TOKEN_EXPIRATION=${{ env.REFRESH_TOKEN_EXPIRATION }}" >> .env
echo "KAKAO_LOGIN_CLIENT_ID=${{ secrets.KAKAO_LOGIN_CLIENT_ID }}" >> .env
echo "KAKAO_LOGIN_CLIENT_SECRET=${{ secrets.KAKAO_LOGIN_CLIENT_SECRET }}" >> .env
echo "SPRING_PROFILES_ACTIVE=${{ env.SPRING_PROFILES_ACTIVE }}" >> .env
echo "DATABASE_NAME=${{ secrets.DATABASE_NAME }}" >> .env.dev
echo "DATABASE_USER=${{ secrets.DATABASE_USER }}" >> .env.dev
echo "DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}" >> .env.dev
echo "DATABASE_ROOT_PASSWORD=${{ secrets.DATABASE_ROOT_PASSWORD }}" >> .env.dev
echo "JWT_SECRET=${{ secrets.JWT_SECRET }}" >> .env.dev
echo "ACCESS_TOKEN_EXPIRATION=${{ env.ACCESS_TOKEN_EXPIRATION }}" >> .env.dev
echo "REFRESH_TOKEN_EXPIRATION=${{ env.REFRESH_TOKEN_EXPIRATION }}" >> .env.dev
echo "KAKAO_LOGIN_CLIENT_ID=${{ secrets.KAKAO_LOGIN_CLIENT_ID }}" >> .env.dev
echo "KAKAO_LOGIN_CLIENT_SECRET=${{ secrets.KAKAO_LOGIN_CLIENT_SECRET }}" >> .env.dev
echo "SPRING_PROFILES_ACTIVE=${{ env.SPRING_PROFILES_ACTIVE }}" >> .env.dev
echo "BUILD_NUMBER=${{ env.BUILD_NUMBER }}" >> .env.dev
echo "REGISTRY_URL=${{ env.REGISTRY_URL }}" >> .env.dev
echo "SERVICE_NAME=${{ env.SERVICE_NAME }}" >> .env.dev
- name: Transfer files to Server
uses: appleboy/scp-action@master
Expand All @@ -96,7 +100,7 @@ jobs:
username: ${{ env.NCP_SERVER_USERNAME }}
password: ${{ env.NCP_SERVER_PASSWORD }}
port: ${{ env.SSH_PORT }}
source: "docker-compose.yml,.env,nginx/default.conf,scripts/server/*"
source: "docker-compose.dev.yml,docker-compose.nginx.yml,.env.dev,nginx/default.conf,scripts/server/*"
target: "~/"
overwrite: true

Expand All @@ -110,9 +114,11 @@ jobs:
script: |
docker login ${{ env.REGISTRY_URL }} -u ${{ env.NCP_ACCESS_KEY }} -p ${{ env.NCP_SECRET_KEY }}
docker-compose -f ~/docker-compose.yml pull
docker-compose -f ~/docker-compose.yml up -d --remove-orphans
docker-compose exec nginx nginx -s reload
docker-compose --env-file .env.dev -f ~/docker-compose.dev.yml pull
docker-compose -f ~/docker-compose.nginx.yml pull
docker-compose --env-file .env.dev -f ~/docker-compose.dev.yml up -d
docker-compose -f ~/docker-compose.nginx.yml up -d
docker-compose -f ~/docker-compose.nginx.yml exec nginx nginx -s reload
chmod +x ~/scripts/server/register-certbot-cron-job.sh
~/scripts/server/register-certbot-cron-job.sh
Expand Down
134 changes: 134 additions & 0 deletions .github/workflows/cd-prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
name: CD Prod Pipeline

on:
push:
branches:
- main
- feature/**

env:
NCP_ACCESS_KEY: ${{ secrets.NCP_ACCESS_KEY }}
NCP_SECRET_KEY: ${{ secrets.NCP_SECRET_KEY }}
NCP_API_URL: https://ncloud.apigw.ntruss.com
NCP_VPC_ID: ${{ secrets.NCP_VPC_ID }}
NCP_AGC_ID: ${{ secrets.NCP_AGC_ID }}
SERVICE_NAME: jaknaeso
REGISTRY_URL: ${{ secrets.NCP_CONTAINER_REGISTRY_URL }}
NCP_SERVER_HOST: ${{ secrets.NCP_SERVER_HOST }}
NCP_SERVER_USERNAME: ${{ secrets.NCP_SERVER_USERNAME }}
NCP_SERVER_PASSWORD: ${{ secrets.NCP_SERVER_PASSWORD }}
ACCESS_TOKEN_EXPIRATION: ${{ secrets.ACCESS_TOKEN_EXPIRATION }}
REFRESH_TOKEN_EXPIRATION: ${{ secrets.REFRESH_TOKEN_EXPIRATION }}
SSH_PORT: 22
BUILD_NUMBER: ${{ github.sha }}-${{ github.run_id }}
SPRING_PROFILES_ACTIVE: prod

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Get Github Actions IP
id: ip
run: |
PUBLIC_IP=$(curl -s https://ifconfig.me)
echo "PUBLIC_IP=$PUBLIC_IP" >> $GITHUB_ENV
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to NCP Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY_URL }}
username: ${{ env.NCP_ACCESS_KEY }}
password: ${{ env.NCP_SECRET_KEY }}

- name: Build and Push Docker Image
uses: docker/build-push-action@v6
with:
context: .
file: ./jaknaeso-server/Dockerfile
push: true
platforms: linux/amd64
tags: |
${{ env.REGISTRY_URL }}/${{ env.SERVICE_NAME }}:${{ env.BUILD_NUMBER }}
${{ env.REGISTRY_URL }}/${{ env.SERVICE_NAME }}:latest
cache-from: type=registry,ref=${{ env.REGISTRY_URL }}/${{ env.SERVICE_NAME}}:buildcache
cache-to: type=registry,ref=${{ env.REGISTRY_URL }}/${{ env.SERVICE_NAME}}:buildcache

- name: Setting NCP CLI & Credentials
run: |
cd ~
wget https://www.ncloud.com/api/support/download/5/65
unzip 65
mkdir ~/.ncloud
echo -e "[DEFAULT]\nncloud_access_key_id = ${{ env.NCP_ACCESS_KEY }}\nncloud_secret_access_key = ${{ env.NCP_SECRET_KEY }}\nncloud_api_url = ${{ env.NCP_API_URL }}" >> ~/.ncloud/configure
- name: Add Github Action Ip to Security group
run: |
chmod -R 777 ~/cli_linux
cd ~/cli_linux
./ncloud vserver addAccessControlGroupInboundRule \
--regionCode KR --vpcNo ${{ env.NCP_VPC_ID }} \
--accessControlGroupNo ${{ env.NCP_AGC_ID }} \
--accessControlGroupRuleList "protocolTypeCode='TCP', ipBlock='${{ env.PUBLIC_IP }}/32', portRange='22'" > /dev/null 2>&1
- name: Create .env file
run: |
echo "DATABASE_NAME=${{ secrets.DATABASE_NAME }}" >> .env.prod
echo "DATABASE_USER=${{ secrets.DATABASE_USER }}" >> .env.prod
echo "DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}" >> .env.prod
echo "DATABASE_ROOT_PASSWORD=${{ secrets.DATABASE_ROOT_PASSWORD }}" >> .env.prod
echo "JWT_SECRET=${{ secrets.JWT_SECRET }}" >> .env.prod
echo "ACCESS_TOKEN_EXPIRATION=${{ env.ACCESS_TOKEN_EXPIRATION }}" >> .env.prod
echo "REFRESH_TOKEN_EXPIRATION=${{ env.REFRESH_TOKEN_EXPIRATION }}" >> .env.prod
echo "KAKAO_LOGIN_CLIENT_ID=${{ secrets.KAKAO_LOGIN_CLIENT_ID }}" >> .env.prod
echo "KAKAO_LOGIN_CLIENT_SECRET=${{ secrets.KAKAO_LOGIN_CLIENT_SECRET }}" >> .env.prod
echo "SPRING_PROFILES_ACTIVE=${{ env.SPRING_PROFILES_ACTIVE }}" >> .env.prod
echo "BUILD_NUMBER=${{ env.BUILD_NUMBER }}" >> .env.prod
echo "REGISTRY_URL=${{ env.REGISTRY_URL }}" >> .env.prod
echo "SERVICE_NAME=${{ env.SERVICE_NAME }}" >> .env.prod
- name: Transfer files to Server
uses: appleboy/scp-action@master
with:
host: ${{ env.NCP_SERVER_HOST}}
username: ${{ env.NCP_SERVER_USERNAME }}
password: ${{ env.NCP_SERVER_PASSWORD }}
port: ${{ env.SSH_PORT }}
source: "docker-compose.prod.yml,docker-compose.nginx.yml,.env.prod,nginx/default.conf,scripts/server/*"
target: "~/"
overwrite: true

- name: Deploy to Server
uses: appleboy/ssh-action@master
with:
host: ${{ env.NCP_SERVER_HOST }}
username: ${{ env.NCP_SERVER_USERNAME }}
password: ${{ env.NCP_SERVER_PASSWORD }}
port: ${{ env.SSH_PORT }}
script: |
docker login ${{ env.REGISTRY_URL }} -u ${{ env.NCP_ACCESS_KEY }} -p ${{ env.NCP_SECRET_KEY }}
docker-compose --env-file .env.prod -f ~/docker-compose.prod.yml pull
docker-compose -f ~/docker-compose.nginx.yml pull
docker-compose --env-file .env.prod -f ~/docker-compose.prod.yml up -d
docker-compose -f ~/docker-compose.nginx.yml up -d
docker-compose -f ~/docker-compose.nginx.yml exec nginx nginx -s reload
chmod +x ~/scripts/server/register-certbot-cron-job.sh
~/scripts/server/register-certbot-cron-job.sh
- name: Remove Github Action Ip from Security group
if: always()
run: |
chmod -R 777 ~/cli_linux
cd ~/cli_linux
./ncloud vserver removeAccessControlGroupInboundRule \
--regionCode KR --vpcNo ${{ env.NCP_VPC_ID }} \
--accessControlGroupNo ${{ env.NCP_AGC_ID }} \
--accessControlGroupRuleList "protocolTypeCode='TCP', ipBlock='${{ env.PUBLIC_IP }}/32', portRange='22'" > /dev/null 2>&1
51 changes: 51 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
services:
dev-mysql:
image: mysql:8.0
container_name: jaknaeso-dev-mysql
env_file:
- .env.dev
ports:
- "3306:3306"
environment:
MYSQL_DATABASE: ${DATABASE_NAME}
MYSQL_USER: ${DATABASE_USER}
MYSQL_PASSWORD: ${DATABASE_PASSWORD}
MYSQL_ROOT_PASSWORD: ${DATABASE_ROOT_PASSWORD}
volumes:
- ./dev/mysql-data:/var/lib/mysql
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-time-zone=Asia/Seoul

networks:
- jaknaeso-dev-network
restart: on-failure

dev-server:
image: ${REGISTRY_URL}/${SERVICE_NAME}:${BUILD_NUMBER}
container_name: jaknaeso-dev-server
env_file:
- .env.dev
expose:
- "8080"
environment:
DATABASE_HOST: dev-mysql
DATABASE_NAME: ${DATABASE_NAME}
DATABASE_USER: ${DATABASE_USER}
DATABASE_PASSWORD: ${DATABASE_PASSWORD}
JWT_SECRET: ${JWT_SECRET}
ACCESS_TOKEN_EXPIRATION: ${ACCESS_TOKEN_EXPIRATION}
REFRESH_TOKEN_EXPIRATION: ${REFRESH_TOKEN_EXPIRATION}
KAKAO_LOGIN_CLIENT_ID: ${KAKAO_LOGIN_CLIENT_ID}
KAKAO_LOGIN_CLIENT_SECRET: ${KAKAO_LOGIN_CLIENT_SECRET}
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE}
TZ: Asia/Seoul
volumes:
- /var/log/jaknaeso/dev:/var/log/jaknaeso
depends_on:
- dev-mysql
networks:
- jaknaeso-dev-network
restart: on-failure

networks:
jaknaeso-dev-network:
driver: bridge
40 changes: 40 additions & 0 deletions docker-compose.nginx.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
version: "3.8"

services:
nginx:
image: nginx:latest
container_name: jaknaeso-nginx
ports:
- "80:80"
- "443:443"
volumes:
- /var/log/nginx:/var/log/nginx
- ~/nginx/default.conf:/etc/nginx/conf.d/default.conf
- /etc/letsencrypt:/etc/letsencrypt
- /var/www/certbot:/var/www/certbot
networks:
- nginx-network
- jaknaeso-dev-network
- jaknaeso-prod-network
restart: always

certbot:
image: certbot/certbot:latest
container_name: jaknaeso-certbot
depends_on:
- nginx
volumes:
- /etc/letsencrypt:/etc/letsencrypt
- /var/www/certbot:/var/www/certbot
command: "certonly --webroot -w /var/www/certbot --email [email protected] --agree-tos --non-interactive -d dev.jaknaeso.kro.kr -d prod.jaknaeso.kro.kr"
networks:
- nginx-network

networks:
nginx-network:
name: nginx-network
driver: bridge
jaknaeso-dev-network:
driver: bridge
jaknaeso-prod-network:
driver: bridge
52 changes: 52 additions & 0 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
services:
prod-mysql:
image: mysql:8.0
container_name: jaknaeso-prod-mysql
env_file:
- .env.prod
ports:
- "3307:3306"
environment:
MYSQL_DATABASE: ${DATABASE_NAME}
MYSQL_USER: ${DATABASE_USER}
MYSQL_PASSWORD: ${DATABASE_PASSWORD}
MYSQL_ROOT_PASSWORD: ${DATABASE_ROOT_PASSWORD}
volumes:
- ./prod/mysql-data:/var/lib/mysql
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --default-time-zone=Asia/Seoul

networks:
- jaknaeso-prod-network
restart: on-failure

prod-server:
image: ${REGISTRY_URL}/${SERVICE_NAME}:${BUILD_NUMBER}
container_name: jaknaeso-prod-server
env_file:
- .env.prod
expose:
- "8081"
environment:
DATABASE_HOST: prod-mysql
DATABASE_NAME: ${DATABASE_NAME}
DATABASE_USER: ${DATABASE_USER}
DATABASE_PASSWORD: ${DATABASE_PASSWORD}
JWT_SECRET: ${JWT_SECRET}
ACCESS_TOKEN_EXPIRATION: ${ACCESS_TOKEN_EXPIRATION}
REFRESH_TOKEN_EXPIRATION: ${REFRESH_TOKEN_EXPIRATION}
KAKAO_LOGIN_CLIENT_ID: ${KAKAO_LOGIN_CLIENT_ID}
KAKAO_LOGIN_CLIENT_SECRET: ${KAKAO_LOGIN_CLIENT_SECRET}
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE}
TZ: Asia/Seoul
volumes:
- /var/log/jaknaeso/prod:/var/log/jaknaeso
depends_on:
- prod-mysql
networks:
- jaknaeso-prod-network
restart: on-failure

networks:
jaknaeso-prod-network:
driver: bridge

Loading

0 comments on commit 9b0392f

Please sign in to comment.