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
94 changes: 0 additions & 94 deletions .github/workflows/cicdDeploy.yml

This file was deleted.

69 changes: 66 additions & 3 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,29 @@ jobs:
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/nginx

- name: set target IP
run: |
STATUS=$(curl -o /dev/null -w "%{http_code}" "http://${{ secrets.EC2_HOST }}/actuator/health")
echo $STATUS
if [ $STATUS = 200 ]; then
CURRENT_UPSTREAM=$(curl -s "http://${{ secrets.EC2_HOST }}/env")
else
CURRENT_UPSTREAM=green
fi
echo CURRENT_UPSTREAM=$CURRENT_UPSTREAM >> $GITHUB_ENV
if [ $CURRENT_UPSTREAM = blue ]; then
echo "CURRENT_PORT=8080" >> $GITHUB_ENV
echo "STOPPED_PORT=8081" >> $GITHUB_ENV
echo "TARGET_UPSTREAM=green" >> $GITHUB_ENV
elif [ $CURRENT_UPSTREAM = green ]; then
echo "CURRENT_PORT=8081" >> $GITHUB_ENV
echo "STOPPED_PORT=8080" >> $GITHUB_ENV
echo "TARGET_UPSTREAM=blue" >> $GITHUB_ENV
else
echo "error"
exit 1
fi

# ssh 접근 후 docker 이미지 pull 및 컨테이너 재시작
- name: executing remote ssh commands using password
uses: appleboy/ssh-action@master
Expand All @@ -85,10 +108,50 @@ jobs:
echo "${{ secrets.ENV }}" | sudo tee .env > /dev/null

sudo curl -o docker-compose.yml https://raw.githubusercontent.com/ewha-exhibition/Backend/main/docker-compose.yml
sudo curl -o docker-compose-blue.yml https://raw.githubusercontent.com/ewha-exhibition/Backend/main/docker-compose-blue.yml
sudo curl -o docker-compose-green.yml https://raw.githubusercontent.com/ewha-exhibition/Backend/main/docker-compose-green.yml

sudo chmod 666 /var/run/docker.sock
sudo docker rm -f $(docker ps -qa)

sudo docker pull ${{ secrets.DOCKER_USERNAME }}/backend
sudo docker pull ${{ secrets.DOCKER_USERNAME }}/nginx
docker compose -f docker-compose.yml --env-file .env up -d
docker compose -f docker-compose-${{env.TARGET_UPSTREAM}}.yml --env-file .env up -d
docker image prune -f

- name: Check deploy server URL
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_KEY }}
script: |
set -e
for i in {1..10}; do
echo "[$i] health check..."
if curl -f http://localhost:${{ env.STOPPED_PORT }}/actuator/health > /dev/null 2>&1; then
echo "health check success"
exit 0
fi
echo "health check failed, retrying in 5s..."
sleep 5
done
echo "health check failed after 10 attempts"
exit 1

- name: Change nginx upstream
uses: appleboy/ssh-action@master
with:
username: ubuntu
host: ${{ secrets.EC2_HOST }}
key: ${{ secrets.EC2_KEY }}
script: |
sudo docker exec -i nginx bash -c 'echo "set \$service_url ${{ env.TARGET_UPSTREAM }};" > /etc/nginx/conf.d/service-env.inc && nginx -s reload'

- name: Stop current server
uses: appleboy/ssh-action@master
with:
username: ubuntu
host: ${{ secrets.EC2_HOST }}
key: ${{ secrets.EC2_KEY }}
script: |
sudo docker stop ${{env.CURRENT_UPSTREAM}}
sudo docker rm ${{env.CURRENT_UPSTREAM}}
10 changes: 8 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM eclipse-temurin:17-jdk
WORKDIR /app
# (중요) cgroup 리소스 감지 비활성화
ENV JAVA_TOOL_OPTIONS="-XX:-UseContainerSupport"

Expand All @@ -8,7 +9,12 @@ ENV SPRING_AUTOCONFIGURE_EXCLUDE="org.springframework.boot.actuate.autoconfigure
# (중요) ProcessorMetrics 바인더 비활성화
ENV MANAGEMENT_METRICS_BINDERS_PROCESSOR_ENABLED="false"

WORKDIR /app

Comment on lines +12 to +13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

WORKDIR /app 명령어가 2번 라인에서 이미 선언되었습니다. 중복된 선언이므로 이 라인들과 이어지는 빈 줄은 삭제하는 것이 좋습니다. 코드 가독성과 유지보수성을 높일 수 있습니다.

EXPOSE 80
ARG JAR_FILE=/build/libs/*.jar
ARG JAR_FILE=build/libs/*.jar
ARG PROFILES
ARG ENV
Comment on lines +16 to +17
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

ARG PROFILESARG ENV 빌드 인자가 선언되었지만 Dockerfile 내에서 사용되지 않고 있습니다. docker-compose 파일에서 environmentPROFILESENV를 설정하고 있으므로, 빌드 인자인 ARG는 혼동을 줄 수 있어 삭제하는 것이 좋습니다. 런타임에 필요한 값은 ENTRYPOINT에서 환경 변수로 처리하는 것이 올바른 접근입니다.

COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","-Duser.timezone=Asia/Seoul","-Dspring.profiles.active=prod","/app.jar"]

ENTRYPOINT ["java","-jar","-Duser.timezone=Asia/Seoul","-Dspring.profiles.active=prod","/app/app.jar"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

ENTRYPOINTspring.profiles.activeprod로 하드코딩되어 있어 docker-compose에서 설정한 blue 또는 green 프로필이 적용되지 않습니다. 이로 인해 블루/그린 배포가 의도대로 동작하지 않습니다.

docker-compose에서 설정한 PROFILES 환경 변수를 사용하도록 ENTRYPOINT를 수정해야 합니다. exec 형식은 쉘 변수 치환을 지원하지 않으므로, /bin/sh -c를 통해 쉘에서 환경 변수를 읽어와 실행하도록 변경해야 합니다.

ENTRYPOINT ["/bin/sh", "-c", "java -jar -Duser.timezone=Asia/Seoul -Dspring.profiles.active=${PROFILES} /app/app.jar"]

44 changes: 35 additions & 9 deletions config/nginx/default.conf
Original file line number Diff line number Diff line change
@@ -1,12 +1,38 @@
server {
listen 80;
listen [::]:80;
upstream blue {
server blue:8080;
}

upstream green {
server green:8080;
}

location / {
proxy_set_header Host $host;
proxy_pass http://backend:8080/;
proxy_read_timeout 90;
server {
listen 80;
listen [::]:80;

include /etc/nginx/conf.d/service-env.inc;

## try_files $uri $uri/ =404;
location = /env {
default_type text/plain;
return 200 "service_url";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

/env 경로의 return 지시어가 $service_url 변수의 값을 반환하는 대신 "service_url"이라는 문자열을 그대로 반환하고 있습니다. 현재 활성화된 서비스(blue/green)를 확인하려는 의도였다면, 변수 값을 반환하도록 수정해야 합니다.

	return 200 "$service_url";

}
}

location / {
proxy_pass http://$service_url;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;

root /usr/share/nginx/html;
index index.html index.htm;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}



19 changes: 19 additions & 0 deletions docker-compose-blue.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: '3.8'

services:
blue:
image: nokmaster/backend
container_name: blue
ports:
- "8080:8080"
env_file:
- .env
environment:
- PROFILES=blue
- ENV=blue
networks:
- nok-network

networks:
nok-network:
external: true
19 changes: 19 additions & 0 deletions docker-compose-green.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: '3.8'

services:
green:
image: nokmaster/backend
container_name: green
ports:
- "8081:8080"
env_file:
- .env
environment:
- PROFILES=green
- ENV=green
networks:
- nok-network

networks:
nok-network:
external: true
25 changes: 11 additions & 14 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
version: "3"

version: '3.8'
services:
backend:
image: nokmaster/backend
container_name: backend
hostname: backend
env_file:
- .env
expose:
- "8080"

nginx:
image: nokmaster/nginx
depends_on:
- backend
container_name: nginx
restart: always
ports:
- "80:80"
- "80:80"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
networks:
- nok-network

networks:
nok-network:
name: nok-network
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public PasswordEncoder passwordEncoder() {
};

private final String[] ActuatorPatterns = {
"/actuator/health"
"/actuator/health", "/env"
};

private final String[] GetPermittedPatterns = {
Expand Down
34 changes: 29 additions & 5 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ spring:
max-file-size: 10MB
max-request-size: 10MB
profiles:
active: prod
active: blue
group:
local: local
blue: blue, prod
green: green, prod

security:
oauth2:
client:
Expand Down Expand Up @@ -67,7 +72,26 @@ logging:
org.hibernate.orm.jdbc.bind: trace
com.zaxxer.hikari: DEBUG

app:
cookie:
secure: false
same-site: Lax
---
spring:
config:
activate:
on-profile: blue

server:
port: 8080
serverAddress: \${SERVER_PROD_URL}

serverName: blue_server
---
spring:
config:
activate:
on-profile: green

server:
port: 8080
serverAddress: \${SERVER_PROD_URL}

serverName: green_server
---
Loading