사내 IIS 서버 CI/CD 구축기
배경
사내 원격 IIS 서버에 처음으로 Gitlab CI를 도입해 CI/CD 파이프라인을 구축하며,
참고할 수 있던 소스가 너무 적고 산재되어있어 누군가에겐 도움이 될까 싶어
참고했었던 링크 및 마주쳤던 오류 사항을 정리해보았습니다.
개발환경
Visual Studio 2019
Asp.net 5.0
React 17 (Vite)
시스템 확장을 고려해 Vite 번들링 툴을 선택하여 Asp.net > ClientApp 프로젝트를 별도로 구성.
배포환경
사내 원격 IIS 서버
문제점
(1) 기존 수동 배포 프로세스의 번거로움
소스코드 수정 → commit → 솔루션 정리 → 빌드 → 게시 (대규모 프로젝트의 경우 대기시간 김) → 기존 파일 수동 백업 → 운영 중인 풀 중단 → 게시된 파일 붙여넣기 → 풀 재 구동
(2) 롤백이 어려움
(3) IIS 동시 접속 제한
(4) 배포 로그 적재 및 작업 추적이 불가함
Gitlab-CI 도입 Benefit
(1) 배포 로그 기록이 가능하여 롤백이 수월함
(2) deploy 브랜치 머지 || 버튼 클릭하나만으로 기존 수동 배포 프로세스를 자동화할 수 있음
가격
사내에선 이미 Gitlab Premium 사용하고 있어서 CI/CD 제한 없음
Complete Guide
(1) 배포환경에 Gitlab Runner 설치 및 등록
다음 두 링크를 참고하여 Gitlab-CI를 구성합니다.
1. Runner 등록 가이드
How To Configure GitLab Runner On Windows Machine (From Scratch)
2. . Runner 등록 이후 가이드
GitLab CI/CD with .Net Framework
생성된 config.toml 파일에 shell = “powershell” 로 변경
위 포스팅에서 다룬 내용 외 운영 서버에 추가로 설치할 파일입니다.
- build tools for visual studio 2019
- nuget.exe: 하단 yml 파일에 등록할 nuget_path 위치
- npm: 설치 및 환경 변수 등록 요
- gitlab-runner: 소스를 받고 빌드할 경로에 구성
- git: 설치 및 환경 변수 등록 요. 이후 gitlab token으로 로그인 시도.
운영 환경에 맞게 방화벽 허용 해주어야 할 도메인입니다.
- api.nuget.org
- registry.npmjs.org
- github.com
- 사내 깃랩 서버
(2) gitlab-ci.yml 파일 최종 구성
variables:
NUGET_PATH: 'C:\Users\...\Tools\Nuget\nuget.exe' # nuget 경로
MSBUILD_PATH: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\MSBuild.exe' # msbuild 경로
before_script:
- CHCP 65001 # output log encoding
stages:
- build # build 스테이지
- deploy # deploy 스테이지
build_job:
stage: build
only:
- deploy # deploy 브랜치에서만 실행
script:
- echo '==== Build ===='
- cd ./SalesMng
- '& "$env:NUGET_PATH" restore <<솔루션파일명>>.sln' # NuGet 패키지 설치
- echo 'Pakages successfully installed.'
- '& "$env:MSBUILD_PATH" <<솔루션파일명>>.sln -p:Configuration=Release -clp:ErrorsOnly -t:build /restore -m' # MSBuild를 사용하여 프로젝트를 빌드/ Configuration: release로 설정 / ErrorsOnly: 오류메시지만 출력
- echo 'Build initiated'
- '& "$env:MSBUILD_PATH" .\<<솔루션파일명>>\<<솔루션파일명>>.csproj -p:DeployOnBuild=true -p:Configuration=Release -P:PublishProfile=FolderProfile.pubxml' # MSBuild를 사용하여 프로젝트를 배포 / DeployOnBuild: 빌드 시 바로 배포 / PublishProfile: 배포 프로필 설정
- echo 'Build completed'
artifacts:
expire_in: 2 days # 아티팩트의 유효기간을 2일로 설정
paths:
- '.\<<솔루션파일명>>\<<솔루션파일명>>\obj\Release\net5.0\PubTmp\Out\' # 빌드된 프로젝트의 배포 결과물(아티팩트) 경로
deploy_job:
stage: deploy
only:
- deploy
script:
- echo '==== Deploy ===='
- echo 'Stop App pool'
- C:\Windows\System32\inetsrv\appcmd stop apppool /apppool.name:"<<중단할 풀 명>>" # 앱 풀 중단
- echo 'File copy initiated'
- 'xcopy /y /s ".\SalesMng\SalesMng\obj\Release\net5.0\PubTmp\Out\*.*" "C:\Website\<<빌드 파일 경로>>"' # 아티팩트 파일 배포 경로로 복사
- echo 'File copy completed'
- echo 'Restart App pool'
- C:\Windows\System32\inetsrv\appcmd start apppool /apppool.name:"<<중단할 풀 명>>" # 앱 풀 재시작
dependencies:
- build_job
(+) yml 파일 실행 시 발생 가능 오류
- encoding 오류
before_script: CHCP 65001 # output log encoding
- 패키지 <<패키지명>>을 찾을 수 없습니다. NuGet 복원 이후 삭제되었을 수 있습니다.
- nuget 캐시 삭제
- nuget 문제
다음처럼 솔루션 파일을 지목:'& "$env:NUGET_PATH" restore <<솔루션파일명>>.sln' # NuGet 패키지 설치
- 빌드 파일에 ClientApp가 누락되던 이슈
- FolderProfile.pubxml 내 Publish 경로 변경
<?xml version="1.0" encoding="utf-8"?> <!-- https://go.microsoft.com/fwlink/?LinkID=208121. --> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <DeleteExistingFiles>False</DeleteExistingFiles> <ExcludeApp_Data>False</ExcludeApp_Data> <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish> <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration> <LastUsedPlatform>Any CPU</LastUsedPlatform> <PublishProvider>FileSystem</PublishProvider> <PublishUrl>bin\Release\net5.0\</PublishUrl> <!--<PublishUrl>bin\Release\net5.0\publish\</PublishUrl>--> <WebPublishMethod>FileSystem</WebPublishMethod> </PropertyGroup> </Project>
- artifact 경로 재설정
build_job 실행 시 copy되는 경로를 찾아 artifacts paths 정의
artifacts: expire_in: 2 days # 아티팩트의 유효기간을 2일로 설정 paths: - '.\SalesMng\SalesMng\obj\Release\net5.0\PubTmp\Out\' # 빌드된 프로젝트의 배포 결과물(아티팩트) 경로
- FolderProfile.pubxml 내 Publish 경로 변경
- (npm install 오류) Python 때문에 npm install (node-sass) 설치 실패 오류
node-sass는 node-gyp를 쓰고 node-gyp는 python을 사용하기 때문에 운영서버에 python 설치가 필요함.- Python global path 설정 (X)
npm install --python=C:\Users\kkjuyeon\AppData\Local\Programs\Python\Python311\python.exe
- window build tool 설치 (X)
npm install --global --production windows-build-tools
- node-sass 삭제
삭제 후에도 scss → css 정상 컴파일 되어 해당 패키지를 삭제하여 해결함.
- Python global path 설정 (X)
- powershell에서 .git을 못찾는 오류
깃 설치 후 git 명령어 powershell에서 잘 실행되지만 .git을 못찾던 문제.환경 변수 세 경로 (C:\Program Files\Git\cmd, C:\Program Files\Git\bin, C:\Program Files\Git\bin\git.exe ) 등록 후, 적용을 위해 운영 서버 재부팅이 필요함. echo $env:PATH 로 점검.
Fetching changes with git depth set to 20... & : 'git' ��� cmdlet, �Լ�, ��ũ��Ʈ ���� �Ǵ� ������ �� �ִ� ���α� �̸����� �νĵ��� �ʽ��ϴ�. �̸��� ��Ȯ���� Ȯ���ϰ� ���ΰ� ���Ե� ���� ���ΰ� �ùٸ��� ������ ���� �ٽ� �õ��Ͻʽÿ�. ��ġ ��:273 ����:3 + & "git" 'config' '-f' 'C:\Users\kkjuyeon\Downloads\Gitlab-Runner\buil ... + ~~~~~ + CategoryInfo : ObjectNotFound: (git:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException ERROR: Job failed: exit status 1
- 풀이 다른 프로세스에 의해 잠겨있는 이슈 (Sharing violation)
앱 중단 후 restart 해주는 스크립트를 추가해야한다.$ xcopy /y /s ".\SalesMng\SalesMng\obj\Release\net5.0\PubTmp\Out\*.*" "C:\Website\SalesMng" .\SalesMng\SalesMng\obj\Release\net5.0\PubTmp\Out\appsettings.Development.json .\SalesMng\SalesMng\obj\Release\net5.0\PubTmp\Out\appsettings.json .\SalesMng\SalesMng\obj\Release\net5.0\PubTmp\Out\f_crypto_cshap.dll .\SalesMng\SalesMng\obj\Release\net5.0\PubTmp\Out\Interop.WORKPACKAGERV3Lib.dll .\SalesMng\SalesMng\obj\Release\net5.0\PubTmp\Out\Microsoft.AspNetCore.NodeServices.dll .\SalesMng\SalesMng\obj\Release\net5.0\PubTmp\Out\Microsoft.AspNetCore.SpaServices.dll Sharing violation ERROR: Job failed: exit status 4
- C:\Windows\System32\inetsrv\appcmd stop apppool /apppool.name:"SalesMng" # 앱 풀 중단 - C:\Windows\System32\inetsrv\appcmd start apppool /apppool.name:"SalesMng" # 앱 풀 재시작
그 외 참고 소스
사내 iis 서버 Azure Devops 도입기 Deploying Code from GitLab to IIS via Azure DevOps: A Step-by-Step Guide
React + Nodejs A React + IIS Website GitLab CI/CD YAML Example