이 가이드는 Ubuntu 22.04 환경에서 Jenkins를 설치하고, .NET 프로젝트의 CI/CD 파이프라인을 구축하는 전 과정을 다룹니다.
1. 환경 준비 및 기본 설정
1.1 시스템 업데이트
sudo apt update && sudo apt upgrade -y
1.2 SSH 서버 설정 (원격 접속용)
# SSH 서버 설치
sudo apt install openssh-server -y
# SSH 서비스 시작 및 자동 시작 설정
sudo systemctl start ssh
sudo systemctl enable ssh
# SSH 서비스 상태 확인
sudo systemctl status ssh
1.3 방화벽 설정
# UFW 방화벽 활성화
sudo ufw enable
# SSH 포트 허용 (기본 22번 포트)
sudo ufw allow 22/tcp
# Jenkins 웹 포트 허용 (8080)
sudo ufw allow 8080/tcp
# 애플리케이션 포트 허용 (예: 5117)
sudo ufw allow 5117/tcp
# 방화벽 상태 확인
sudo ufw status
⋇iptime에서 지원하는 DDNS 기능을 사용할 경우 포트포워딩을 별도로 설정해 주어야합니다.
2. Jenkins 설치 및 초기 설정
2.1 Java 설치 (Jenkins 필수 요구사항)
# OpenJDK 17 설치
sudo apt install openjdk-17-jdk -y
# Java 버전 확인
java -version
# JAVA_HOME 환경변수 설정
echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' >> ~/.bashrc
echo 'export PATH=$PATH:$JAVA_HOME/bin' >> ~/.bashrc
source ~/.bashrc
2.2 Jenkins 저장소 추가 및 설치
단계 1: Jenkins GPG 키 다운로드 및 추가
# Jenkins 공식 보안 키를 다운로드하여 시스템에 추가
curl -fsSL https://pkg.jenkins.io/debian/jenkins.io-2023.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
GPG 키? 패키지가 진짜 Jenkins에서 만든 것인지 확인하는 디지털 서명입니다. 가짜 패키지 설치를 방지하기 위함.
명령어 설명:
- curl -fsSL: Jenkins 웹사이트에서 보안 키 파일을 다운로드
- sudo tee: 다운로드한 키를 시스템 보안 키 저장소에 저장
- /usr/share/keyrings/: Ubuntu에서 패키지 보안 키를 저장하는 표준 위치
단계 2: Jenkins 저장소를 시스템에 추가
# Jenkins 패키지 저장소를 APT 소스 목록에 추가
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian binary/" | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
단계 3: 패키지 목록 업데이트
# 새로 추가된 Jenkins 저장소를 포함하여 패키지 목록 업데이트
sudo apt update
단계 4: Jenkins 설치
# Jenkins 패키지 설치
sudo apt install jenkins -y
단계 5: Jenkins 서비스 설정
# Jenkins 서비스 시작
sudo systemctl start jenkins
# 시스템 부팅 시 Jenkins 자동 시작 설정
sudo systemctl enable jenkins
# Jenkins 서비스 상태 확인
sudo systemctl status jenkins
설치 성공 확인:
- sudo systemctl status jenkins 명령어 실행 시 Active: active (running) 상태여야 함
- 만약 실패했다면 sudo journalctl -u jenkins로 로그 확인
2.3 Jenkins 초기 설정
# Jenkins 초기 관리자 비밀번호 확인
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
웹 브라우저에서 http://[서버IP]:8080에 접속하여:
- 위에서 확인한 초기 비밀번호 입력
- "Install suggested plugins" 선택 (권장)
- 관리자 계정 생성
- Jenkins URL 설정
3. .NET 개발 환경 구축
3.1 .NET SDK 설치
# Microsoft 패키지 저장소 추가
wget https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
# .NET SDK 설치
sudo apt update
sudo apt install -y dotnet-sdk-8.0
# 설치 확인
dotnet --version
3.2 Git 설정
# Git 설치 (보통 이미 설치되어 있음)
sudo apt install git -y
# Git 사용자 정보 설정 (사용자)
sudo -u jenkins git config --global user.name "사용자 이름"
sudo -u jenkins git config --global user.email "이메일"
4. systemd 서비스 설정
4.1 애플리케이션용 systemd 서비스 생성
#.Net 서비스 파일 생성
sudo nano /etc/systemd/system/{프로젝트명}.service
서비스 파일 내용
[Unit]
Description="프로젝트명" Service
After=network.target
[Service]
Type=simple
User=jenkins
Group=jenkins
#WorkingDirectory=/var/lib/jenkins/deployments/프로젝트명
WorkingDirectory="프로젝트 빌드파일 위치"
# 환경변수
Environment=ASPNETCORE_ENVIRONMENT=Development
Environment=ASPNETCORE_URLS=http://0.0.0.0:5117
#ExecStart=/usr/bin/dotnet 프로젝트.dll
ExecStart="프로젝트 실행파일(.dll)"
Restart=always
RestartSec=5
KillMode=mixed
KillSignal=SIGINT
[Install]
WantedBy=multi-user.target
4.2 환경변수 파일 생성 (민감한 정보 보호)
# 환경변수 디렉토리 생성
sudo mkdir -p /etc/fitness-api
# 환경변수 파일 생성
sudo nano /etc/fitness-api/environment
환경변수 파일 내용 예시:
# 데이터베이스 연결 문자열
ConnectionStrings__DefaultConnection=Server=localhost;Database=FitnessDB;User=dbuser;Password=your_secure_password;
# JWT 설정
JwtSettings__SecretKey=your_jwt_secret_key_here
JwtSettings__Issuer=Issuer
JwtSettings__Audience=Audience
JwtSettings__ExpiryMinutes=1440
# API 키들
ExternalApi__GoogleMaps=your_google_maps_api_key
ExternalApi__Payment=your_payment_gateway_key
# 로깅 설정
Serilog__MinimumLevel=Information
4.3 서비스 권한 설정 및 등록
# 환경변수 파일 권한 설정 (보안 강화)
sudo chown root:jenkins /etc/프로젝트 경로/environment
sudo chmod 640 /etc/프로젝트 경로/environment
# 배포 디렉토리 생성 및 권한 설정
sudo mkdir -p /var/lib/jenkins/deployments/프로젝트 폴더
sudo chown -R jenkins:jenkins /var/lib/jenkins/deployments
# systemd 서비스 등록
sudo systemctl daemon-reload
sudo systemctl enable 프로젝트명.service
5. Jenkins Job 생성 및 배포 스크립트
5.1 Jenkins Job 생성
사전 준비: Git 인증 정보 설정
Private repository이거나 Push 권한이 필요한 경우 반드시 인증 정보를 설정해야 합니다.
GitHub Personal Access Token 사용 (권장)
- GitHub에서 토큰 생성:
- GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)
- "Generate new token" 클릭
- 권한 선택: repo (전체 저장소 접근) 체크
- 토큰 복사 (한 번만 보여줌으로 별도의 메모장에 작성해두고 사용하길 권장합니다.)
- Jenkins에 인증 정보 추가:
- Jenkins 관리 → Manage Credentials → System → Global credentials
- "Add Credentials" 클릭
- Kind: "Username with password" 선택
- Username: GitHub 사용자명
- Password: 위에서 생성한 Personal Access Token 입력
- ID: github-credentials (기억하기 쉬운 이름)
- Description: GitHub Personal Access Token
Jenkins Job 생성 단계:
- Jenkins 대시보드 → "새 항목"
- 항목 이름: FitnessPT_API_Deploy
- "Freestyle project" 선택
- "소스 코드 관리" → Git 선택
- Repository URL:
- HTTPS 방식: 깃 레포주소
- Credentials: 위에서 생성한 인증 정보 선택
- Branch: */main
- Repository URL:
연결 테스트:
- Repository URL과 Credentials 설정 후 "Test Connection" 버튼 클릭
- 성공 시: "Credentials verified for user [username], repository [repo-name]"
- 실패 시: 인증 정보나 URL 확인 필요
5.2 배포 스크립트 생성
Jenkins Execute Shell에 입력할 스크립트
#!/bin/bash
echo "🚀 자동배포를 시작합니다..."
# ================================================================
# 🎯 프로젝트 설정
# ================================================================
PROJECT_NAME="프로젝트명"
SERVICE_NAME=".Service 이름"
APP_PORT="5117"
BUILD_CONFIG="Release"
DEPLOY_PATH="/var/lib/jenkins/deployments/$PROJECT_NAME"
# 색상 정의 (가독성 향상)
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'
# ================================================================
# 🛠️ 배포 프로세스
# ================================================================
echo -e "${YELLOW}📋 배포 설정:${NC}"
echo " • 프로젝트: $PROJECT_NAME"
echo " • 서비스명: $SERVICE_NAME"
echo " • 포트: $APP_PORT"
echo " • 빌드 구성: $BUILD_CONFIG"
echo " • 배포 경로: $DEPLOY_PATH"
echo ""
# 1. 기존 서비스 중지
echo -e "${YELLOW}🛑 기존 서비스 중지 중...${NC}"
sudo systemctl stop $SERVICE_NAME || echo "서비스가 실행 중이 아닙니다."
# 2. 이전 배포 파일 백업 (선택사항)
if [ -d "$DEPLOY_PATH" ]; then
echo -e "${YELLOW}📦 이전 배포 파일 백업 중...${NC}"
sudo cp -r $DEPLOY_PATH ${DEPLOY_PATH}_backup_$(date +%Y%m%d_%H%M%S) || true
fi
# 3. 배포 디렉토리 생성/정리
echo -e "${YELLOW}📁 배포 디렉토리 준비 중...${NC}"
sudo mkdir -p $DEPLOY_PATH
sudo rm -rf $DEPLOY_PATH/*
# 4. .NET 프로젝트 빌드
echo -e "${YELLOW}🔨 .NET 프로젝트 빌드 중...${NC}"
dotnet clean
dotnet restore
dotnet publish -c $BUILD_CONFIG -o $DEPLOY_PATH --no-restore
if [ $? -ne 0 ]; then
echo -e "${RED}❌ 빌드 실패!${NC}"
exit 1
fi
# 5. 파일 권한 설정
echo -e "${YELLOW}🔐 파일 권한 설정 중...${NC}"
sudo chown -R jenkins:jenkins $DEPLOY_PATH
sudo chmod +x $DEPLOY_PATH/$PROJECT_NAME
# 6. 서비스 시작
echo -e "${YELLOW}🚀 서비스 시작 중...${NC}"
sudo systemctl start $SERVICE_NAME
# 7. 서비스 상태 확인
sleep 5
SERVICE_STATUS=$(sudo systemctl is-active $SERVICE_NAME)
if [ "$SERVICE_STATUS" = "active" ]; then
echo -e "${GREEN}✅ 서비스가 성공적으로 시작되었습니다!${NC}"
# 헬스체크
echo -e "${YELLOW}🔍 헬스체크 진행 중...${NC}"
sleep 10
if curl -f http://localhost:$APP_PORT/health > /dev/null 2>&1; then
echo -e "${GREEN}✅ 헬스체크 성공!${NC}"
else
echo -e "${YELLOW}⚠️ 헬스체크 실패 (서비스는 실행 중)${NC}"
fi
# 최종 결과 출력
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo -e "${GREEN}🎉 배포 완료!${NC}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "프로젝트: $PROJECT_NAME"
echo "포트: $APP_PORT"
echo "URL: http://localhost:$APP_PORT"
echo "배포 위치: $DEPLOY_PATH"
echo "로그 확인: sudo journalctl -u $SERVICE_NAME -f"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# 실행 중인 프로세스 정보
echo "실행 중인 프로세스:"
ps aux | grep "$PROJECT_NAME" | grep -v grep || echo "프로세스 정보 조회 실패"
else
echo -e "${RED}❌ 서비스 시작 실패!${NC}"
echo "서비스 로그 확인:"
sudo journalctl -u $SERVICE_NAME --no-pager -l
exit 1
fi
echo -e "${GREEN}✅ 모든 작업 완료!${NC}"
빌드 스크립트의 경우 프로젝트의 설정마다 일부 차이가 있을 수 있습니다.
기본적인 .NET 프로젝트 기준으로 작성된 스크립트로서 빌드 오류가 발생시 프로젝트에 맞추어 수정이 필요할 수 있습니다.
6. 보안 설정 및 환경변수 관리
6.1 Jenkins 사용자 sudo 권한 설정
# Jenkins 사용자에게 특정 명령어만 sudo 권한 부여
sudo visudo
다음 내용 추가
# Jenkins가 서비스 관리만 할 수 있도록 제한
jenkins ALL=(ALL) NOPASSWD: /bin/systemctl start 프로젝트명, /bin/systemctl stop 프로젝트명, /bin/systemctl restart 프로젝트명, /bin/systemctl status 프로젝트명, /bin/journalctl -u 프로젝트명*
6.2 환경변수 보안 관리
# 환경변수 파일 암호화 (선택사항)
sudo apt install gpg -y
# 환경변수 파일 백업
sudo cp /etc/프로젝트명/environment /etc/프로젝트명/environment.backup
# 권한 재확인
sudo ls -la /etc/프로젝트명/
7. 트러블슈팅 및 모니터링
7.1 로그 모니터링
# Jenkins 로그 확인
sudo journalctl -u jenkins -f
# 애플리케이션 로그 확인
sudo journalctl -u 프로젝트명 -f
# 시스템 로그 확인
sudo tail -f /var/log/syslog
7.2 포트 및 프로세스 확인
# 포트 사용 현황 확인
sudo netstat -tulpn | grep :5117
# 실행 중인 프로세스 확인
ps aux | grep 프로젝트명
# 서비스 상태 확인
sudo systemctl status 프로젝트명
7.3 일반적인 문제 해결
문제 1: 빌드 실패
# .NET SDK 버전 확인
dotnet --version
# 프로젝트 의존성 복원
dotnet restore --force
# 캐시 정리
dotnet clean
문제 2: 서비스 시작 실패
# 서비스 로그 상세 확인
sudo journalctl -u 프로젝트명 -n 50
# 환경변수 파일 문법 검사
sudo systemd-analyze verify /etc/systemd/system/프로젝트명.service
# 권한 문제 해결
sudo chown -R jenkins:jenkins /var/lib/jenkins/deployments
문제 3: 포트 충돌
# 포트를 사용하는 프로세스 찾기
sudo lsof -i :{프로젝트 내부 포트}
# 해당 프로세스 종료
sudo kill -9 [PID]
마무리 및 추가 개선사항
완성된 CI/CD 파이프라인의 특징
- 자동화: Git 푸시 → 자동 빌드 → 자동 배포
- 보안: 환경변수로 민감 정보 보호
- 안정성: systemd 서비스로 프로세스 관리
- 모니터링: 상세한 로깅 및 헬스체크
- 확장성: 다른 프로젝트에도 쉽게 적용 가능
세팅 이후 내용을 정리한 가이드로서 진행중 이슈가 있을 수 있습니다.
도움이 필요한 부분은 댓글을 남겨주시면 내용 수정 및 추가 가이드 안내 드리겠습니다.