Table of Contents
- 사전 요구사항
- SonarQube 서버 설정
- Jenkins 플러그인 설치 및 설정
- SonarQube 프로젝트 설정
- Jenkins 파이프라인 연동
- Quality Gates 설정
- 연동 테스트
- 문제 해결
- 베스트 프랙티스
- 유지보수
1. Prerequisites
- Kubernetes cluster (minikube, k8s, etc.)
- Helm 3.x installed
- kubectl installed with cluster access permissions
- Jenkins server running
- Jenkins administrator console access
- Network connectivity between Jenkins ↔ SonarQube
2. SonarQube Server Setup
2.1 Helm Chart Installation
helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube
helm repo update
helm install sonarqube sonarqube/sonarqube \
--namespace sonarqube \
--create-namespace \
--values sonarqube.yaml
2.2 Access Verification
# Ingress 확인
curl -I http://sonarqube.127.0.0.1.nip.io
# 또는 포트 포워딩
kubectl port-forward svc/sonarqube-sonarqube 9000:9000 -n sonarqube
2.3 Initial Credentials
- ID:
admin - PW:
admin(must be changed on first login)
2.4 Token Generation
-
Profile → My Account → Security → Generate Tokens


-
Token name:
jenkins-integration, Type: Global Analysis TokenGenerate Tokens Name : jenkins-integration Type : Project Analysis Token Project : apps-demo Expires in : No expiration -
After generation, register in Jenkins
- id: sonarqube-token secret: token
3. Jenkins Plugin Installation and Configuration
3.1 Required Plugins
- SonarQube Scanner for Jenkins
- Quality Gates Plugin
3.2 Scanner Tool Configuration
-
Manage Jenkins → Global Tool Configuration

-
Add SonarQube Scanner (auto-install). The name used here is the command identifier that will be called from the Jenkinsfile.


3.3 SonarQube Server Registration
-
Manage Jenkins → System Configuration
-
Name:
SonarQube -
URL:
http://sonarqube.127.0.0.1.nip.io -
Credentials:
sonarqube-tokenThe SonarQube secret key generated earlier Kind: Secret text

4. SonarQube Project Setup
4.2 Quality Profile
-
Default
Sonar wayor custom-defined
4.3 sonar-project.properties Example
- Register this configuration file in the same location where the Jenkinsfile is stored.
# SonarQube project configuration
sonar.projectKey=app-demo
sonar.projectName=App Demo
sonar.projectVersion=1.0
# Source code location
sonar.sources=.
sonar.sourceEncoding=UTF-8
# Exclusions
sonar.exclusions=**/dist/**,**/venv/**,**/__pycache__/**,**/node_modules/**,**/.git/**,**/target/**,**/*.pyc,**/.pytest_cache/**,**/htmlcov/**
# Python specific settings (no test coverage files exist)
# sonar.python.coverage.reportPaths=coverage.xml
# sonar.python.xunit.reportPath=test-results.xml
# Language detection
sonar.language=py
# Test settings (no tests directory exists)
# sonar.tests=tests/
# sonar.test.inclusions=**/test_*.py,**/*_test.py
# Coverage exclusions
sonar.coverage.exclusions=**/test_*.py,**/*_test.py,**/conftest.py
# Duplication exclusions
sonar.cpd.exclusions=**/migrations/**
5. Jenkins Pipeline Integration
5.0 Jenkinsfile Parameter Example
string(name: 'SONAR_HOST_URL', defaultValue: 'http://sonarqube.127.0.0.1.nip.io', description: 'SonarQube server URL')
string(name: 'SONAR_CREDENTIALS_ID', defaultValue: 'sonarqube-token', description: 'Jenkins credentialsId for SonarQube token')
string(name: 'SONAR_PROJECT_KEY', defaultValue: 'app-demo', description: 'SonarQube project key')
string(name: 'SONAR_PROJECT_NAME', defaultValue: 'App Demo', description: 'SonarQube project name')
booleanParam(name: 'ENABLE_SONAR', defaultValue: true, description: 'Enable SonarQube code analysis')
booleanParam(name: 'SONAR_QUALITY_GATE', defaultValue: true, description: 'Wait for SonarQube Quality Gate')
5.1 Jenkinsfile Example
stage('SonarQube Analysis') {
when {
expression { return params.ENABLE_SONAR }
}
steps {
script {
echo "Starting SonarQube code analysis for project: ${params.SONAR_PROJECT_KEY}"
// Jenkins SonarQube 플러그인의 표준 방식
withSonarQubeEnv('SonarQube') {
// Jenkins에서 관리하는 SonarScanner 도구 사용
def scannerHome = tool 'sonar-scanner'
sh """
${scannerHome}/bin/sonar-scanner \
-Dsonar.projectKey=${params.SONAR_PROJECT_KEY} \
-Dsonar.projectName="${params.SONAR_PROJECT_NAME}" \
-Dsonar.projectVersion=${env.VERSION}
"""
}
}
}
}
stage('SonarQube Quality Gate') {
when {
allOf {
expression {
echo "ENABLE_SONAR: ${params.ENABLE_SONAR} (type: ${params.ENABLE_SONAR?.getClass()})"
return params.ENABLE_SONAR == true || params.ENABLE_SONAR == 'true'
}
expression {
echo "SONAR_QUALITY_GATE: ${params.SONAR_QUALITY_GATE} (type: ${params.SONAR_QUALITY_GATE?.getClass()})"
return params.SONAR_QUALITY_GATE == true || params.SONAR_QUALITY_GATE == 'true'
}
}
}
steps {
script {
echo "Waiting for SonarQube Quality Gate result..."
echo "Webhook URL: http://host.minikube.internal:8080/sonarqube-webhook/"
timeout(time: 10, unit: 'MINUTES') {
def qg = waitForQualityGate()
echo "Quality Gate result received: ${qg.status}"
echo "Quality Gate details: ${qg}"
if (qg.status != 'OK') {
error "Pipeline aborted due to quality gate failure: ${qg.status}"
}
echo "Quality Gate passed successfully"
}
}
}
}
5.2 Webhook Configuration

- SonarQube: Project Settings → Webhooks → Create
- Name:
Jenkins-sonarqube-quality - URL example:
http://jenkins:8080/sonarqube-webhook/
6. Quality Gates Configuration
- Coverage < 80%
- Duplicated lines > 3%
- Maintainability/Reliability/Security Rating ≤ A
→ Project Settings → Quality Gate → Select Custom Gate
7. Integration Testing
- Run Jenkins build (
ENABLE_SONAR=true) - Check analysis results in Jenkins console log
- Verify project status in SonarQube dashboard
8. Troubleshooting
8.1 Common Issues
- Scanner not found: Check Jenkins Global Tool configuration
- Authentication failure: Check if token has expired
- Webhook timeout: Verify SonarQube → Jenkins connectivity
8.2 Debugging
# Jenkins → SonarQube 연결 확인
curl -I http://sonarqube.127.0.0.1.nip.io
# SonarQube → Jenkins Webhook 테스트
curl -X POST http://jenkins:8080/sonarqube-webhook/ -d '{"test":"ok"}'
9. Best Practices
- Use strong passwords for administrator accounts
- Rotate tokens periodically
- Apply HTTPS
- Gradually strengthen Quality Gate conditions
10. Maintenance
- Regularly update SonarQube and plugins
- Monitor disk space and back up the database
- Periodically review Quality Profiles
- Configure monitoring and alerts
👉 The manual now has section numbers that match the table of contents, with subheadings, code blocks, and lists neatly organized.
If you’d like, I can also prepare this document in PDF distribution format or as a company wiki Markdown version. Which format do you need?
