-
Notifications
You must be signed in to change notification settings - Fork 8
refactor: CD 성능 개선 #552
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: CD 성능 개선 #552
Changes from 10 commits
98b7c03
83d611f
216e83a
898d594
a76e446
59c0116
c86901a
595c6aa
63a16fa
ab3054e
01114c3
229d9aa
1b57e74
0c431df
7ae94b1
be3d47a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -10,6 +10,7 @@ jobs: | |||||||
| runs-on: ubuntu-latest | ||||||||
| permissions: | ||||||||
| contents: read | ||||||||
| packages: write | ||||||||
|
|
||||||||
| steps: | ||||||||
| - name: Checkout the code | ||||||||
|
|
@@ -18,81 +19,121 @@ jobs: | |||||||
| token: ${{ secrets.SUBMODULE_ACCESS_TOKEN }} | ||||||||
| submodules: true | ||||||||
|
|
||||||||
| # --- Java, Gradle 설정 --- | ||||||||
| - name: Set up JDK 17 | ||||||||
| uses: actions/setup-java@v4 | ||||||||
| with: | ||||||||
| java-version: '17' | ||||||||
| distribution: 'temurin' | ||||||||
|
|
||||||||
| # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. | ||||||||
| # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md | ||||||||
| - name: Setup Gradle | ||||||||
| uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 | ||||||||
|
|
||||||||
| uses: gradle/actions/setup-gradle@v3 | ||||||||
| - name: Grant execute permission for Gradle wrapper(gradlew) | ||||||||
| run: chmod +x ./gradlew | ||||||||
|
|
||||||||
| - name: Build with Gradle | ||||||||
| run: ./gradlew bootJar | ||||||||
|
|
||||||||
| - name: Copy jar file to remote | ||||||||
| uses: appleboy/scp-action@master | ||||||||
| # --- Docker 설정 --- | ||||||||
| - name: Set up Docker Buildx | ||||||||
| uses: docker/setup-buildx-action@v3 | ||||||||
| with: | ||||||||
| host: ${{ secrets.DEV_HOST }} | ||||||||
| username: ${{ secrets.DEV_USERNAME }} | ||||||||
| key: ${{ secrets.DEV_PRIVATE_KEY }} | ||||||||
| source: "./build/libs/*.jar" | ||||||||
| target: "/home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/" | ||||||||
|
|
||||||||
| - name: Copy docker file to remote | ||||||||
| uses: appleboy/scp-action@master | ||||||||
| platforms: linux/arm64 | ||||||||
| - name: Log in to GitHub Container Registry (GHCR) | ||||||||
| uses: docker/login-action@v3 | ||||||||
| with: | ||||||||
| host: ${{ secrets.DEV_HOST }} | ||||||||
| username: ${{ secrets.DEV_USERNAME }} | ||||||||
| key: ${{ secrets.DEV_PRIVATE_KEY }} | ||||||||
| source: "./Dockerfile" | ||||||||
| target: "/home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/" | ||||||||
| registry: ghcr.io | ||||||||
| username: ${{ github.repository_owner }} | ||||||||
| password: ${{ secrets.GITHUB_TOKEN }} | ||||||||
|
|
||||||||
| - name: Copy docker compose file to remote | ||||||||
| uses: appleboy/scp-action@master | ||||||||
| with: | ||||||||
| host: ${{ secrets.DEV_HOST }} | ||||||||
| username: ${{ secrets.DEV_USERNAME }} | ||||||||
| key: ${{ secrets.DEV_PRIVATE_KEY }} | ||||||||
| source: "./docker-compose.dev.yml" | ||||||||
| target: "/home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/" | ||||||||
| # --- 2. 이미지 메타데이터(이름, 태그) 정의 --- | ||||||||
| # 빌드/푸시 단계와 SSH 단계에서 공통으로 사용할 변수를 미리 정의합니다. | ||||||||
| - name: Define image name and tag | ||||||||
| id: image_meta | ||||||||
| run: | | ||||||||
| OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') | ||||||||
| IMAGE_TAG=$(date +'%Y%m%d-%H%M%S') | ||||||||
| echo "image_name=ghcr.io/${OWNER_LOWERCASE}/solid-connection-dev" >> $GITHUB_OUTPUT | ||||||||
| echo "image_tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT | ||||||||
|
|
||||||||
| - name: Copy alloy config file to remote | ||||||||
| uses: appleboy/scp-action@master | ||||||||
| # --- 3. Docker 이미지 빌드, 푸시, 캐시 --- | ||||||||
| # 'docker/build-push-action'을 사용하여 캐시 옵션을 적용합니다. | ||||||||
| - name: Build, push, and cache Docker image | ||||||||
| uses: docker/build-push-action@v5 | ||||||||
| with: | ||||||||
| host: ${{ secrets.DEV_HOST }} | ||||||||
| username: ${{ secrets.DEV_USERNAME }} | ||||||||
| key: ${{ secrets.DEV_PRIVATE_KEY }} | ||||||||
| source: "./docs/infra-config/config.alloy" | ||||||||
| target: "/home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/" | ||||||||
| context: . | ||||||||
| platforms: linux/arm64 | ||||||||
| push: true | ||||||||
| tags: ${{ format('{0}:{1}', steps.image_meta.outputs.image_name, steps.image_meta.outputs.image_tag) }} | ||||||||
| cache-from: type=registry,ref=${{ steps.image_meta.outputs.image_name }}:buildcache | ||||||||
| cache-to: type=registry,ref=${{ steps.image_meta.outputs.image_name }}:buildcache,mode=max | ||||||||
|
|
||||||||
| - name: Copy nginx config to remote | ||||||||
| uses: appleboy/scp-action@master | ||||||||
| with: | ||||||||
| host: ${{ secrets.DEV_HOST }} | ||||||||
| username: ${{ secrets.DEV_USERNAME }} | ||||||||
| key: ${{ secrets.DEV_PRIVATE_KEY }} | ||||||||
| source: "./docs/infra-config/nginx.dev.conf" | ||||||||
| target: "/home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/nginx" | ||||||||
| rename: "default.conf" | ||||||||
| # --- 4. 설정 파일들만 scp로 전송 --- | ||||||||
| - name: Copy config files to remote | ||||||||
| run: | | ||||||||
| echo "${{ secrets.DEV_PRIVATE_KEY }}" > deploy_key.pem | ||||||||
| chmod 600 deploy_key.pem | ||||||||
|
|
||||||||
| scp -i deploy_key.pem \ | ||||||||
| -o StrictHostKeyChecking=no \ | ||||||||
| ./docker-compose.dev.yml \ | ||||||||
| ./docs/infra-config/config.alloy \ | ||||||||
| ./docs/infra-config/nginx.dev.conf \ | ||||||||
| ${{ secrets.DEV_USERNAME }}@${{ secrets.DEV_HOST }}:/home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/ | ||||||||
|
|
||||||||
| # --- 5. 서버에서 'docker pull' 및 서비스 재시작 --- | ||||||||
| - name: Run docker compose and apply nginx config | ||||||||
| uses: appleboy/ssh-action@master | ||||||||
| with: | ||||||||
| host: ${{ secrets.DEV_HOST }} | ||||||||
| username: ${{ secrets.DEV_USERNAME }} | ||||||||
| key: ${{ secrets.DEV_PRIVATE_KEY }} | ||||||||
| script_stop: true | ||||||||
| script: | | ||||||||
| sudo cp /home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/nginx/default.conf /etc/nginx/conf.d/default.conf | ||||||||
| run: | | ||||||||
| echo "${{ secrets.DEV_PRIVATE_KEY }}" > deploy_key_ssh.pem | ||||||||
| chmod 600 deploy_key_ssh.pem | ||||||||
|
||||||||
|
|
||||||||
| ssh -i deploy_key_ssh.pem \ | ||||||||
| -o StrictHostKeyChecking=no \ | ||||||||
| ${{ secrets.DEV_USERNAME }}@${{ secrets.DEV_HOST }} \ | ||||||||
| ' | ||||||||
| set -e | ||||||||
|
|
||||||||
| # [수정] 1. 변수를 'image_meta' 단계의 출력값에서 가져옴 | ||||||||
| export OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') | ||||||||
| export IMAGE_TAG_ONLY=${{ steps.image_meta.outputs.image_tag }} | ||||||||
| export FULL_IMAGE_NAME="ghcr.io/${OWNER_LOWERCASE}/solid-connection-dev:${IMAGE_TAG_ONLY}" | ||||||||
|
|
||||||||
| # 2. 서버가 GHCR에 로그인 (pull 받기 위해) | ||||||||
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin | ||||||||
|
||||||||
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin | |
| OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') | |
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${OWNER_LOWERCASE} --password-stdin |
🤖 Prompt for AI Agents
.github/workflows/dev-cd.yml around line 100: the docker login uses ${{
github.repository_owner }} which may contain uppercase letters while the image
tag and OWNER_LOWERCASE are used elsewhere, causing GHCR auth failures; change
the login username to the already-computed OWNER_LOWERCASE variable (or compute
a lowercase owner just before login) so the docker login user matches the
lowercase image namespace, and apply the same change in prod-cd.yml.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이전에 lower_case로 통일하도록 이미지 메타데이터 정의 스텝에서 전처리를 해두었기에 문제가 나지 않을 것 같은데?
심지어 내 닉네임이 Hexeong인데, fork 레포에서 깃헙 액션을 실행시켰을 때에 문제가 발생하지 않았었어
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
맞습니다! 제가 잘못 지적했네요. 죄송합니다. 🙇
-
Docker/GHCR 로그인은 사용자명 대소문자를 구분하지 않습니다.
- Line 100의
docker login ghcr.io -u ${{ github.repository_owner }}는Hexeong이든hexeong이든 정상적으로 인증됩니다.
- Line 100의
-
이미지 경로는 올바르게 소문자를 사용하고 있습니다.
- Line 95에서
OWNER_LOWERCASE를 재계산하고 - Line 97에서
FULL_IMAGE_NAME에 소문자 버전을 사용하여 - Line 103의
docker pull이 정상 작동합니다.
- Line 95에서
실제 테스트에서 문제가 없었다는 것이 이를 증명하네요. 불필요한 수정 제안을 드려 혼란을 드려 죄송합니다!
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지금 쓰기가 가능한 토큰이 서버로 전송되는데 보안상 취약하지 않을까요...? 읽기 전용 토큰을 따로 발급해서 사용하는 게 좋아보입니당
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SSH를 통해 GHCR에 접근하는 이 방식을 적용하려면, SUBMODULE_ACCESS_TOKEN처럼 Fine-grained Token을 사용하는 것이 보안상 가장 좋다고 생각합니다!
하지만 이 방식을 사용하려면 GHCR 읽기 권한이 있는 분이 직접 토큰을 발급해야 하는데, 이는 특정 계정에 파이프라인이 의존하게 되는 문제가 있어 망설여졌습니다.
그래서 일단은 임시로 GITHUB_TOKEN을 사용하는 방식을 적용했습니다만, 혹시 이 '개인 종속성' 문제를 해결할 더 좋은 방법이 있다면 의견 부탁드립니다! @lsy1307
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
machine user 개념으로 CI/CD용 계정을 따로 만들어서 사용하는 건 어떨까요? Github Docs에도 나와있는 내용입니다!
참고 : https://docs.github.com/en/get-started/learning-about-github/types-of-github-accounts#user-accounts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
machine user 대신 최근 Github 추천하는 방식인 Github App을 사용해서 Repository에서 임시 토큰을 발급할 수 있도록 개선했습니다! 해당 문제는 해결된 것 같아요!
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,89 +10,134 @@ jobs: | |
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
|
|
||
| steps: | ||
| - name: Checkout the code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| token: ${{ secrets.SUBMODULE_ACCESS_TOKEN }} | ||
| submodules: true | ||
| - name: Checkout the code | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| token: ${{ secrets.SUBMODULE_ACCESS_TOKEN }} | ||
| submodules: true | ||
|
|
||
| - name: Set up JDK 17 | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| java-version: '17' | ||
| distribution: 'temurin' | ||
| # --- Java, Gradle 설정 (dev와 동일하게 버전 통일) --- | ||
| - name: Set up JDK 17 | ||
| uses: actions/setup-java@v4 | ||
| with: | ||
| java-version: '17' | ||
| distribution: 'temurin' | ||
| - name: Setup Gradle | ||
| uses: gradle/actions/setup-gradle@v3 | ||
| - name: Grant execute permission for Gradle wrapper(gradlew) | ||
| run: chmod +x ./gradlew | ||
| - name: Build with Gradle | ||
| run: ./gradlew bootJar | ||
|
|
||
| # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. | ||
| # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md | ||
| - name: Setup Gradle | ||
| uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 | ||
| # --- 1. Docker 설정 --- | ||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v3 | ||
| with: | ||
| platforms: linux/arm64 | ||
| - name: Log in to GitHub Container Registry (GHCR) | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| registry: ghcr.io | ||
| username: ${{ github.repository_owner }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} | ||
|
Comment on lines
+40
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. GHCR 로그인 시 사용자명 대소문자 불일치 문제가 있습니다. 워크플로우를 자세히 보면:
문제: GitHub 저장소 소유자명이 대문자를 포함하면, docker pull 시 이미지명과 로그인 사용자명의 대소문자 불일치로 인증 오류가 발생할 수 있습니다. 아래와 같이 수정하세요: # 2. 서버가 GHCR에 로그인 (pull 받기 위해)
- echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
+ OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
+ echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${OWNER_LOWERCASE} --password-stdinAlso applies to: 98-100 🤖 Prompt for AI Agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 레지스트리 경로명은 항상 소문자로 유지되기에 repository_owner가 대문자가 포함되어 있어도 이후에 문제가 되지 않아! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Hexeong, 설명 감사합니다! GHCR의 인증 과정에서 사용자명은 대소문자를 구분하지 않고, 레지스트리 경로는 자동으로 소문자로 정규화되는 점을 확인해주셨네요. 제가 너무 신중하게 접근했습니다. 현재 구현이 문제없이 작동하겠네요! 👍 ✏️ Learnings added
|
||
|
|
||
| - name: Grant execute permission for Gradle wrapper(gradlew) | ||
| run: chmod +x ./gradlew | ||
| # --- 2. 이미지 메타데이터(이름, 태그) 정의 --- | ||
| - name: Define image name and tag | ||
| id: image_meta | ||
| run: | | ||
| OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') | ||
| IMAGE_TAG=$(date +'%Y%m%d-%H%M%S') | ||
| echo "image_name=ghcr.io/${OWNER_LOWERCASE}/solid-connection-server" >> $GITHUB_OUTPUT | ||
| echo "image_tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT | ||
|
|
||
| - name: Build with Gradle | ||
| run: ./gradlew bootJar | ||
| # --- 3. Docker 이미지 빌드, 푸시, 캐시 --- | ||
| - name: Build, push, and cache Docker image | ||
| uses: docker/build-push-action@v5 | ||
| with: | ||
| context: . | ||
| platforms: linux/arm64 | ||
| push: true | ||
| tags: ${{ format('{0}:{1}', steps.image_meta.outputs.image_name, steps.image_meta.outputs.image_tag) }} | ||
| cache-from: type=registry,ref=${{ steps.image_meta.outputs.image_name }}:buildcache | ||
| cache-to: type=registry,ref=${{ steps.image_meta.outputs.image_name }}:buildcache,mode=max | ||
|
|
||
| # --- 4. 설정 파일들만 scp로 전송 --- | ||
| - name: Copy config files to remote | ||
| run: | | ||
| echo "${{ secrets.PRIVATE_KEY }}" > deploy_key.pem | ||
| chmod 600 deploy_key.pem | ||
|
|
||
| - name: Copy jar file to remote | ||
| uses: appleboy/scp-action@master | ||
| with: | ||
| host: ${{ secrets.HOST }} | ||
| username: ${{ secrets.USERNAME }} | ||
| key: ${{ secrets.PRIVATE_KEY }} | ||
| source: "./build/libs/*.jar" | ||
| target: "/home/${{ secrets.USERNAME }}/solid-connect-server/" | ||
|
|
||
| - name: Copy docker file to remote | ||
| uses: appleboy/scp-action@master | ||
| with: | ||
| host: ${{ secrets.HOST }} | ||
| username: ${{ secrets.USERNAME }} | ||
| key: ${{ secrets.PRIVATE_KEY }} | ||
| source: "./Dockerfile" | ||
| target: "/home/${{ secrets.USERNAME }}/solid-connect-server/" | ||
|
|
||
| - name: Copy docker compose file to remote | ||
| uses: appleboy/scp-action@master | ||
| with: | ||
| host: ${{ secrets.HOST }} | ||
| username: ${{ secrets.USERNAME }} | ||
| key: ${{ secrets.PRIVATE_KEY }} | ||
| source: "./docker-compose.prod.yml" | ||
| target: "/home/${{ secrets.USERNAME }}/solid-connect-server/" | ||
|
|
||
| - name: Copy alloy config file to remote | ||
| uses: appleboy/scp-action@master | ||
| with: | ||
| host: ${{ secrets.HOST }} | ||
| username: ${{ secrets.USERNAME }} | ||
| key: ${{ secrets.PRIVATE_KEY }} | ||
| source: "./docs/infra-config/config.alloy" | ||
| target: "/home/${{ secrets.USERNAME }}/solid-connect-server/" | ||
|
|
||
| - name: Copy nginx config to remote | ||
| uses: appleboy/scp-action@master | ||
| with: | ||
| host: ${{ secrets.HOST }} | ||
| username: ${{ secrets.USERNAME }} | ||
| key: ${{ secrets.PRIVATE_KEY }} | ||
| source: "./docs/infra-config/nginx.prod.conf" | ||
| target: "/home/${{ secrets.USERNAME }}/solid-connection-prod/nginx" | ||
| rename: "default.conf" | ||
|
|
||
| - name: Run docker compose and apply nginx config | ||
| uses: appleboy/ssh-action@master | ||
| with: | ||
| host: ${{ secrets.HOST }} | ||
| username: ${{ secrets.USERNAME }} | ||
| key: ${{ secrets.PRIVATE_KEY }} | ||
| script_stop: true | ||
| script: | | ||
| sudo cp /home/${{ secrets.USERNAME }}/solid-connection-prod/nginx/default.conf /etc/nginx/conf.d/default.conf | ||
| sudo nginx -t | ||
| sudo nginx -s reload | ||
| scp -i deploy_key.pem \ | ||
| -o StrictHostKeyChecking=no \ | ||
| ./docker-compose.prod.yml \ | ||
| ./docs/infra-config/config.alloy \ | ||
| ./docs/infra-config/nginx.prod.conf \ | ||
| ${{ secrets.USERNAME }}@${{ secrets.HOST }}:/home/${{ secrets.USERNAME }}/solid-connection-prod/ | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # --- 5. 서버에서 'docker pull' 및 서비스 재시작 --- | ||
| - name: Run docker compose and apply nginx config | ||
| run: | | ||
| echo "${{ secrets.PRIVATE_KEY }}" > deploy_key_ssh.pem | ||
| chmod 600 deploy_key_ssh.pem | ||
|
|
||
| ssh -i deploy_key_ssh.pem \ | ||
| -o StrictHostKeyChecking=no \ | ||
| ${{ secrets.USERNAME }}@${{ secrets.HOST }} \ | ||
| ' | ||
| set -e | ||
|
|
||
| # 1. 변수 설정 | ||
| export OWNER_LOWERCASE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') | ||
| export IMAGE_TAG_ONLY=${{ steps.image_meta.outputs.image_tag }} | ||
| export FULL_IMAGE_NAME="ghcr.io/${OWNER_LOWERCASE}/solid-connection-server:${IMAGE_TAG_ONLY}" | ||
|
|
||
| # 2. 서버가 GHCR에 로그인 (pull 받기 위해) | ||
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin | ||
|
|
||
| # 3. docker pull (전체 이미지 이름 사용) | ||
| echo "Pulling new image layer from GHCR..." | ||
| docker pull $FULL_IMAGE_NAME | ||
|
|
||
| # 4. 작업 디렉토리로 이동 및 Nginx 설정 이동 | ||
| cd /home/${{ secrets.USERNAME }}/solid-connection-prod | ||
| mkdir -p ./nginx | ||
| mv ./nginx.prod.conf ./nginx/default.conf | ||
|
|
||
| # 5. Nginx 재시작 | ||
| sudo cp ./nginx/default.conf /etc/nginx/conf.d/default.conf | ||
| sudo nginx -t | ||
| sudo nginx -s reload | ||
|
|
||
| # 6. Docker Compose 재시작 (안정성 확보 로직 포함) | ||
| echo "Restarting Docker Compose with tag: $IMAGE_TAG_ONLY" | ||
| echo "Stopping containers gracefully..." | ||
| docker compose -f docker-compose.prod.yml stop | ||
|
|
||
| echo "Removing old containers and networks..." | ||
| docker compose -f docker-compose.prod.yml down --remove-orphans | ||
|
|
||
| echo "Starting new containers..." | ||
| OWNER_LOWERCASE=$OWNER_LOWERCASE IMAGE_TAG=$IMAGE_TAG_ONLY docker compose -f docker-compose.prod.yml up -d | ||
|
|
||
| # 7. <none> 이미지 정리 | ||
| echo "Pruning dangling docker images..." | ||
| docker image prune -f | ||
|
|
||
| echo "Deploy and Docker Compose restart finished." | ||
| ' | ||
|
|
||
| cd /home/${{ secrets.USERNAME }}/solid-connect-server | ||
| docker compose -f docker-compose.prod.yml down | ||
| docker compose -f docker-compose.prod.yml up -d --build | ||
| # --- 6. 이미지 정리 --- | ||
| - name: Clean up old image versions from GHCR | ||
| if: success() | ||
| uses: snok/container-retention-policy@v2 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| image-names: solid-connection-server | ||
| delete-untagged: true | ||
| keep-n-tags: 5 | ||
| account-type: org | ||
| org-name: ${{ github.repository_owner }} | ||
| cut-off: '7 days ago UTC' | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
github.repository_owner로 설정하면 레포 소유자 이름(e.g. whqtker)으로 고정되는 건가요 ? 만약 그렇다면,solid-connection과 같이 사용자에 종속되지 않는 이름으로 설정하는 게 좋을 거 같습니다 !There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Organization에 속한 레포의 워크플로우 실행의 경우
github.repository_owner은 Organization 이름인solid-connection이 됩니다! 때문에 사용자 이름으로 종속되지는 않아 해당 문제는 없을 것 같아요!There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
확인했습니다 ~!