This guide covers installing and configuring a SonarQube server for use with the OpenCode SonarQube Plugin.
- Quick Start with Docker
- Production Installation
- Initial Configuration
- Quality Gates Setup
- User & Token Management
- Troubleshooting
The fastest way to get SonarQube running for development:
# Create a network
docker network create sonarqube
# Start SonarQube (Community Edition)
docker run -d \
--name sonarqube \
--network sonarqube \
-p 9000:9000 \
-e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true \
sonarqube:lts-community
# Wait for startup (can take 1-2 minutes)
sleep 60
# Check if it's running
curl -s http://localhost:9000/api/system/status | jq .status
# Should return "UP"Default credentials: admin / admin
| Component | Minimum | Recommended |
|---|---|---|
| CPU | 2 cores | 4+ cores |
| RAM | 4 GB | 8+ GB |
| Disk | 10 GB | 50+ GB SSD |
| Java | JRE 17 | JRE 17 |
| Database | PostgreSQL 13+ | PostgreSQL 15+ |
Create docker-compose.yml:
version: "3.8"
services:
sonarqube:
image: sonarqube:lts-community
container_name: sonarqube
depends_on:
- db
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
- sonarqube_logs:/opt/sonarqube/logs
ports:
- "9000:9000"
restart: unless-stopped
db:
image: postgres:15
container_name: sonarqube-db
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
POSTGRES_DB: sonar
volumes:
- postgresql_data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
sonarqube_data:
sonarqube_extensions:
sonarqube_logs:
postgresql_data:Start with:
docker-compose up -dSonarQube requires specific kernel parameters:
# Add to /etc/sysctl.conf
vm.max_map_count=524288
fs.file-max=131072
# Apply immediately
sudo sysctl -w vm.max_map_count=524288
sudo sysctl -w fs.file-max=131072
# Add to /etc/security/limits.conf
sonarqube - nofile 131072
sonarqube - nproc 8192server {
listen 443 ssl http2;
server_name sonarqube.example.com;
ssl_certificate /etc/letsencrypt/live/sonarqube.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/sonarqube.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}# Via API
curl -X POST -u admin:admin \
"http://localhost:9000/api/users/change_password" \
-d "login=admin&previousPassword=admin&password=YourSecurePassword123!"Or via UI: Administration > Security > Users > admin > Change Password
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/settings/set" \
-d "key=sonar.core.serverBaseURL&value=https://sonarqube.example.com"For TypeScript/JavaScript (included by default). Additional languages:
# Via Administration > Marketplace, or CLI:
# Python
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/plugins/install?key=python"
# Restart required after plugin installation
docker restart sonarqubeThe plugin can auto-create quality gates, but you can also set them up manually.
# Create quality gate
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create" \
-d "name=Enterprise"
# Get the gate ID
GATE_ID=$(curl -s -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/list" | jq '.qualitygates[] | select(.name=="Enterprise") | .id')
# Add conditions
# Coverage >= 80%
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=Enterprise&metric=coverage&op=LT&error=80"
# Duplications <= 0%
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=Enterprise&metric=duplicated_lines_density&op=GT&error=0"
# Bugs = 0
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=Enterprise&metric=bugs&op=GT&error=0"
# Vulnerabilities = 0
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=Enterprise&metric=vulnerabilities&op=GT&error=0"
# Code Smells = 0
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=Enterprise&metric=code_smells&op=GT&error=0"
# Reliability Rating = A
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=Enterprise&metric=reliability_rating&op=GT&error=1"
# Security Rating = A
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=Enterprise&metric=security_rating&op=GT&error=1"
# Maintainability Rating = A
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=Enterprise&metric=sqale_rating&op=GT&error=1"curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create" \
-d "name=Standard"
# Coverage >= 70%
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=Standard&metric=coverage&op=LT&error=70"
# Duplications <= 3%
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=Standard&metric=duplicated_lines_density&op=GT&error=3"
# Bugs = 0
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=Standard&metric=bugs&op=GT&error=0"
# Vulnerabilities = 0
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/qualitygates/create_condition" \
-d "gateName=Standard&metric=vulnerabilities&op=GT&error=0"# Create user for CI/CD
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/users/create" \
-d "login=opencode-service&name=OpenCode Service&password=ServicePassword123!"
# Grant permissions
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/permissions/add_user" \
-d "login=opencode-service&permission=scan"
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/permissions/add_user" \
-d "login=opencode-service&permission=provisioning"# Global analysis token
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/user_tokens/generate" \
-d "name=opencode-global&type=GLOBAL_ANALYSIS_TOKEN" | jq .token
# Project-specific token (created automatically by plugin)
curl -X POST -u admin:YourPassword \
"http://localhost:9000/api/user_tokens/generate" \
-d "name=my-project-token&type=PROJECT_ANALYSIS_TOKEN&projectKey=my-project" | jq .token- Use project tokens - More secure than global tokens
- Set expiration - Rotate tokens regularly
- Store securely - Use environment variables or secrets manager
- Audit regularly - Review token usage in Administration > Security > Users
Configure the plugin using these environment variables:
# Required
export SONAR_HOST_URL="https://sonarqube.example.com"
export SONAR_USER="admin"
export SONAR_PASSWORD="YourSecurePassword"
# Or use token authentication
export SONAR_TOKEN="sqp_xxxxxxxxxxxxx"
# Optional
export SONAR_PROJECT_KEY="my-project"
export SONAR_SOURCES="src"# Check logs
docker logs sonarqube
# Common issue: Elasticsearch heap
# Add to docker-compose.yml environment:
# SONAR_SEARCH_JAVAADDITIONALOPTS: "-Dnode.store.allow_mmap=false"# Increase heap in docker-compose.yml
environment:
SONAR_WEB_JAVAOPTS: "-Xmx1G -Xms512m"
SONAR_CE_JAVAOPTS: "-Xmx1G -Xms512m"
SONAR_SEARCH_JAVAOPTS: "-Xmx1G -Xms512m"# Check PostgreSQL is running
docker logs sonarqube-db
# Test connection
docker exec -it sonarqube-db psql -U sonar -d sonar -c "SELECT 1"# Verify connectivity
curl -s http://localhost:9000/api/system/status
# Check firewall
sudo ufw status
sudo ufw allow 9000/tcp- Increase scanner memory:
SONAR_SCANNER_OPTS="-Xmx2G" - Exclude unnecessary files in
sonar-project.properties - Use incremental analysis for PRs
# Stop SonarQube
docker-compose stop sonarqube
# Backup database
docker exec sonarqube-db pg_dump -U sonar sonar > sonar_backup.sql
# Backup volumes
docker run --rm -v sonarqube_data:/data -v $(pwd):/backup alpine \
tar czf /backup/sonarqube_data.tar.gz /data
# Restart
docker-compose start sonarqube# Stop SonarQube
docker-compose stop sonarqube
# Restore database
cat sonar_backup.sql | docker exec -i sonarqube-db psql -U sonar sonar
# Restore volumes
docker run --rm -v sonarqube_data:/data -v $(pwd):/backup alpine \
tar xzf /backup/sonarqube_data.tar.gz -C /
# Restart
docker-compose start sonarqube- Enable HTTPS - Use reverse proxy with TLS
- Change default credentials - Immediately after installation
- Restrict network access - Firewall rules
- Regular updates - Keep SonarQube updated
- Audit logs - Monitor Administration > System > Logs
- LDAP/SAML - Integrate with enterprise identity provider