Chapter 04Lesson 04~135 minutes

Docker, Containers, Persistent Storage, and Production Deployment: Diagnostics, Failure Modes, and Production Practices

Diagnose containerized SonarQube failures by preserving evidence and isolating image, configuration, network, database, volume, host/search, resource, and edition layers before changing anything.

DiagnosticsDocker DNSMountsLogsRecovery

Learning objectives

  • Preserve first-failure evidence before restart, cleanup, or image replacement.
  • Separate network/DNS, database, volume/ownership, host/search, resource, image/configuration, and SonarQube policy failures.
  • Diagnose an intentionally broken localhost JDBC configuration without weakening TLS, authentication, host checks, or quality policy.
  • Explain how floating tags, ephemeral DB data, broad port exposure, and volume deletion create operational ambiguity or data loss.
  • Apply the least destructive correction and rerun the smallest equivalent scenario.

1. Evidence-first diagnostic sequence

  1. Freeze change. Preserve docker ps -a, inspect output, image digests, logs, Compose/run configuration, and timestamps.
  2. Confirm exact SonarQube/PostgreSQL image identities and architecture.
  3. Confirm effective JDBC/server environment without printing sensitive values into shared artifacts.
  4. Inspect mounts and volume identities.
  5. Inspect Docker network membership, aliases, and DNS assumptions.
  6. Inspect DB readiness and DB logs.
  7. Inspect SonarQube web/CE/search logs and /api/system/status.
  8. Inspect host sysctl/ulimit/resource state if search or resource failures appear.
  9. Apply the least destructive correction, then rerun the same smallest scenario.

2. Preserve first-failure evidence before touching the container

mkdir -p evidence

docker ps -a --no-trunc > evidence/docker-ps.txt
docker image inspect sonarqube:26.9.0.129388-community > evidence/sonarqube-image.json
docker inspect sq-lab > evidence/sq-lab-inspect.json 2>&1 || true
docker inspect sq-db > evidence/sq-db-inspect.json 2>&1 || true
docker network inspect sq_net > evidence/sq-net.json 2>&1 || true
docker logs sq-lab > evidence/sq-lab.log 2>&1 || true
docker logs sq-db > evidence/sq-db.log 2>&1 || true

Before sharing evidence, redact passwords, tokens, private hostnames, and sensitive labels. Preserve raw evidence securely if needed; publish only the minimum sanitized subset.

3. Intentionally broken example: localhost points to the wrong process

Assume PostgreSQL is healthy in sq-db on sq_net, but SonarQube was started with:

SONAR_JDBC_URL=jdbc:postgresql://localhost:5432/sonar

Expected evidence: SonarQube cannot connect to PostgreSQL because TCP 5432 inside sq-lab is not the sibling database container. Confirm before fixing:

docker network inspect sq_net
docker exec sq-db pg_isready -U sonar -d sonar
docker logs --tail 160 sq-lab

The least destructive correction is to recreate only sq-lab with jdbc:postgresql://db:5432/sonar. Do not publish PostgreSQL broadly, lower a quality gate, delete volumes, or switch project keys. Those changes are unrelated to the failing layer.

4. Volume and ownership failures

A SonarQube startup can fail because a bind-mounted directory is not writable by the effective container user, because a volume was mounted at the wrong destination, or because an operator deleted a needed named volume. Inspect rather than guessing:

docker inspect sq-lab --format '{{json .Mounts}}'
docker image inspect sonarqube:26.9.0.129388-community --format 'user={{.Config.User}}'
docker volume inspect sq_data sq_extensions sq_logs

Do not solve ownership by running the whole container as root. Align volume semantics and permissions with the supported image behavior.

5. “The project disappeared” is usually a database-identity question

If the SonarQube container recreates successfully but projects/users/settings disappear, first verify the JDBC endpoint and PostgreSQL volume identity. A fresh Postgres container without the original data volume is a fresh durable store. Reusing sonarqube_data cannot reconstruct missing database rows.

Never attempt direct SQL reconstruction. Restore a supported database backup/recovery point or correct the database attachment. Direct DB edits are outside the supported operational model.

6. Embedded-search failures: container logs can point back to the host

Symptoms such as bootstrap-check failures, inability to use /tmp, file-descriptor exhaustion, or search process exits belong to host/search/runtime state. Inspect current Linux limits and resource pressure before changing SonarQube policy:

sysctl vm.max_map_count
sysctl fs.file-max
ulimit -n
ulimit -u
docker stats --no-stream sq-lab
docker logs --tail 200 sq-lab

Do not normalize SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true as a production shortcut. Fix the owning host/runtime prerequisite.

7. Floating-tag drift: “same Compose file” may not mean same software

If a stack uses sonarqube:latest or sonarqube:community, a later pull can select new image content without changing YAML. Compare RepoDigests, container image IDs, deployment timestamps, and release notes. The correction is a controlled version/digest policy, not deleting logs that expose the change.

8. Secret failures versus secret exposure

An authentication error can come from a wrong DB password, wrong user, wrong JDBC endpoint, or database-side permissions. Diagnose without printing passwords. Conversely, a correct password embedded in a Dockerfile or committed Compose file is an incident even if the container starts. Correctness and confidentiality are separate properties.

9. Destructive cleanup is not troubleshooting

Commands such as docker system prune, docker volume prune, or docker compose down -v can remove evidence and durable state. Preserve logs/inspect output and identify exact resource names first. SonarSource’s container update guidance explicitly warns operators about volume-removal commands because database state can be lost.

10. Symptom-to-layer matrix

Symptom Likely layer First evidence Wrong shortcut
DB connection refused Network/DB/JDBC network inspect, DB readiness, Sonar logs lowering quality gate
Permission denied under extensions/data Mount/UID/security context mounts, image user, host perms run everything as root
Elasticsearch bootstrap failure Host/search es/server logs, sysctl/ulimit disable bootstrap checks
Projects gone after redeploy DB identity/persistence JDBC endpoint + PG volume edit DB/search directly
Unexpected new behavior after pull Image drift tag/digest + release notes delete caches/logs

11. Production practice: make rollback evidence explicit

A production container change record should include source configuration revision, old/new image tags and digests, supported upgrade path, database backup point, plugin compatibility, host/resource preflight, maintenance window, expected migration behavior, health checks, and rollback/recovery decision criteria. An older image is not automatically a safe rollback after a database migration.

Knowledge check

What is the first thing to do when a containerized SonarQube startup fails?

Why is publishing PostgreSQL port 5432 not the fix for a wrong localhost JDBC URL?

If project history disappears, why is sonarqube_data not enough to restore it?

What should you do instead of disabling Elasticsearch bootstrap checks?

Why can latest make incident diagnosis harder?

Next lesson

From diagnosis to an auditable checkpoint

Lesson 5 repeats the stack as a controlled exercise: predict state, record an evidence packet, prove persistence, inject one network mistake, repair it, and tear down only the named lab resources.

Official references and version notes

Version and compatibility note

Version-sensitive statements were rechecked against current SonarSource and Docker Hub primary material on 2026-09-07. Mandatory examples use SonarQube Community Build 26.9.0.129388 with the official sonarqube:26.9.0.129388-community image and PostgreSQL postgres:17.11, which is inside the currently supported PostgreSQL 14–18 range. The recorded multi-platform SonarQube image index digest at authoring time is sha256:62930c7f510534bb2bf551ca69ad3ee6f8e12b4116d394597c64cefccbb3313b; learners should inspect the digest they actually pull and retain it in their evidence packet. The SonarQube image supplies its own Java runtime; record java -version inside the running container when runtime provenance matters. No SonarScanner execution, third-party plugin, CI/provider integration, enterprise identity provider, or commercial feature is required by the mandatory Chapter 04 labs. Commercial Server/Data Center, Kubernetes, managed databases, paid CI, and enterprise identity are optional/later-course boundaries.

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.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.