chore/#243 운영 배포를 위한 스테이징 환경 구축 및 스크립트 구성#244
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Walkthrough스테이징 배포 파이프라인을 추가하고, 관리자용 컨트롤러들의 기본 경로를 /api/v1/admin/*로 변경했다. prod 프로필에서 SpringDoc(Swagger UI, API Docs)을 비활성화했다. 스테이징용 Docker Compose, Nginx 설정, 원격 배포 스크립트, GitHub Actions 워크플로우를 신규 추가했다. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested reviewers
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
Test Coverage Report
|
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## develop #244 +/- ##
==========================================
Coverage 91.42% 91.42%
Complexity 159 159
==========================================
Files 49 49
Lines 455 455
Branches 9 9
==========================================
Hits 416 416
Misses 29 29
Partials 10 10 Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 10
🧹 Nitpick comments (36)
aics-admin/src/main/resources/application-prod.yml (1)
21-21: YAMLLint 경고: 파일 끝 개행 누락(EOL).CI/Lint 안정화를 위해 마지막 줄에 개행을 추가해 주세요.
다음처럼 마지막에 빈 줄 1줄을 추가하면 됩니다:
api-docs: enabled: false +aics-auth/src/main/resources/application-prod.yml (1)
21-21: YAMLLint 경고: 파일 끝 개행 누락(EOL).관리형 린트 오류를 없애기 위해 마지막 줄에 개행을 추가해 주세요.
수정 예시:
api-docs: enabled: false +aics-admin/src/main/java/kgu/developers/admin/carousel/presentation/CarouselAdminControllerImpl.java (1)
24-26: 클라이언트/프록시 측 영향 검토 및 점진적 이전 전략 제안(선택).기존 /api/v1/carousels 호출이 남아있다면 단기적으로 Nginx에서 리라이트로 완충하는 것도 고려해볼 수 있습니다.
예시(Nginx):
location ~ ^/api/v1/(comments|carousels|users|abouts|clubs|files|labs|posts|professors)(/.*)?$ { return 308 /api/v1/admin/$1$2; }운영 반영 전/후 일정에 맞춰 제거하면 안전하게 마이그레이션 가능합니다.
aics-admin/src/main/java/kgu/developers/admin/lab/presentation/LabAdminControllerImpl.java (1)
26-26: 하드코딩된 경로 상수화 제안(선택): 중복/오타 리스크 감소여러 Admin 컨트롤러에서 동일 접두어가 반복됩니다. 공통 상수로 추출하면 유지보수가 쉬워집니다.
적용 예시(현재 파일):
-@RequestMapping("/api/v1/admin/labs") +@RequestMapping(AdminApiPaths.V1 + "/labs")추가: 공용 상수 정의(새 파일 예시)
// aics-admin 모듈 내 적절한 패키지에 생성 (예: kgu.developers.admin.support) package kgu.developers.admin.support; public final class AdminApiPaths { private AdminApiPaths() {} public static final String V1 = "/api/v1/admin"; }컨트롤러에 import 추가:
import kgu.developers.admin.support.AdminApiPaths;aics-admin/src/main/java/kgu/developers/admin/about/presentation/AboutAdminControllerImpl.java (1)
25-25: 경로 상수화(선택): 다수 컨트롤러 공통 접두어 중앙집중화다른 Admin 컨트롤러와 동일하게 상수 재사용을 권장합니다.
-@RequestMapping("/api/v1/admin/abouts") +@RequestMapping(AdminApiPaths.V1 + "/abouts")상수 정의 예시는 이전 코멘트의 AdminApiPaths 참고.
aics-admin/src/main/java/kgu/developers/admin/file/presentation/FileAdminControllerImpl.java (1)
25-25: 경로 상수화(선택)여타 컨트롤러와 동일하게 경로 상수 사용을 권장합니다.
-@RequestMapping("/api/v1/admin/files") +@RequestMapping(AdminApiPaths.V1 + "/files")aics-admin/src/main/java/kgu/developers/admin/professor/presentation/ProfessorAdminControllerImpl.java (1)
24-24: 경로 상수화(선택)다른 파일과 동일한 제안입니다.
-@RequestMapping("/api/v1/admin/professors") +@RequestMapping(AdminApiPaths.V1 + "/professors")aics-admin/src/main/java/kgu/developers/admin/club/presentation/ClubAdminControllerImpl.java (2)
26-26: 경로 상수화(선택)여타 컨트롤러와 동일 제안입니다.
-@RequestMapping("/api/v1/admin/clubs") +@RequestMapping(AdminApiPaths.V1 + "/clubs")
34-34: 경미: fileId에 양수 제약 일관 적용 제안동일 패턴의 LabAdminControllerImpl는
@Positive @RequestParam(required = false) Long fileId로 검증을 일관 적용합니다. Club도 동일하게 두면 입력 검증이 명확해집니다. null은 허용되며, 값이 있을 때만 양수 검증이 적용됩니다.- @RequestParam(required = false) Long fileId, + @Positive @RequestParam(required = false) Long fileId,aics-api/src/main/resources/application-prod.yml (1)
17-21: SpringDoc(prod) 비활성화 설정 적절 — 파일 끝 개행(EOF newline) 추가 필요
springdoc.swagger-ui.enabled=false,springdoc.api-docs.enabled=false적용은 운영 보안 관점에서 적절합니다.- YAMLlint 경고(new-line-at-end-of-file)를 해소하기 위해 파일 끝에 개행을 1줄 추가해 주세요.
적용 예:
api-docs: enabled: false +docker/staging/networks.yml (1)
1-3: 네트워크 정의 LGTM — EOF 개행 추가
aics-network브리지 네트워크 정의는 적절합니다.- 파일 끝 개행 1줄 추가로 YAMLlint 경고를 제거해 주세요.
docker/staging/service/service-redis.yml (4)
9-10: 호스트 포트 공개 범위 축소 또는 제거 권장.스테이징이라도 불필요한 외부 노출은 줄이는 게 안전합니다. 내부 네트워크에서만 사용한다면 ports를 제거하거나, 호스트 바인딩을 loopback으로 제한하세요.
예시:
- ports: - - "6379:6379" + # 내부 테스트 용도로만 필요할 때: + ports: + - "127.0.0.1:6379:6379"
3-3: 이미지 태그 고정 권장.
latest는 재현성과 보안 측면에서 리스크가 큽니다. 메이저/마이너 또는 digest로 고정해 주세요.예시:
- image: redis:latest + image: redis:7-alpine
1-14: 옵션: 데이터 지속성(필요 시)과 헬스체크 추가 제안.캐시로만 쓰지 않고 재시작 시 데이터 유지가 필요하다면 볼륨을 마운트하고, 기동 상태 판단을 위해 간단한 헬스체크를 권장합니다.
예시:
services: redis: @@ - networks: - - aics-network + networks: + - aics-network + # 필요 시 데이터 지속성 + volumes: + - redis-data:/data + +volumes: + redis-data:주의: 동일 docker compose 묶음 내 다른 파일에서 이미 volumes를 선언한다면 중복 선언을 피하세요.
14-14: 파일 끝 개행 추가.일부 툴(yamllint 등)과 VCS에서 경고가 발생합니다. 마지막 줄에 개행을 추가해 주세요.
docker/staging/service/service-postgres.yml (4)
8-9: DB 포트 외부 노출 축소 권장.내부 네트워크 사용만 필요하다면 포트 매핑을 제거하거나 loopback으로 제한해 주세요.
- ports: - - "5432:5432" + # 로컬 호스트에서만 접근 필요 시: + ports: + - "127.0.0.1:5432:5432" + # 전혀 필요 없다면 ports 섹션 제거
3-3: 이미지 태그 고정 권장.
postgres:15는 최신 마이너로 부동입니다. 재현성을 위해 패치 버전 또는 alpine 변형 등으로 고정해 주세요.- image: postgres:15 + image: postgres:15-alpine
10-17: 헬스체크를 추가해 서비스 의존성 안정화.DB가 준비되기 전에 앱이 붙으면서 실패/재시도되는 현상을 줄일 수 있습니다.
environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] + interval: 10s + timeout: 5s + retries: 5
20-20: 파일 끝 개행 추가.yamllint 경고(new-line-at-end-of-file)가 있습니다. 마지막 줄에 개행을 추가해 주세요.
docker/staging/service/service-nginx.yml (3)
3-3: 이미지 태그 고정 권장.배포 재현성과 예측 가능성을 위해 특정 버전으로 고정해 주세요.
- image: nginx:latest + image: nginx:1.25-alpine
2-9: 옵션: depends_on으로 초기 502 빈도 완화.백엔드 컨테이너가 준비되기 전에 Nginx가 먼저 떠서 502가 발생할 수 있습니다. 엄밀한 readiness가 아니지만 초기 실패를 줄이는 데 도움이 됩니다.
nginx: image: nginx:latest + depends_on: + - aics-api + - aics-admin + - aics-auth + - aics-app
9-9: 파일 끝 개행 추가.yamllint 경고(new-line-at-end-of-file)가 있습니다.
nginx/staging/nginx.conf (4)
4-9: 프록시 표준 헤더 보강(X-Forwarded-For/Proto).백엔드에서 클라이언트 IP/프로토콜을 정확히 인지하도록 표준 프록시 헤더를 추가하세요.
location ^~ /api/v1/auth/ { proxy_pass http://aics-auth:8082/api/v1/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Origin $http_origin; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; }
11-16: 프록시 표준 헤더 보강(X-Forwarded-For/Proto).location ^~ /api/v1/admin/ { proxy_pass http://aics-admin:8081/api/v1/admin/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Origin $http_origin; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; }
18-23: 프록시 표준 헤더 보강(X-Forwarded-For/Proto).location ^~ /api/v1/ { proxy_pass http://aics-api:8080/api/v1/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Origin $http_origin; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; }
25-32: WebSocket 블록에서도 표준 헤더 추가 및 Connection 헤더 따옴표 일관화.실사용 시 앱이 클라이언트 IP/프로토콜을 필요로 할 수 있습니다. 또한 관례적으로 Connection 값은 큰따옴표를 사용합니다.
location / { proxy_pass http://aics-app:3000/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection 'upgrade'; + proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; }.github/workflows/staging-build-deploy.yml (1)
24-28: Gradle 빌드 최적화 제안(선택).모듈별로
clean build를 각각 실행하면 캐시 이점을 잃습니다. 루트에서 멀티프로젝트 빌드하거나 clean은 1회만 수행하는 편이 빠릅니다.- ./gradlew clean build -p aics-admin -x test - ./gradlew clean build -p aics-api -x test - ./gradlew clean build -p aics-auth -x test + ./gradlew clean + ./gradlew :aics-admin:build :aics-api:build :aics-auth:build -x testdeploy/staging/deploy.sh (3)
2-2: 셸 스크립트 안전성 강화:set -u -o pipefail추가 제안정의되지 않은 변수 접근과 파이프라인 오류를 조기에 감지하도록 엄격 모드를 권장합니다.
-set -e +set -Eeuo pipefail
4-4: APP_HOME 계산 방식이 취약합니다 — 스크립트 위치 기준으로 계산하도록 변경 권장현재
$(pwd)/backend는 실행 디렉터리에 의존해 오작동 가능성이 큽니다. 스크립트 파일 위치를 기준으로APP_HOME을 계산하세요.-APP_HOME=$(pwd)/backend +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# 레포 루트 기준으로 backend 위치 추적 (deploy/staging/deploy.sh → ../../backend) +APP_HOME="$(cd "$SCRIPT_DIR/../.." && pwd)/backend"
6-10: 이미지 tar 존재 여부 확인 및 반복 로드로 간결화지정 경로에 tar 파일이 없으면 실패합니다. 존재 검증과 반복 처리로 가독성과 견고성을 높일 수 있습니다. 경로에 공백이 있을 경우를 대비해 인용도 추가합니다.
-echo "===== Loading Docker images =====" -sudo docker load -i $APP_HOME/tar/aics-api.tar -sudo docker load -i $APP_HOME/tar/aics-admin.tar -sudo docker load -i $APP_HOME/tar/aics-auth.tar +echo "===== Loading Docker images =====" +for img in aics-api aics-admin aics-auth; do + TAR_PATH="$APP_HOME/tar/${img}.tar" + if [[ ! -f "$TAR_PATH" ]]; then + echo "ERROR: Image tar not found: $TAR_PATH" >&2 + exit 1 + fi + sudo docker load -i "$TAR_PATH" +donedocker/staging/service/service-application.yml (6)
3-7: 가용성: 재시작 정책 추가 제안의도치 않은 종료 시 자동 복구를 위해
restart: unless-stopped권장합니다.aics-api: image: ${DOCKER_USERNAME}/aics-api:latest container_name: aics-api + restart: unless-stopped
25-29: 가용성: 재시작 정책 추가 제안 (aics-admin)aics-admin: image: ${DOCKER_USERNAME}/aics-admin:latest container_name: aics-admin + restart: unless-stopped
47-51: 가용성: 재시작 정책 추가 제안 (aics-auth)aics-auth: image: ${DOCKER_USERNAME}/aics-auth:latest container_name: aics-auth + restart: unless-stopped
9-21: 환경변수 중복 정의를 YAML 앵커로 제거하여 유지보수성 향상3개 서비스에 동일한 env가 반복됩니다. YAML 앵커/alias로 중복 제거를 권장합니다.
예시(참고용, 파일 상단에 공통 정의 추가):
x-common-env: &common-env SPRING_PROFILES_ACTIVE: prod DB_HOST: postgres DB_PORT: 5432 DB_NAME: ${POSTGRES_DB} DB_USERNAME: ${POSTGRES_USER} DB_PASSWORD: ${POSTGRES_PASSWORD} JWT_ISSUER: kgudevelopers@gmail.com JWT_SECRET_KEY: ${JWT_SECRET_KEY} REDIS_HOST: redis REDIS_PASSWORD: ${REDIS_PASSWORD} FILE_SECRET_KEY: ${FILE_SECRET_KEY}서비스 내 적용:
environment: <<: *common-envAlso applies to: 31-43, 53-65
21-22: 의존성 기동 순서 관리: depends_on(+헬스체크) 고려Postgres/Redis가 준비되기 전에 앱이 시작되면 초기 연결 실패가 발생할 수 있습니다.
depends_on과 헬스체크(별도 서비스 파일에서 정의 필요)를 활용하세요.예시:
depends_on: postgres: condition: service_healthy redis: condition: service_healthy주의:
service-postgres.yml,service-redis.yml에 적절한healthcheck가 정의되어 있어야 합니다. 없다면 추가가 필요합니다.Also applies to: 44-45, 65-66
66-66: EOF 개행 누락파일 끝에 개행 문자가 없습니다. 일부 도구에서 경고가 발생합니다. 개행 추가를 권장합니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (22)
.github/workflows/staging-build-deploy.yml(1 hunks)aics-admin/src/main/java/kgu/developers/admin/about/presentation/AboutAdminControllerImpl.java(1 hunks)aics-admin/src/main/java/kgu/developers/admin/carousel/presentation/CarouselAdminControllerImpl.java(1 hunks)aics-admin/src/main/java/kgu/developers/admin/club/presentation/ClubAdminControllerImpl.java(1 hunks)aics-admin/src/main/java/kgu/developers/admin/comment/presentation/CommentAdminControllerImpl.java(1 hunks)aics-admin/src/main/java/kgu/developers/admin/file/presentation/FileAdminControllerImpl.java(1 hunks)aics-admin/src/main/java/kgu/developers/admin/lab/presentation/LabAdminControllerImpl.java(1 hunks)aics-admin/src/main/java/kgu/developers/admin/post/presentation/PostAdminControllerImpl.java(1 hunks)aics-admin/src/main/java/kgu/developers/admin/professor/presentation/ProfessorAdminControllerImpl.java(1 hunks)aics-admin/src/main/java/kgu/developers/admin/user/presentation/UserAdminControllerImpl.java(1 hunks)aics-admin/src/main/resources/application-prod.yml(1 hunks)aics-api/src/main/resources/application-prod.yml(1 hunks)aics-auth/src/main/resources/application-prod.yml(1 hunks)deploy/staging/deploy.sh(1 hunks)docker/staging/docker-compose-db.yml(1 hunks)docker/staging/docker-compose.yml(1 hunks)docker/staging/networks.yml(1 hunks)docker/staging/service/service-application.yml(1 hunks)docker/staging/service/service-nginx.yml(1 hunks)docker/staging/service/service-postgres.yml(1 hunks)docker/staging/service/service-redis.yml(1 hunks)nginx/staging/nginx.conf(1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
docker/staging/service/service-redis.yml
[error] 14-14: no new line character at the end of file
(new-line-at-end-of-file)
docker/staging/service/service-postgres.yml
[error] 20-20: no new line character at the end of file
(new-line-at-end-of-file)
docker/staging/networks.yml
[error] 3-3: no new line character at the end of file
(new-line-at-end-of-file)
docker/staging/docker-compose-db.yml
[error] 4-4: no new line character at the end of file
(new-line-at-end-of-file)
aics-api/src/main/resources/application-prod.yml
[error] 21-21: no new line character at the end of file
(new-line-at-end-of-file)
docker/staging/docker-compose.yml
[error] 4-4: no new line character at the end of file
(new-line-at-end-of-file)
aics-admin/src/main/resources/application-prod.yml
[error] 21-21: no new line character at the end of file
(new-line-at-end-of-file)
docker/staging/service/service-nginx.yml
[error] 9-9: no new line character at the end of file
(new-line-at-end-of-file)
docker/staging/service/service-application.yml
[error] 66-66: no new line character at the end of file
(new-line-at-end-of-file)
aics-auth/src/main/resources/application-prod.yml
[error] 21-21: no new line character at the end of file
(new-line-at-end-of-file)
🪛 actionlint (1.7.7)
.github/workflows/staging-build-deploy.yml
13-13: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue
(action)
31-31: shellcheck reported issue in this script: SC2086:info:1:28: Double quote to prevent globbing and word splitting
(shellcheck)
31-31: shellcheck reported issue in this script: SC2086:info:2:26: Double quote to prevent globbing and word splitting
(shellcheck)
31-31: shellcheck reported issue in this script: SC2086:info:3:27: Double quote to prevent globbing and word splitting
(shellcheck)
37-37: shellcheck reported issue in this script: SC2086:info:2:24: Double quote to prevent globbing and word splitting
(shellcheck)
37-37: shellcheck reported issue in this script: SC2086:info:3:22: Double quote to prevent globbing and word splitting
(shellcheck)
37-37: shellcheck reported issue in this script: SC2086:info:4:23: Double quote to prevent globbing and word splitting
(shellcheck)
🔇 Additional comments (17)
aics-admin/src/main/java/kgu/developers/admin/comment/presentation/CommentAdminControllerImpl.java (2)
12-12: 관리자 네임스페이스로의 경로 변경 적절합니다.Nginx 리버스 프록시 설계(/api/v1/admin/**)와 일관성이 생겨 운영/스테이징 분리에 유리합니다.
12-12: 레거시 API 호출 경로 검토: 실제 호출 지점 확인 필요제공된 스크립트 실행 결과, 아래 파일들은 모두 컨트롤러 정의(
@RequestMapping) 및SecurityConfig설정으로 검출되었으며, 의도된 동작입니다.
실제 레거시 경로(/api/v1/comments등)가 호출되고 있는지를 확인하려면 다음 영역을 추가 점검해주세요:
- 프론트엔드 코드(UI 레포지토리)
- 통합/인수 테스트(src/**/*Test.java 등)
- 외부 클라이언트 설정 및 API 문서화된 클라이언트 SDK
aics-admin/src/main/resources/application-prod.yml (1)
17-21: prod 환경에서 OpenAPI/Swagger 비활성화 적절합니다.운영 노출 최소화와 공격면 축소에 도움이 됩니다. 개발/스테이징에서는 별도 프로필로만 활성화되도록 유지하면 좋습니다.
aics-auth/src/main/resources/application-prod.yml (1)
17-21: prod 환경에서 OpenAPI/Swagger 비활성화 일관성 유지 좋습니다.인증 서비스는 특히 민감하므로 운영에서 문서/스키마 노출 차단은 바람직합니다.
aics-admin/src/main/java/kgu/developers/admin/carousel/presentation/CarouselAdminControllerImpl.java (1)
24-24: 관리자 네임스페이스(/api/v1/admin/carousels)로의 변경 적절합니다.리버스 프록시와 보안 경계가 명확해졌습니다.
aics-admin/src/main/java/kgu/developers/admin/user/presentation/UserAdminControllerImpl.java (1)
23-23: 관리자 네임스페이스(/api/v1/admin/users)로의 경로 정비 좋습니다.엔드포인트 경계가 명확해지고, 프록시 라우팅 규칙과의 일관성도 올라갑니다. 클라이언트(관리 콘솔 등) 호출 경로 업데이트만 확인해 주세요.
aics-admin/src/main/java/kgu/developers/admin/lab/presentation/LabAdminControllerImpl.java (1)
26-26: /api/v1/admin/labs 경로 변경 영향 범위 점검 결과
- 구 경로(
/api/v1/labs) 참조
• 리포지터리 전역 검색 결과, API 컨트롤러 매핑 외 별도 리터럴 참조 없음
• aics-api/src/main/java/kgu/developers/api/lab/presentation/LabControllerImpl.java:14 (@RequestMapping("/api/v1/labs"))- 보안 설정
• 컨트롤러별@PreAuthorize("hasRole('ROLE_ADMIN')")적용 중
•HttpSecurity에서 global하게/api/v1/admin/**를 매칭하는antMatchers/mvcMatchers/requestMatchers구문 미발견
⇒ 메서드 보안 활성화 여부 및 추가 인가 규칙 필요 여부 확인 권장- 프록시(Nginx/GW) 설정
• 리포지터리 내 프록시 설정 파일 미발견
⇒ 운영 환경의/api/v1/admin/ → admin 서비스라우팅 정책 확인 필요aics-admin/src/main/java/kgu/developers/admin/about/presentation/AboutAdminControllerImpl.java (1)
25-25: /api/v1/admin/abouts 경로 변경 전후 호출자·보안·프록시 점검 필요경로 변경 자체는 문제가 없으나, 연관된 호출자·인가·프록시 설정 일치 여부를 꼭 확인해 주세요:
- 구 경로(/api/v1/abouts) 참조
• aics-admin 모듈 내에서는 더 이상 발견되지 않음
• aics-api 모듈의 AboutControllerImpl에서만 남아 있으므로, admin 쪽에는 잔여 참조가 없는지 재확인- Spring Security 인가 규칙
•/api/v1/admin/**경로에 대한 antMatchers/mvcMatchers 등 인가 설정이 등록되어 있는지 확인- Nginx/프록시 라우팅
•/api/v1/admin/경로로 요청이 올바르게 전달되도록 proxy_pass 혹은 location 블록에 라우팅이 정의되어 있는지 확인aics-admin/src/main/java/kgu/developers/admin/file/presentation/FileAdminControllerImpl.java (1)
25-25: /api/v1/admin/files 변경 완료 — Nginx 업로드 프록시 설정 검토 필요코드베이스에서
/api/v1/files참조는 모두 제거된 것을 확인했습니다. 운영 환경의 Nginx 설정 파일을 열어 아래 항목을 직접 점검해 주세요:
- client_max_body_size: 업로드 최대 허용 크기
- proxy_request_buffering / proxy_read_timeout: 대용량 파일 및 느린 네트워크 대응
/api/v1/admin/경로가 admin 서비스로 정상 라우팅되는지aics-admin/src/main/java/kgu/developers/admin/professor/presentation/ProfessorAdminControllerImpl.java (1)
24-24: /api/v1/admin/professors 경로 변경 영향 범위 점검 결과
- 구 경로(/api/v1/professors) 참조
• aics-api/src/main/java/kgu/developers/api/professor/presentation/ProfessorControllerImpl.java 에서 여전히/api/v1/professors로 매핑되어 있어, 관리용 경로 변경이 기존 퍼블릭 API에 영향을 주지 않음이 확인되었습니다.- 보안 설정
•antMatchers,mvcMatchers,requestMatchers검색 결과/api/v1/admin/**매칭이 발견되지 않았습니다. 관리용 엔드포인트 접근 제어를 위해 보안 설정에 해당 경로를 추가·검토해 주세요.- Nginx/프록시 설정
• repository 내 파일 검색에서/api/v1/admin관련 라우팅 설정이 탐지되지 않았습니다. 프록시(Nginx 등)에서 admin 경로를 올바르게 라우팅하는지 확인해 주세요.기능상 문제는 없으나, 위 보안 설정과 프록시 라우팅 부분만 보완 후 머지하시길 권장드립니다.
aics-admin/src/main/java/kgu/developers/admin/post/presentation/PostAdminControllerImpl.java (1)
26-28: 인터페이스 중복 매핑 없음 · @PreAuthorize prefix 전략 검토
- 인터페이스(
PostAdminController)에는 별도의@RequestMapping이 없으므로 이중 경로 매핑이 발생하지 않습니다.- 모든 AdminControllerImpl에서
@PreAuthorize("hasRole('ROLE_ADMIN')")만 사용 중이며,hasAuthority(...)는 호출된 곳이 없습니다.Spring Security 기본
ROLE_접두사를 유지한다면
•hasRole('ADMIN')
또는
•hasAuthority('ROLE_ADMIN')
중 하나로 통일해야 합니다.
만약 커스텀으로 접두사를 제거하도록 설정(GrantedAuthorityDefaults등)했다면, 현재 사용 중인hasRole('ROLE_ADMIN')도 정상 동작합니다.확인할 위치:
- Security 설정 클래스(ex.
SecurityConfig.java)에서rolePrefix또는GrantedAuthorityDefaults빈 등록 여부 확인docker/staging/docker-compose.yml (1)
1-4: 스테이징 컴포즈: 프로젝트 이름 고정 및 파일 끝 개행 추가
docker/staging/docker-compose.yml최상단에를 추가해 DB 스택(예:name: aics-stagingdocker-compose-db.yml)과 동일 네트워크(aics-network)에 연결되도록 합니다.- 파일 맨 끝에 빈 줄 한 줄을 추가해 YAMLlint 경고를 해소합니다.
- Nginx 프록시 설정(
/api/v1/admin → aics-admin)을 정의한.conf파일이 저장소에서 확인되지 않아, 실제로 해당 경로를 프록시하도록 설정되어 있는지 직접 검토해 주세요.패치 예:
+name: aics-staging include: - networks.yml - service-application.yml - service-nginx.yml +.github/workflows/staging-build-deploy.yml (2)
54-59: SSH 액션도 태그/커밋 핀 고정 상태 유지 권장.현재
appleboy/ssh-action@v1.1.0은 버전 지정이 되어 있어 양호합니다. 보안 정책상 주기적 갱신 여부만 확인해 주세요.
53-64: 배포 스크립트·이미지 태그 일관성 확인 요청현재
.github/workflows/staging-build-deploy.yml에서 원격 서버로backend/deploy.sh를 실행하도록만 설정되어 있습니다.
이 스크립트가 다음 요건을 충족하는지 확인이 필요합니다. 불일치할 경우 새로운 컨테이너가 기동되지 않을 수 있습니다.확인 사항:
backend/deploy.sh내부에
docker load로 tar 이미지를 로드한 뒤- 동일한 SHA 태그(
aics-*:GITHUB_SHA)로 참조하거나latest등으로 재태깅(docker tag)하는 로직docker-compose up또는docker-compose pull호출 로직- 서버에 배포된
docker-compose.yml(또는 유사 파일)에서
image: aics-admin:…,aics-api:…,aics-auth:…등의 태그가
실제 로드/태깅된 태그와 일치하는지위 검증이 어려운 경우, 직접 해당 파일들을 열어 로직을 검토하거나 아래와 같은 예시 스크립트를 참고해 수동 확인해 주세요.
deploy/staging/deploy.sh (2)
6-15: 전반적 구성은 목적에 부합합니다에어갭 환경에서 tar 로딩 → 기존 컨테이너 down → 새로 up 플로우는 합리적입니다. 위 제안 적용 시 재현성과 내고장성이 더 좋아질 것입니다.
11-15: 경로 확인 및 스크립트 개선 제안
fd실행 결과, 레포에 존재하는docker-compose.yml파일은 다음 경로뿐입니다.
- docker/development/docker-compose.yml
- docker/staging/docker-compose.yml
현재
deploy/staging/deploy.sh에서는$APP_HOME/docker-compose.yml을 사용 중인데, 실제 파일이 있는 경로(docker/staging/docker-compose.yml)와 불일치할 가능성이 높습니다.
아래 예시처럼 파일 존재 여부 검증, 변수 인용,--remove-orphans옵션을 추가하고,COMPOSE_FILE·ENV_FILE경로를 실제 위치로 수정해 주세요.echo "===== Stopping existing containers =====" -COMPOSE_FILE="$APP_HOME/docker-compose.yml" +COMPOSE_FILE="$APP_HOME/docker/staging/docker-compose.yml" +ENV_FILE="$APP_HOME/docker/staging/.env" + +if [[ ! -f "$COMPOSE_FILE" ]]; then + echo "ERROR: Compose file not found: $COMPOSE_FILE" >&2 + exit 1 +fi sudo docker compose -f "$COMPOSE_FILE" down --remove-orphans || true echo "===== Starting containers =====" -if [[ ! -f "$ENV_FILE" ]]; then +if [[ ! -f "$ENV_FILE" ]]; then echo "ERROR: .env file not found: $ENV_FILE" >&2 exit 1 fi sudo docker compose -f "$COMPOSE_FILE" --env-file "$ENV_FILE" up -d --remove-orphans위 경로가 맞는지,
$APP_HOME이 어디를 가리키는지 재확인 후 반영해 주세요.docker/staging/service/service-application.yml (1)
10-10: 스테이징에서 prod 프로필 사용 확인 필요
SPRING_PROFILES_ACTIVE: prod설정으로 Swagger 비활성 등 프로덕션 특성이 적용됩니다. 스테이징에서 API 문서 접근이 차단되어도 문제 없다는 팀 컨센서스가 있는지 확인 바랍니다.Also applies to: 32-32, 54-54
aics-admin/src/main/java/kgu/developers/admin/club/presentation/ClubAdminControllerImpl.java
Show resolved
Hide resolved
...dmin/src/main/java/kgu/developers/admin/comment/presentation/CommentAdminControllerImpl.java
Show resolved
Hide resolved
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Summary
폐쇄망으로 구축된 운영 환경에서 원활한 배포를 위해 스테이징 환경을 유사하게 구축하였습니다.
GitHub Actions와 scp 기반으로 docker image를 압축하여 복사하며, 별도의 deploy 셸 스크립트를 통해 컨테이너를 구동합니다.
Tasks
To Reviewer
보안 상 중요한 파일은 노션에 추가하였습니다