Installation Prerequisites, Database Planning, and First Server: Guided Hands-On Workflow
Install and operate one pinned disposable Community Build server while capturing host, Java, path, database, port, process, and log evidence before and after startup.
Learning objectives
- Install a pinned SonarQube Community Build 26.9.0.129388 ZIP in an isolated local path.
- Prove the JDK, user identity, disk, port, and Linux search prerequisites before startup.
- Start the server locally, distinguish Web/Compute Engine/search log evidence, and verify the default endpoint.
- Explain where H2 fits in the lab and how a supported external database changes the architecture.
- Stop and restart cleanly while preserving an installation evidence manifest.
1. Lab contract and stop conditions
This workflow uses Community Build 26.9.0.129388 from the official ZIP distribution and the embedded H2 database only because the instance is disposable and local. Do not reuse the H2 result as a production deployment pattern.
Abort before installation if the current Community Build host requirements are not met, the JDK is unsupported, disk is critically low, the intended directories are outside the lab scope, or the machine cannot provide the required embedded-search behavior.
2. Create the installation manifest before touching the server
Use a working directory such as C:\sq-lab on Windows or
$HOME/sq-lab on Linux/macOS. Record the planned values
first:
sonarqube_product=Community Build
sonarqube_version=26.9.0.129388
install_mode=ZIP
java_requirement=JDK 21 or 25 (re-check current docs)
database=embedded H2 (lab only)
web_url=http://127.0.0.1:9000
source=synthetic/local only
cleanup=stop server, preserve evidence, remove lab directory when finished
The manifest turns assumptions into reviewable inputs. If a later startup differs—wrong Java, wrong path, wrong port—you can see the drift instead of guessing.
3. Download the pinned distribution and prove its identity
The pinned binary URL used by the official Community Build image for this release is:
https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-26.9.0.129388.zip
Windows PowerShell example:
$Root = 'C:\sq-lab'
$Version = '26.9.0.129388'
$Zip = Join-Path $Root "sonarqube-$Version.zip"
New-Item -ItemType Directory -Force -Path $Root | Out-Null
curl.exe -L 'https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-26.9.0.129388.zip' -o $Zip
Get-Item $Zip | Select-Object FullName,Length,LastWriteTime
Get-FileHash $Zip -Algorithm SHA256
Linux/macOS example:
set -eu
ROOT="$HOME/sq-lab"
VERSION="26.9.0.129388"
mkdir -p "$ROOT"
curl -fL 'https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-26.9.0.129388.zip' -o "$ROOT/sonarqube-$VERSION.zip"
sha256sum "$ROOT/sonarqube-$VERSION.zip" 2>/dev/null || shasum -a 256 "$ROOT/sonarqube-$VERSION.zip"
Record the calculated hash in your lab evidence. For production acquisition, use the current SonarSource verification/signature guidance rather than treating a copied URL as sufficient provenance.
4. Prove runtime and host prerequisites
On Windows, confirm the exact Java executable and version:
Get-Command java | Select-Object Source
java -version
Get-NetTCPConnection -State Listen -LocalPort 9000 -ErrorAction SilentlyContinue
Get-PSDrive -PSProvider FileSystem | Select-Object Name,Used,Free
On Linux, add the embedded-search prerequisites:
java -version
id
sysctl vm.max_map_count
sysctl fs.file-max
ulimit -n
ulimit -u
ss -ltn | grep ':9000' || true
df -h "$HOME"
Expected: a supported JDK (current baseline Java 21 or 25), enough disk, no unintended listener conflict, a non-root Unix user, and current documented search limits. If any prerequisite fails, preserve the output and stop. Do not hide a host incompatibility by disabling bootstrap checks.
5. Unpack into a clean path and inspect before execution
Extract the ZIP. The release directory should be
sonarqube-26.9.0.129388. Inspect rather than
immediately launching it.
$Home = 'C:\sq-lab\sonarqube-26.9.0.129388'
Expand-Archive -Path $Zip -DestinationPath 'C:\sq-lab' -Force
Get-ChildItem $Home
Get-ChildItem (Join-Path $Home 'bin')
Get-ChildItem (Join-Path $Home 'conf')
Get-ChildItem (Join-Path $Home 'logs') -ErrorAction SilentlyContinue
cd "$HOME/sq-lab"
unzip -q "sonarqube-26.9.0.129388.zip"
SQ_HOME="$HOME/sq-lab/sonarqube-26.9.0.129388"
printf 'SQ_HOME=%s
' "$SQ_HOME"
find "$SQ_HOME" -maxdepth 1 -mindepth 1 -printf '%f
' | sort
Do not copy an old conf, extensions, or
data directory into this fresh release. That would
convert a controlled first install into an undocumented migration.
6. Start locally and follow process-specific evidence
For Windows, open a dedicated terminal as the normal lab user and run:
Set-Location 'C:\sq-lab\sonarqube-26.9.0.129388\bin\windows-x86-64'
.\StartSonar.bat
For Linux, run as the non-root lab user:
"$SQ_HOME/bin/linux-x86-64/sonar.sh" console
In a second shell, inspect the log files rather than repeatedly refreshing the browser:
$Logs='C:\sq-lab\sonarqube-26.9.0.129388\logs'
Get-Content (Join-Path $Logs 'sonar.log') -Tail 80
Get-Content (Join-Path $Logs 'web.log') -Tail 80
Get-Content (Join-Path $Logs 'ce.log') -Tail 80
Get-Content (Join-Path $Logs 'es.log') -Tail 80
A successful startup reaches the documented SonarQube is operational state. The files separate orchestration, Web, Compute Engine, and embedded-search evidence. Preserve the first failure if startup stops before that point.
7. Verify the local endpoint and bootstrap state
Only after the logs show a healthy startup should you inspect the web endpoint:
curl.exe -I http://127.0.0.1:9000/
Get-NetTCPConnection -State Listen -LocalPort 9000
curl -I http://127.0.0.1:9000/
ss -ltnp | grep ':9000'
Open http://127.0.0.1:9000. The current ZIP
installation documentation identifies admin/admin as
the bootstrap administrator credentials. For this disposable lab,
note that state in the evidence packet. For any persistent instance,
change bootstrap credentials immediately and review permissions
before widening network exposure.
8. Compare the H2 lab to a production-shaped database plan
Do not convert this lesson into a database installation course. Instead, write the production delta. A supported external database requires a pre-created SonarQube database/schema, a least-privilege database user with the permissions required by current documentation, an explicit JDBC URL, and secure credential delivery.
# Production-shaped example only; use fake values here.
sonar.jdbc.username=sonarqube
sonar.jdbc.password=FAKE_DO_NOT_USE
sonar.jdbc.url=jdbc:postgresql://db.example.invalid:5432/sonarqube
Do not put a real database password in a course repository. In a real deployment, use the supported environment/secret mechanism for your operating model. The lesson’s key distinction is architectural: switching from H2 to PostgreSQL changes the durable-state boundary and backup/recovery plan; it does not change scanner project keys or quality-gate semantics.
9. Stop gracefully, restart, and compare evidence
On Linux/macOS ZIP installations, use the documented graceful stop command. On Windows, use the appropriate console/service stop path for how you started the instance. Do not kill Java processes until you have preserved logs and attempted a graceful stop.
"$SQ_HOME/bin/linux-x86-64/sonar.sh" stop
"$SQ_HOME/bin/linux-x86-64/sonar.sh" start
After restart, verify the same URL, version, port, and log sequence. The expected result is a repeatable startup, not merely a lucky first run.
10. Challenge: identify the layer before choosing the fix
For each symptom, name the owning layer before proposing a change:
| Symptom | Likely first layer | First evidence |
|---|---|---|
java -version reports 17 |
Runtime compatibility | PATH/JDK identity, host requirements |
| 9000 already listening before SonarQube starts | Network/process ownership | listener PID/process |
es.log reports bootstrap limit failure |
Host/search prerequisites | sysctl/ulimit values |
| Database login refused | Database/network/credential | JDBC config + DB logs, without printing secrets |
11. Cleanup and retained evidence
Preserve the manifest, version/hash record, preflight output, first startup logs, endpoint verification, and shutdown result. Then stop the server. Delete only the explicitly named lab directory after confirming no persistent work is needed. Do not delete database/search/log directories on a real instance as “cleanup.”
Knowledge check
Why does the lab record a file hash even though it uses an official download URL?
The hash gives the evidence packet an exact artifact identity. Production acquisition should add the current official signature/provenance verification process.
Why do we inspect logs before opening the browser?
Because startup may fail in Web, Compute Engine, or embedded search. A browser refresh does not identify the failing process and may lose focus on first-failure evidence.
What changes when a real PostgreSQL database replaces H2?
The durable-state boundary, database operations, credentials, backup/recovery, and availability design change. Scanner project semantics do not automatically change.
Why must you not disable Elasticsearch bootstrap checks just to make the server start?
Those checks surface host conditions required for reliable embedded-search operation. Disabling them hides an incompatible host instead of fixing the owning layer.
What proves the restart is reproducible?
The same pinned release/JDK/configuration starts again with healthy process-specific logs, the expected listener, and the expected local endpoint—not merely a single successful browser response.
Official references and version notes
- SonarQube Community Build downloads — current Community Build release identity and download entry point.
- Server host requirements — current JDK, OS, CPU/RAM/disk, and embedded-search requirements.
- Installing database — supported databases and the H2 non-production boundary.
- Linux pre-installation — current vm.max_map_count, file-descriptor, thread, and seccomp prerequisites.
- ZIP installation overview — required installation sequence and initial login baseline.
- Basic ZIP installation — database, data/temp paths, web connection, and healthy startup guidance.
- Starting and stopping from ZIP — current platform start/stop commands and graceful-stop semantics.
- Running as a service — Windows service and Linux service-account guidance.
Version-sensitive statements were rechecked against current SonarSource primary documentation on 2026-09-07. Executable ZIP examples pin SonarQube Community Build 26.9.0.129388. Current Community Build host requirements specify a JDK with Java 21 or 25 for ZIP installation. Current database guidance treats embedded H2 as test/trial-only and lists PostgreSQL 14–18 plus supported Microsoft SQL Server and Oracle versions. Linux embedded-search prerequisites include vm.max_map_count ≥ 524288, fs.file-max ≥ 131072, at least 131072 open file descriptors for the SonarQube user, and at least 8192 threads. Re-check all of these before future reproduction.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.