이전글
https://jwinjection.tistory.com/245
nginx활용한 CICD 구현(1)
배포시 문제점새로운 버전을 배포할 시배포하는 시간동안 서비스를 사용할 수 없게되는 문제가 생긴다.이를 해결하기 위해서 무중단 배포를 하는것이다. 또한 새로운 버전을 개발하고 이를 직
jwinjection.tistory.com
1. 윈도우 배치파일작성
8080에 A웹서버
8778에 B웹서버 를 실행시킨다음
실제 서비스하는 포트두개(8080,8778)를 배치파일 상단에 적어준다
코드로직을 간단히 설명하자면
8080으로 작성되어있으면 8778로 수정
또는
8778로 작성되어있으면 8080으로 수정한 후
reload 명령어까지 실행해준다.
@echo off
setlocal enabledelayedexpansion
:: Set the variables
set "port1=8080"
set "port2=8778"
set "nginx_exe_path=C:\nginx-1.24.0\nginx.exe"
:: Derive the path to nginx.conf from nginx.exe path
for %%I in ("%nginx_exe_path%") do set "nginx_conf_path=%%~dpIconf\nginx.conf"
:: Debug output to check the configuration file path
echo nginx_conf_path is %nginx_conf_path%
:: Read the file content and determine the current port
set "current_port="
for /f "tokens=*" %%A in ('type "%nginx_conf_path%"') do (
set "line=%%A"
echo Checking line: !line!
echo !line! | findstr /c:"server localhost:%port1%;" >nul && set "current_port=%port1%"
echo !line! | findstr /c:"server localhost:%port2%;" >nul && set "current_port=%port2%"
)
:: Debug output to check the current port
echo current_port is %current_port%
:: Check if a valid port was found
if "%current_port%"=="" (
echo No valid port found in %nginx_conf_path%.
exit /b 1
)
:: Set the new port based on the current port
if "%current_port%"=="%port1%" (
set "new_port=%port2%"
) else (
set "new_port=%port1%"
)
:: Replace the port in the file
(for /f "tokens=*" %%A in ('type "%nginx_conf_path%"') do (
set "line=%%A"
set "line=!line:server localhost:%current_port%=server localhost:%new_port%!"
echo !line!
)) > temp.conf
:: Replace the original file with the updated file
move /y temp.conf "%nginx_conf_path%"
:: Reload Nginx to apply changes
"%nginx_exe_path%" -s reload
echo Port changed from %current_port% to %new_port% in %nginx_conf_path% and Nginx reloaded.
실제 무중단배포 작동모습
2. 자동배포
이제 무중단 배포는 알았으니
자동배포만 남았다.
위에 예를들면
현재 내가 8080에 최신본을 적용하고
배치프로그램을 이용해서 8778 => 8080으로 업데이트를 했다고 가정하자
그럼 시간이 지나 8080보다 더 최신버전을 적용하려고한다면
당연 8778에 적용해야 할 것이다.
이렇게 항상 번갈아가며 적용해야하는데
그때마다 개발자가 현재 어떤포트에 최신본이 적용되어있는지 일일이 찾은다음 적용하려한다면
너무 귀찮은 일이 될것이다.
그래서 이 과정을 자동화해보겠다.
로직은 단순하다.
- 현재 작동중인 포트를 conf파일에서 추출해온다
- GIT으로 최신판을 pull 받아온다
- mvn clean package 명렁어를 사용해서 war파일을 생성한다
- war파일을 현재 작동중이지 않은 포트에 배포시킨다
- 최신버전 테스트(생략)
- nginx config 파일을 열어 최신버전이 담긴 작동중이지 않은포트번호로 수정한다
- reload한다
3. CICD배치파일 코드
@echo off
setlocal enabledelayedexpansion
:: Set the variables
set "port1=포트1"
set "port2=포트2"
:: Define the base path for nginx
set "nginx_base_path=C:\nginx-1.24.0"
:: Define the paths for nginx executable and configuration directory
set "nginx_exe_path=%nginx_base_path%\nginx.exe"
set "nginx_conf_dir=%nginx_base_path%\conf"
set "nginx_conf_path=%nginx_conf_dir%\nginx.conf"
:: Set project-specific variables
set "PROJECT_NAME=프로젝트폴더명"
set "SERVER_NAME_1=서버이름"
set "SERVER_NAME_2=서버이름_1"
set "SERVICE_NAME_1=Tomcat8_서비스명"
set "SERVICE_NAME_2=Tomcat8_서버스명_1"
:: Debug output to check the configuration file path
echo nginx_conf_path is %nginx_conf_path%
:: Initialize current port variable
set "current_port="
:: Read the nginx.conf file and extract the port from 'server localhost:' only
for /f "tokens=*" %%A in ('findstr /r /c:"server localhost:[0-9]*;" "%nginx_conf_path%"') do (
set "line=%%A"
:: Extract port number from the line
for /f "tokens=2 delims=:" %%B in ("!line!") do (
set "port_candidate=%%B"
:: Remove any trailing characters such as ';'
for /f "tokens=1 delims=; " %%C in ("!port_candidate!") do (
set "current_port=%%C"
:: Debug output to check the extracted port
echo Extracted port: !current_port!
)
)
)
:: Debug output to check final extracted port
echo Final extracted port: !current_port!
:: ----------------------------------------------------------------------------------------------------------------------
:: ----------------------------------------------------------------------------------------------------------------------
:: start deployment
:: Check if a valid port was found and execute the corresponding file
if "!current_port!"=="!port1!" (
echo 현재 포트 1이 작동중이니 2에 배포합니다
set "SERVER_NAME=!SERVER_NAME_2!"
set "SERVICE_NAME=!SERVICE_NAME_2!"
cd /d C:\Project\!PROJECT_NAME!
git checkout master
git pull
git checkout super_master
git merge master
git push
call mvn clean package
echo Maven build completed.
echo !SERVICE_NAME!
sc stop !SERVICE_NAME!
timeout /t 5 /nobreak > nul
cd target
ren !PROJECT_NAME!-1.0.0.war ROOT.war
echo "프로젝트 네임 !PROJECT_NAME!"
rmdir /s /q C:\SERVICE\apache-tomcat\8.5.57-!SERVER_NAME!\webapps\ROOT 2>nul
move /Y ROOT.war C:\SERVICE\apache-tomcat\8.5.57-!SERVER_NAME!\webapps
rmdir /s /q C:\SERVICE\apache-tomcat\8.5.57-!SERVER_NAME!\work
sc start !SERVICE_NAME!
) else (
echo 현재 포트 2가 작동중이니 1에 배포합니다
set "SERVER_NAME=!SERVER_NAME_1!"
set "SERVICE_NAME=!SERVICE_NAME_1!"
cd /d C:\Project\!PROJECT_NAME!
git checkout master
git pull
git checkout super_master
git merge master
git push
call mvn clean package
echo Maven build completed.
echo !SERVICE_NAME!
sc stop !SERVICE_NAME!
timeout /t 5 /nobreak > nul
cd target
echo "프로젝트 네임 !PROJECT_NAME!"
ren !PROJECT_NAME!-1.0.0.war ROOT.war
rmdir /s /q C:\SERVICE\apache-tomcat\8.5.57-!SERVER_NAME!\webapps\ROOT 2>nul
move /Y ROOT.war C:\SERVICE\apache-tomcat\8.5.57-!SERVER_NAME!\webapps
rmdir /s /q C:\SERVICE\apache-tomcat\8.5.57-!SERVER_NAME!\work
sc start !SERVICE_NAME!
)
:: End the script
timeout /t 20 /nobreak > nul
:: ----------------------------------------------------------------------------------------------------------------------
:: ----------------------------------------------------------------------------------------------------------------------
:: reverse proxy auto switch
:: Read the file content and determine the current port
cd /d "%nginx_base_path%"
set "current_port="
for /f "tokens=*" %%A in ('type "%nginx_conf_path%"') do (
set "line=%%A"
echo Checking line: !line!
echo !line! | findstr /c:"server localhost:%port1%;" >nul && set "current_port=%port1%"
echo !line! | findstr /c:"server localhost:%port2%;" >nul && set "current_port=%port2%"
)
:: Debug output to check the current port
echo current_port is %current_port%
:: Check if a valid port was found
if "%current_port%"=="" (
echo No valid port found in %nginx_conf_path%.
exit /b 1
)
:: Set the new port based on the current port
if "%current_port%"=="%port1%" (
set "new_port=%port2%"
) else (
set "new_port=%port1%"
)
:: Replace the port in the file
(for /f "tokens=*" %%A in ('type "%nginx_conf_path%"') do (
set "line=%%A"
set "line=!line:server localhost:%current_port%=server localhost:%new_port%!"
echo !line!
)) > temp.conf
:: Replace the original file with the updated file
move /y temp.conf "%nginx_conf_path%"
:: Reload Nginx to apply changes
"%nginx_exe_path%" -s reload
echo Port changed from %current_port% to %new_port% in %nginx_conf_path% and Nginx reloaded.
pause
배치파일을 실행하면
Git을 통해 최신파일을 불러온 후
최신버전을 배포한다.
이후 nginx conf 파일에 설정된 포트번호를
자동으로 최신버전의 포트로 수정한다.
nginx가상포트만 방화벽으로 열고
실제 8080 8778 과같은 실제 배포된 서비스포트는 방화벽에 등록하면 안된다.
'DevOps > 🛠️ CICD' 카테고리의 다른 글
CICD | Webhook을 이용한 Blue-Green 배포 구현 (2) | 2024.10.05 |
---|---|
Jenkins | GitLab webhook설정 (1) | 2024.10.01 |
DuckDNS로 무료 도메인 등록하기 (0) | 2024.10.01 |
윈도우환경에서 nginx활용한 초간단 CICD 구현(1) (1) | 2024.09.05 |
리버스 프록시란? (0) | 2024.09.05 |