From 109362618fff995a50b3680d3208650c2b384a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AA=85=EC=A4=80?= <86913355+mjj111@users.noreply.github.com> Date: Mon, 20 Jan 2025 00:17:36 +0900 Subject: [PATCH] =?UTF-8?q?[IDLE-518]=20=EC=84=9C=EB=B2=84=20=EC=9E=AC?= =?UTF-8?q?=EA=B5=AC=EC=B6=95=20=EB=B0=8F=20CI/CD=20=EC=9E=AC=EA=B0=80?= =?UTF-8?q?=EB=8F=99=20(#258)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [IDLE-518] bastion서버를 통해 production 서버로 접근 후, 배포하도록 설정 * [IDLE-518] ECR 레파지토리 변경 * [IDLE-518] docker-compose 파일 경로 변경 * [IDLE-518] 소스파일 경로 변경 * [IDLE-518] target 경로 변경 * [IDLE-518] 소스파일 경로 변경 * [IDLE-518] 타겟파일 경로 원상복구 * [IDLE-518] 타겟파일 경로 수정 * [IDLE-518] compose 파일 실행 경로 수정 * [IDLE-518] 하드코딩된 변수를 secrets로 변경 * [IDLE-518] 하드코딩된 변수를 secrets로 변경 * [IDLE-518] 하드코딩된 변수를 secrets로 변경 * [IDLE-518] Configuration Env file 스탭 추가 * [IDLE-518] secrets로 변경 * [IDLE-518] CI/CD 재가동 전 수동으로 수정 * [IDLE-518] CI/CD 재가동 전 수동으로 수정 * [IDLE-518] ECR 레파지토리 작성 * [IDLE-518] .env 파일 경로 변경 * [IDLE-518] 레지스트리 내용 변경 * [IDLE-518] DB 이름을 caremeet으로 변경 * [IDLE-518] 서비스 간 통신을 위한 컨테이너간 네트워크 설정 추가 * [IDLE-518] ddl create 적용 * [IDLE-518] private_key.pem 파일을 통해 접근하도록 수정 * [IDLE-518] 호스트키 체크 우회 수정 * [IDLE-518] SSH 세션에 터미널을 할당하도록 옵션 추가 * [IDLE-518] 터널링 방법을 수정 * [IDLE-518] Private Subnet에 존재하는 서버의 22번 포트를 로컬 2222 포트로 연결 * [IDLE-518] .env파일 생성하는 명령어 수정 * [IDLE-518] 들여쓰기 수정 * [IDLE-518] INPUT_으로 시작하는 항목, .env 파일에 제외 * [IDLE-518] null 값을 제외하는 처리를 추가 * [IDLE-518] 병합 전에 null 값을 제외하는 처리를 추가 * [IDLE-518] context 출력문 추가 * [IDLE-518] JSON 형식으로 변환한 후, SSH 스크립트 내부에서 이를 파일로 저장 * [IDLE-518] .env 파일에 INSTANCE_PEM_KEY가 들어가지 않도록 수정 * [IDLE-518] ddl을 validate으로 수정 * [IDLE-518] 브랜치 push시에 동작하도록 수정 --- .github/workflows/dev-server-deployer.yaml | 4 +- .github/workflows/prod-server-deployer.yaml | 74 ++++++++++++++----- .../src/main/resources/application-domain.yml | 5 +- idle-presentation/compose-dev.yaml | 21 +++++- 4 files changed, 79 insertions(+), 25 deletions(-) diff --git a/.github/workflows/dev-server-deployer.yaml b/.github/workflows/dev-server-deployer.yaml index 679cfeee..1250645d 100644 --- a/.github/workflows/dev-server-deployer.yaml +++ b/.github/workflows/dev-server-deployer.yaml @@ -86,9 +86,9 @@ jobs: key: ${{ secrets.INSTANCE_PEM_KEY }} envs: VARS_CONTEXT,SECRETS_CONTEXT script: | - cd ~/app/docker + cd ~/app/docker/idle-presentation jq -s '.[0] * .[1]' <(echo "$VARS_CONTEXT") <(echo "$SECRETS_CONTEXT") \ - | jq -r 'to_entries | map("\(.key)=\(.value)") | .[]' > .env + | jq -r 'to_entries | map(select(.key != "INSTANCE_PEM_KEY")) | map("\(.key)=\(.value)") | .[]' > .env - name: Run Docker Compose up uses: appleboy/ssh-action@master diff --git a/.github/workflows/prod-server-deployer.yaml b/.github/workflows/prod-server-deployer.yaml index c242ca3c..6c9880f8 100644 --- a/.github/workflows/prod-server-deployer.yaml +++ b/.github/workflows/prod-server-deployer.yaml @@ -1,6 +1,9 @@ name: Production Server Deployer (CD) -on: workflow_dispatch +on: + push: + branches: + - main jobs: deploy: runs-on: ubuntu-latest @@ -50,7 +53,13 @@ jobs: username: ${{ vars.BASTION_USERNAME }} key: ${{ secrets.INSTANCE_PEM_KEY }} script: | - ssh -o "ProxyJump=${{ vars.BASTION_HOST }}" -i ${{ secrets.INSTANCE_PEM_KEY }} ${{ vars.INSTANCE_USERNAME }}@${{ vars.INSTANCE_HOST }} << 'EOF' + if [ ! -f private_key.pem ]; then + echo "${{ secrets.INSTANCE_PEM_KEY }}" > private_key.pem + chmod 600 private_key.pem + fi + ssh -f -N -M -S my-cicd-socket -o StrictHostKeyChecking=no -i private_key.pem -L 2222:${{ vars.INSTANCE_HOST }}:22 ec2-user@${{ vars.BASTION_HOST }} + ssh -o StrictHostKeyChecking=no -i private_key.pem -p 2222 ubuntu@localhost << 'EOF' + echo "Connected to Private Subnet productionServer via SSH Tunneling" if ! command -v docker >/dev/null 2>&1; then echo "Installing Docker..." sudo apt-get update @@ -66,23 +75,42 @@ jobs: echo "Docker Compose already installed." fi EOF + ssh -S my-cicd-socket -O exit ec2-user@${{ vars.BASTION_HOST }} + rm -f private_key.pem - name: Configuration Env file uses: appleboy/ssh-action@master - env: - VARS_CONTEXT: ${{ toJson(vars) }} - SECRETS_CONTEXT: ${{ toJson(secrets) }} with: host: ${{ vars.BASTION_HOST }} username: ${{ vars.BASTION_USERNAME }} key: ${{ secrets.INSTANCE_PEM_KEY }} - envs: VARS_CONTEXT,SECRETS_CONTEXT script: | - ssh -o "ProxyJump=${{ vars.BASTION_HOST }}" -i ${{ secrets.INSTANCE_PEM_KEY }} ${{ vars.INSTANCE_USERNAME }}@${{ vars.INSTANCE_HOST }} << 'EOF' - cd ~/app/docker - jq -s '.[0] * .[1] | del(.INSTANCE_PEM_KEY)' <(echo "$VARS_CONTEXT") <(echo "$SECRETS_CONTEXT") \ - | jq -r 'to_entries | map("\(.key)=\(.value)") | .[]' > .env + if [ ! -f private_key.pem ]; then + echo "${{ secrets.INSTANCE_PEM_KEY }}" > private_key.pem + chmod 600 private_key.pem + fi + ssh -f -N -M -S my-cicd-socket -o StrictHostKeyChecking=no -i private_key.pem -L 2222:${{ vars.INSTANCE_HOST }}:22 ec2-user@${{ vars.BASTION_HOST }} + ssh -o StrictHostKeyChecking=no -i private_key.pem -p 2222 ubuntu@localhost << 'EOF' + echo "Connected to Private Subnet productionServer via SSH Tunneling" + cd ~/app/docker + + echo "VARS_CONTEXT: ${{ toJson(vars) }}" + echo "SECRETS_CONTEXT: ${{ toJson(secrets) }}" + + VARS_CONTEXT_JSON='${{ toJson(vars) }}' + SECRETS_CONTEXT_JSON='${{ toJson(secrets) }}' + + echo "$VARS_CONTEXT_JSON" > vars_context.json + echo "$SECRETS_CONTEXT_JSON" > secrets_context.json + + jq -s '.[0] * .[1]' vars_context.json secrets_context.json \ + | jq -r 'to_entries | map(select(.key != "INSTANCE_PEM_KEY")) | map("\(.key)=\(.value)") | .[]' > .env + + echo ".env file generated:" + cat .env EOF + ssh -S my-cicd-socket -O exit ec2-user@${{ vars.BASTION_HOST }} + rm -f private_key.pem - name: SSH to Bastion and deploy to Production server uses: appleboy/ssh-action@master @@ -91,17 +119,25 @@ jobs: username: ${{ vars.BASTION_USERNAME }} key: ${{ secrets.INSTANCE_PEM_KEY }} script: | - ssh -o "ProxyJump=${{ vars.BASTION_HOST }}" -i ${{ secrets.INSTANCE_PEM_KEY }} ${{ vars.INSTANCE_USERNAME }}@${{ vars.INSTANCE_HOST }} << 'EOF' - sudo docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }} - sudo docker pull public.ecr.aws/f5q3r6m5/caremeet:latest - if [ $(sudo docker ps -q -f name=caremeet_server_prod) ]; then - sudo docker stop caremeet_server_prod - sudo docker rm caremeet_server_prod + if [ ! -f private_key.pem ]; then + echo "${{ secrets.INSTANCE_PEM_KEY }}" > private_key.pem + chmod 600 private_key.pem fi - sudo docker run --name caremeet_server_prod --env-file ./app/docker/.env \ - -e SPRING_PROFILES_ACTIVE=prod \ - -d -p 8080:8080 public.ecr.aws/f5q3r6m5/caremeet:latest + ssh -f -N -M -S my-cicd-socket -o StrictHostKeyChecking=no -i private_key.pem -L 2222:${{ vars.INSTANCE_HOST }}:22 ec2-user@${{ vars.BASTION_HOST }} + ssh -o StrictHostKeyChecking=no -i private_key.pem -p 2222 ubuntu@localhost << 'EOF' + echo "Connected to Private Subnet productionServer via SSH Tunneling" + sudo docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }} + sudo docker pull public.ecr.aws/e4z1s9l7/caremeet:latest + if [ $(sudo docker ps -q -f name=caremeet_server_prod) ]; then + sudo docker stop caremeet_server_prod + sudo docker rm caremeet_server_prod + fi + sudo docker run --name caremeet_server_prod --env-file ./app/docker/.env \ + -e SPRING_PROFILES_ACTIVE=prod \ + -d -p 8080:8080 public.ecr.aws/e4z1s9l7/caremeet:latest EOF + ssh -S my-cicd-socket -O exit ec2-user@${{ vars.BASTION_HOST }} + rm -f private_key.pem - name: Remove GitHub Actions IP run: | diff --git a/idle-domain/src/main/resources/application-domain.yml b/idle-domain/src/main/resources/application-domain.yml index 9f8c6dc5..47fbf36f 100644 --- a/idle-domain/src/main/resources/application-domain.yml +++ b/idle-domain/src/main/resources/application-domain.yml @@ -1,7 +1,8 @@ + spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver - url: ${DB_URL:jdbc:mysql://localhost:3306/idle?serverTimezone=Asia/Seoul&characterEncoding=UTF-8} + url: ${DB_URL:jdbc:mysql://localhost:3306/caremeet?serverTimezone=Asia/Seoul&characterEncoding=UTF-8} username: ${DB_USERNAME:root} password: ${DB_PASSWORD:mysql} jpa: @@ -9,6 +10,8 @@ spring: properties: hibernate.format_sql: true dialect: org.hibernate.dialect.MySQLDialect + hibernate: + ddl-auto: validate data: redis: host: ${REDIS_HOST:localhost} diff --git a/idle-presentation/compose-dev.yaml b/idle-presentation/compose-dev.yaml index 4cb5bb9d..c3ce62df 100644 --- a/idle-presentation/compose-dev.yaml +++ b/idle-presentation/compose-dev.yaml @@ -10,19 +10,26 @@ services: pull_policy: always env_file: - .env - depends_on: - - mysql ports: - "8080:8080" + depends_on: + - mysql + - redis + networks: + - redis-caremeet-net + - mysql-caremeet-net mysql: image: mysql:8.0.33 + container_name: mysql_dev environment: - MYSQL_DATABASE: idle + MYSQL_DATABASE: caremeet MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} TZ: Asia/Seoul ports: - "3306:3306" + networks: + - mysql-caremeet-net redis: image: redis:7.2.5 @@ -35,6 +42,14 @@ services: volumes: - redis-volume:/data restart: unless-stopped + networks: + - redis-caremeet-net + +networks: + mysql-caremeet-net: + driver: bridge + redis-caremeet-net: + driver: bridge volumes: mysql-volume: