From 345ea519240b36b718128cb26089c249aca479c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=82=98=EA=B2=BD?= <1030n@naver.com> Date: Mon, 15 Dec 2025 21:00:04 +0900 Subject: [PATCH 1/4] =?UTF-8?q?:rocket:=20Deploy:=20CICD=20=EA=B5=AC?= =?UTF-8?q?=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflow/cd.yml | 82 +++++++++++++++++++++++++++++++++++++++ .github/workflow/ci.yml | 59 ++++++++++++++++++++++++++++ docker/.dockerignore | 26 +++++++++++++ docker/Dockerfile | 24 ++++++++++++ docker/docker-compose.yml | 71 +++++++++++++++++++++++++++++++++ 5 files changed, 262 insertions(+) create mode 100644 .github/workflow/cd.yml create mode 100644 .github/workflow/ci.yml create mode 100644 docker/.dockerignore create mode 100644 docker/Dockerfile create mode 100644 docker/docker-compose.yml diff --git a/.github/workflow/cd.yml b/.github/workflow/cd.yml new file mode 100644 index 0000000..49ceee9 --- /dev/null +++ b/.github/workflow/cd.yml @@ -0,0 +1,82 @@ +name: CD + +on: + push: + branches: [ "main", "cicd" ] + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository (with submodules) + uses: actions/checkout@v4 + with: + token: ${{ secrets.GIT_ACTION_TOKEN }} + submodules: true + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker Hub Login + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Docker Build & Push (cache) + uses: docker/build-push-action@v6 + with: + context: . + file: ./docker/Dockerfile + push: true + tags: ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_REPO }}:latest + cache-from: type=gha + cache-to: type=gha,mode=max + + deploy: + runs-on: ubuntu-latest + needs: build + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Copy docker-compose.yml to Server + uses: appleboy/scp-action@master + with: + host: ${{ secrets.SSH_HOST }} + port: ${{ secrets.SSH_PORT }} + username: ${{ secrets.SSH_USERNAME }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + source: "docker/docker-compose.yml" + target: "~/app" + + - name: Deploy on server (no down) + uses: appleboy/ssh-action@master + env: + ENV_FILE: ${{ secrets.ENV_FILE }} + with: + envs: ENV_FILE + host: ${{ secrets.SSH_HOST }} + port: ${{ secrets.SSH_PORT }} + username: ${{ secrets.SSH_USERNAME }} + key: ${{ secrets.SSH_PRIVATE_KEY }} + script: | + set -e + cd ~/app/docker + + echo "⚪️ .env 생성" + echo "$ENV_FILE" > .env + + echo "⚪️ 최신 이미지 pull" + docker compose pull + + echo "⚪️ 변경분만 재기동 (down 하지 않음)" + docker compose up -d + + echo "⚪️ 사용하지 않는 이미지 정리(선택)" + docker image prune -f \ No newline at end of file diff --git a/.github/workflow/ci.yml b/.github/workflow/ci.yml new file mode 100644 index 0000000..0b4e13e --- /dev/null +++ b/.github/workflow/ci.yml @@ -0,0 +1,59 @@ +name: CI + +on: + pull_request: + types: [ opened, synchronize, reopened ] + +permissions: + contents: read + checks: write + pull-requests: write + +jobs: + spotless: + name: Code Style Check + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: "21" + distribution: "temurin" + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Check code style with Spotless + run: ./gradlew spotlessCheck + + build: + name: Build + needs: spotless + runs-on: ubuntu-22.04 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + token: ${{ secrets.GIT_ACTION_TOKEN }} + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: "21" + distribution: "temurin" + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: ./gradlew build -x test \ No newline at end of file diff --git a/docker/.dockerignore b/docker/.dockerignore new file mode 100644 index 0000000..59eb92b --- /dev/null +++ b/docker/.dockerignore @@ -0,0 +1,26 @@ +# Gradle 관련 +.gradle/ +build/ +!gradle/wrapper/gradle-wrapper.jar + +# IDE 관련 +.idea/ +.vscode/ +*.iws +*.iml +*.ipr +.classpath +.project +.settings/ + +# 로그 파일 +logs/ +*.log + +# 기타 +.git/ +.gitignore +README.md +docker-compose.yml +Dockerfile +.dockerignore \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..abf19aa --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,24 @@ +FROM eclipse-temurin:21-jdk AS build + +# 작업 위치 +WORKDIR /app + +# 소스 코드 복사 +COPY . . + +# 실행 권한 부여 +RUN chmod +x ./gradlew + +# 프로젝트 빌드 +RUN ./gradlew build -x test + +FROM eclipse-temurin:21-jre + +# 빌드 이미지에서 JAR 파일 복사 +COPY --from=build /app/build/libs/*.jar app.jar + +# 포트 노출 +EXPOSE 8080 + +# 애플리케이션 실행 +ENTRYPOINT ["java", "-jar", "app.jar"] \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..22579e0 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,71 @@ +services: + app: + image: ${DOCKER_USERNAME}/${DOCKER_REPO}:latest + container_name: insa + expose: + - "8080" + environment: + - SPRING_PROFILES_ACTIVE=${SPRING_PROFILES_ACTIVE} + - SPRING_DATASOURCE_URL=${SPRING_DATASOURCE_URL} + - SPRING_DATASOURCE_USERNAME=${SPRING_DATASOURCE_USERNAME} + - SPRING_DATASOURCE_PASSWORD=${SPRING_DATASOURCE_PASSWORD} + depends_on: + mysql: + condition: service_healthy + redis: + condition: service_healthy + networks: + - insa-network + restart: unless-stopped + + mysql: + image: mysql:8.0 + container_name: mysql + expose: + - "3306" + environment: + - MYSQL_DATABASE=${MYSQL_DATABASE} + - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} + volumes: + - mysql-data:/var/lib/mysql + healthcheck: + test: [ "CMD", "mysqladmin", "ping" ] + interval: 10s + timeout: 5s + retries: 5 + networks: + - insa-network + restart: unless-stopped + + nginx: + image: nginx:latest + container_name: nginx + ports: + - "80:80" + - "443:443" + volumes: + - /home/ubuntu/nginx/conf.d:/etc/nginx/conf.d + - /etc/letsencrypt:/etc/letsencrypt:ro + - /home/ubuntu/nginx/.htpasswd:/etc/nginx/.htpasswd:ro + depends_on: + - app + - dozzle + networks: + - insa-network + restart: unless-stopped + + dozzle: + image: amir20/dozzle:latest + container_name: dozzle + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + networks: + - insa-network + restart: unless-stopped + +networks: + insa-network: + driver: bridge + +volumes: + mysql-data: \ No newline at end of file From a530bd9683585d0759dcd6ebd6cacd19339dca93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=82=98=EA=B2=BD?= <1030n@naver.com> Date: Mon, 15 Dec 2025 21:14:03 +0900 Subject: [PATCH 2/4] =?UTF-8?q?:rocket:=20Deploy:=20network=20name=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-compose.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 22579e0..9d450cf 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,7 +1,7 @@ services: app: image: ${DOCKER_USERNAME}/${DOCKER_REPO}:latest - container_name: insa + container_name: insaroad expose: - "8080" environment: @@ -15,7 +15,7 @@ services: redis: condition: service_healthy networks: - - insa-network + - insaroad-network restart: unless-stopped mysql: @@ -34,7 +34,7 @@ services: timeout: 5s retries: 5 networks: - - insa-network + - insaroad-network restart: unless-stopped nginx: @@ -51,7 +51,7 @@ services: - app - dozzle networks: - - insa-network + - insaroad-network restart: unless-stopped dozzle: @@ -60,11 +60,11 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock:ro networks: - - insa-network + - insaroad-network restart: unless-stopped networks: - insa-network: + insaroad-network: driver: bridge volumes: From 7f415f2abf4b152471ecd2b0609c05b9a4173c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=82=98=EA=B2=BD?= <1030n@naver.com> Date: Mon, 15 Dec 2025 21:24:30 +0900 Subject: [PATCH 3/4] =?UTF-8?q?:truck:=20Rename:=20=ED=8F=B4=EB=8D=94?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/{workflow => workflows}/cd.yml | 0 .github/{workflow => workflows}/ci.yml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename .github/{workflow => workflows}/cd.yml (100%) rename .github/{workflow => workflows}/ci.yml (100%) diff --git a/.github/workflow/cd.yml b/.github/workflows/cd.yml similarity index 100% rename from .github/workflow/cd.yml rename to .github/workflows/cd.yml diff --git a/.github/workflow/ci.yml b/.github/workflows/ci.yml similarity index 100% rename from .github/workflow/ci.yml rename to .github/workflows/ci.yml From fb22a105903511296a6a69d6ced0ea5778a83453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=82=98=EA=B2=BD?= <1030n@naver.com> Date: Mon, 15 Dec 2025 21:31:46 +0900 Subject: [PATCH 4/4] =?UTF-8?q?:rocket:=20Deploy:=20redis=20=EC=A2=85?= =?UTF-8?q?=EC=86=8D=EC=84=B1=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker/docker-compose.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 9d450cf..120fa64 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -12,8 +12,6 @@ services: depends_on: mysql: condition: service_healthy - redis: - condition: service_healthy networks: - insaroad-network restart: unless-stopped