Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 14 additions & 24 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Java CI/CD with Docker

on:
push:
branches: [ "deploy" ]
branches: [ "deploy" ]

jobs:
build-and-push:
Expand Down Expand Up @@ -37,24 +37,14 @@ jobs:
${{ secrets.DOCKER_USERNAME }}/cuk-compasser:latest
${{ secrets.DOCKER_USERNAME }}/cuk-compasser:${{ github.sha }}

# 2. 서버에 배포
deploy:
needs: build-and-push
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Copy docker-compose-prod.yml to EC2
uses: appleboy/scp-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
source: "docker-compose-prod.yml" # 로컬 파일
target: "~/BE" # 서버 목적지

- name: Deploy to EC2
- name: Deploy to EC2 via SSH
uses: appleboy/ssh-action@master
env:
IMAGE_TAG: ${{ github.sha }}
Expand All @@ -63,16 +53,15 @@ jobs:
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
envs: IMAGE_TAG
debug: true
script: |
mkdir -p ~/BE
cd ~/BE

# 네트워크 생성 (네트워크가 존재하지 않을 시)
sudo docker network inspect cuk-compasser-net >/dev/null 2>&1 || \
sudo docker network create cuk-compasser-net

# .env 파일 생성
# 1. [핵심] 깃허브의 모든 최신 파일(promtail-config 등) 강제 동기화
git fetch --all
git reset --hard origin/deploy

# 2. .env 파일 생성 (보안상 필요한 변수들만 주입)
# 기존에 작성하신 echo 방식을 유지하되, 덮어쓰기(>)와 추가(>>)를 구분합니다.
echo "MYSQL_ROOT_PASSWORD=${{ secrets.MYSQL_ROOT_PASSWORD }}" > .env
echo "MYSQL_DATABASE=${{ secrets.MYSQL_DATABASE }}" >> .env
echo "MYSQL_USER=${{ secrets.MYSQL_USER }}" >> .env
Expand All @@ -82,20 +71,21 @@ jobs:
echo "DB_USERNAME=${{ secrets.DB_USERNAME }}" >> .env
echo "DB_PASSWORD=${{ secrets.DB_PASSWORD }}" >> .env
echo "SPRING_PROFILES_ACTIVE=${{ secrets.SPRING_PROFILES_ACTIVE }}" >> .env

echo "AWS_ACCESS_KEY=${{ secrets.AWS_ACCESS_KEY }}" >> .env
echo "AWS_SECRET_KEY=${{ secrets.AWS_SECRET_KEY }}" >> .env
echo "S3_BUCKET_NAME=${{ secrets.S3_BUCKET_NAME }}" >> .env
echo "GF_SECURITY_ADMIN_PASSWORD=${{secrets.GF_SECURITY_ADMIN_PASSWORD}}" >> .env

echo "JWT_SECRET_KEY=${{ secrets.JWT_SECRET_KEY }}" >> .env
echo "KAKAO_CLIENT_ID=${{ secrets.KAKAO_CLIENT_ID }}" >> .env
echo "KAKAO_LOGIN_REDIRECT_URI=${{ secrets.KAKAO_LOGIN_REDIRECT_URI }}" >> .env
echo "KAKAO_REST_API_KEY=${{ secrets.KAKAO_REST_API_KEY }}" >> .env

sudo docker-compose -f docker-compose-prod.yml down --remove-orphans
# 3. 네트워크 생성 확인
sudo docker network inspect cuk-compasser-net >/dev/null 2>&1 || sudo docker network create cuk-compasser-net

# 4. 이미지 풀 및 서비스 재시작
sudo docker pull ${{ secrets.DOCKER_USERNAME }}/cuk-compasser:$IMAGE_TAG

sudo IMAGE_TAG=$IMAGE_TAG docker-compose -f docker-compose-prod.yml up -d --force-recreate

sudo docker image prune -f
# 5. 미사용 이미지 정리
sudo docker image prune -f
30 changes: 26 additions & 4 deletions docker-compose-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,35 @@ services:
- AWS_ACCESS_KEY=${AWS_ACCESS_KEY}
- AWS_SECRET_KEY=${AWS_SECRET_KEY}
- SPRING_PROFILES_ACTIVE=prod
# application.yml의 변수명(${SPRING_DATA_REDIS_HOST})과 일치시킴
- SPRING_DATA_REDIS_HOST=redis
- SPRING_DATA_REDIS_PORT=6379
# JWT 및 카카오 설정 (환경변수로 주입)
- JWT_SECRET_KEY=${JWT_SECRET_KEY}
- KAKAO_CLIENT_ID=${KAKAO_CLIENT_ID}
- KAKAO_LOGIN_REDIRECT_URI=${KAKAO_LOGIN_REDIRECT_URI}
- KAKAO_LOCAL_BASE_URL=https://dapi.kakao.com
- KAKAO_REST_API_KEY=${KAKAO_REST_API_KEY}
depends_on:
mysql-db:
condition: service_healthy
redis:
condition: service_started

logging:
driver: loki
driver: "json-file"
options:
loki-url: "http://loki:3100/loki/api/v1/push"
loki-external-labels: "job=spring-boot"
max-size: "10m"
max-file: "3"
networks:
- cuk-compasser-net

redis:
image: redis:latest
container_name: redis
restart: always
ports:
- "6379:6379"
networks:
- cuk-compasser-net

Expand Down Expand Up @@ -97,12 +118,13 @@ services:
restart: always
volumes:
- ./promtail/promtail-config.yml:/etc/promtail/config.yml
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/log:/var/log
command: -config.file=/etc/promtail/config.yml
networks:
- cuk-compasser-net

# AWS 서버 디스크에 생성될 실제 저장 공간 정의
volumes:
mysql_data:
prometheus_data:
Expand Down
20 changes: 19 additions & 1 deletion promtail/promtail-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,29 @@ clients:
- url: http://loki:3100/loki/api/v1/push

scrape_configs:
# 1. 기존 시스템 로그 (EC2 자체 로그)
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
application: compasser-api
__path__: /var/log/*.log
__path__: /var/log/*.log

# 2. 도커 컨테이너 로그 (스프링 부트 로그 포함)
- job_name: docker_logs
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
relabel_configs:
- source_labels: [__meta_docker_container_id]
target_label: __path__
replacement: /var/lib/docker/containers/$1/*-json.log
- source_labels: ['__meta_docker_container_name']
regex: '/(.*)'
target_label: 'container_name'
- source_labels: ['__meta_docker_container_name']
regex: '/cuk-compasser-service'
target_label: 'job'
replacement: 'spring-boot'
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package Comprehensive_Design_Project.CUK_Compasser.global.security.config;

import Comprehensive_Design_Project.CUK_Compasser.global.security.filter.JWTAuthenticationFilter;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -14,6 +16,7 @@
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;

@Configuration
@RequiredArgsConstructor
Expand All @@ -39,7 +42,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
"/auth/login/**",
"/swagger-ui/**",
"/swagger-ui.html",
"/v3/api-docs/**"
"/v3/api-docs/**",
"/actuator/**"
).permitAll()
.requestMatchers("/stores/**").authenticated()
.requestMatchers("/owners/**").authenticated()
Expand All @@ -60,4 +64,5 @@ public AuthenticationManager authenticationManager(AuthenticationConfiguration c
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,14 @@ private void handleExpiredAccessToken (HttpServletRequest request, HttpServletRe
throw new GeneralException(GeneralErrorCode.RT_NOT_FOUND);
}
}

@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
String path = request.getRequestURI();
// 이 경로들은 필터 로직을 아예 실행하지 않음
return path.startsWith("/actuator")
|| path.startsWith("/swagger-ui")
|| path.startsWith("/v3/api-docs")
|| path.startsWith("/favicon.ico");
}
}
6 changes: 6 additions & 0 deletions src/main/resources/application-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ spring:
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
pool-name: HikariPool-1

jpa:
database-platform: org.hibernate.dialect.MySQLDialect
Expand Down Expand Up @@ -69,6 +70,11 @@ jwt:
secret:
key: ${JWT_SECRET_KEY}

kakao:
local:
base-url: https://dapi.kakao.com
rest-api-key: ${KAKAO_REST_API_KEY}

management:
endpoints:
web:
Expand Down
Loading