Hướng dẫn cài đặt SonarQube bằng Docker: Từ cơ bản đến nâng cao

07 tháng 4, 2026·15 phút đọc

SonarQube là nền tảng phân tích mã nguồn tĩnh phổ biến nhất thế giới, và Docker là cách nhanh nhất để triển khai nó. Bài viết này sẽ hướng dẫn bạn từ cách chạy nhanh SonarQube để đánh giá cho đến thiết lập môi trường sản xuất hoàn chỉnh với PostgreSQL và Docker Compose, giúp bạn phát hiện lỗi và lỗ hổng bảo mật ngay từ giai đoạn phát triển.

Hướng dẫn cài đặt SonarQube bằng Docker: Từ cơ bản đến nâng cao

SonarQube là nền tảng phân tích mã nguồn tĩnh (static analysis) được triển khai rộng rãi nhất thế giới, và Docker là cách nhanh nhất để vận hành nó. Cho dù bạn cần một phiên bản cục bộ cho các dự án cá nhân hay một triển khai sản xuất cho đội ngũ kỹ thuật của mình, việc chạy SonarQube trong các container Docker giúp loại bỏ sự phức tạp của việc cài đặt thủ công Java, cấu hình cơ sở dữ liệu và quản lý các phụ thuộc.

Hướng dẫn này bao gồm mọi thứ, từ một lệnh docker run duy nhất để đánh giá nhanh đến thiết lập Docker Compose đầy đủ với PostgreSQL, lưu trữ dữ liệu liên tục (persistent volumes), cấu hình scanner và bảo mật cho môi trường sản xuất. Khi kết thúc, bạn sẽ có một phiên bản SonarQube hoạt động để phân tích mã của bạn và bắt lỗi, lỗ hổng và "mùi code" trước khi chúng đến môi trường sản xuất.

Giao diện SonarQubeGiao diện SonarQube

Điều kiện tiên quyết

Trước khi bắt đầu, hãy đảm bảo các công cụ sau đã được cài đặt trên máy của bạn:

  • Docker Engine phiên bản 20.10 trở lên (kiểm tra bằng docker --version)
  • Docker Compose phiên bản 2.0 trở lên (kiểm tra bằng docker compose version)
  • Tối thiểu 4 GB RAM được cấp cho Docker - Elasticsearch tích hợp của SonarQube rất "đói" bộ nhớ
  • 2 nhân CPU tối thiểu - Cả Elasticsearch và máy chủ tính toán của SonarQube đều cần sức mạnh xử lý

Trên máy chủ Linux, bạn cũng cần đặt một tham số kernel trước khi SonarQube khởi động:

# Yêu cầu cho Elasticsearch - đặt tạm thời
sudo sysctl -w vm.max_map_count=524288

# Đặt vĩnh viễn (sống sót qua các lần khởi động lại)
echo "vm.max_map_count=524288" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Trên macOS và Windows với Docker Desktop, cài đặt này được xử lý tự động. Bạn không cần chạy lệnh sysctl.

Khởi động nhanh với docker run

Nếu bạn chỉ muốn thử SonarQube nhanh chóng mà không cần thiết lập cơ sở dữ liệu, một lệnh docker run duy nhất sẽ giúp bạn chạy trong vòng dưới hai phút. Cách tiếp cận này sử dụng cơ sở dữ liệu H2 tích hợp của SonarQube, phù hợp để đánh giá nhưng không được hỗ trợ cho môi trường sản xuất.

docker run -d \
  --name sonarqube \
  -p 9000:9000 \
  sonarqube:lts-community

Lệnh này kéo image SonarQube Community Edition LTS, khởi động nó trong nền và ánh xạ cổng 9000. Chờ khoảng 60 đến 90 giây để ứng dụng khởi tạo, sau đó mở http://localhost:9000 trong trình duyệt của bạn.

Thông tin đăng nhập mặc định là:

  • Username: admin
  • Password: admin

SonarQube sẽ ngay lập tức yêu cầu bạn thay đổi mật khẩu mặc định. Hãy đặt một mật khẩu mạnh và lưu lại - bạn sẽ cần nó sau này để tạo token scanner.

Để kiểm tra nhật ký container trong quá trình khởi động:

docker logs -f sonarqube

Khi bạn thấy thông báo SonarQube is operational, máy chủ đã sẵn sàng sử dụng.

Để dừng và xóa container sau này:

docker stop sonarqube && docker rm sonarqube

Cách tiếp cận khởi động nhanh này hữu ích để cái nhìn đầu tiên về giao diện và tính năng của SonarQube, nhưng dữ liệu được lưu trữ bên trong container và sẽ bị mất khi container bị xóa. Đối với bất kỳ thứ gì vượt quá một bài kiểm tra nhanh, hãy sử dụng Docker Compose với PostgreSQL.

Thiết lập Docker Compose với PostgreSQL

Một triển khai SonarQube sẵn sàng cho sản xuất cần một cơ sở dữ liệu PostgreSQL bên ngoài. Docker Compose cho phép bạn định nghĩa cả hai dịch vụ trong một tệp duy nhất và quản lý chúng cùng nhau. Đây là cách tiếp cận được khuyến nghị cho bất kỳ đội ngũ hoặc cài đặt lâu dài nào.

Tạo một thư mục dự án và thêm tệp docker-compose.yml:

mkdir sonarqube-docker && cd sonarqube-docker

Bây giờ hãy tạo docker-compose.yml với nội dung sau:

services:
  sonarqube:
    image: sonarqube:lts-community
    container_name: sonarqube
    depends_on:
      db:
        condition: service_healthy
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonarqube
      SONAR_JDBC_USERNAME: sonar
      SONAR_JDBC_PASSWORD: sonar_password
    ports:
      - "9000:9000"
    volumes:
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_logs:/opt/sonarqube/logs
    networks:
      - sonarnet
    restart: unless-stopped

  db:
    image: postgres:16
    container_name: sonarqube-db
    environment:
      POSTGRES_USER: sonar
      POSTGRES_PASSWORD: sonar_password
      POSTGRES_DB: sonarqube
    volumes:
      - postgresql_data:/var/lib/postgresql/data
    networks:
      - sonarnet
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U sonar -d sonarqube"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  sonarqube_data:
  sonarqube_extensions:
  sonarqube_logs:
  postgresql_data:

networks:
  sonarnet:
    driver: bridge

Có một số chi tiết quan trọng trong cấu hình này:

  • Khối depends_on với condition: service_healthy đảm bảo SonarQube không khởi động cho đến khi PostgreSQL sẵn sàng chấp nhận kết nối. Nếu không có cái này, SonarQube có thể bị sập khi khởi động vì cơ sở dữ liệu chưa khả dụng.
  • Ba volume được đặt tên lưu trữ dữ liệu, plugin và nhật ký của SonarQube qua các lần khởi động lại và nâng cấp container. Một volume thứ tư lưu trữ dữ liệu PostgreSQL.
  • Cả hai dịch vụ chia sẻ một mạng cầu nối chuyên dụng (sonarnet) để SonarQube có thể tiếp cận PostgreSQL bằng tên máy chủ dịch vụ db.
  • Chính sách restart: unless-stopped đảm bảo cả hai container quay lại sau khi khởi động lại máy chủ.

Khởi động các dịch vụ:

docker compose up -d

Giám sát quá trình khởi động:

docker compose logs -f sonarqube

Sau 60 đến 120 giây, bạn sẽ thấy SonarQube is operational trong nhật ký. Mở http://localhost:9000, đăng nhập bằng admin/admin và thay đổi mật khẩu của bạn khi được nhắc.

Cấu hình: Biến môi trường và Volume

Image Docker của SonarQube hỗ trợ cấu hình rộng rãi thông qua các biến môi trường. Phần này bao gồm các biến quan trọng nhất cho các triển khai Docker.

Các biến môi trường thiết yếu

Các biến này được đặt trong khối environment của docker-compose.yml của bạn:

environment:
  # Kết nối cơ sở dữ liệu (bắt buộc cho sản xuất)
  SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonarqube
  SONAR_JDBC_USERNAME: sonar
  SONAR_JDBC_PASSWORD: sonar_password

  # Cài đặt máy chủ web
  SONAR_WEB_PORT: 9000
  SONAR_WEB_CONTEXT: /sonarqube  # Truy cập tại /sonarqube thay vì /
  SONAR_WEB_HOST: 0.0.0.0

  # Cài đặt bộ nhớ JVM
  SONAR_WEB_JAVAOPTS: "-Xmx512m -Xms128m"
  SONAR_CE_JAVAOPTS: "-Xmx1024 -Xms128m"
  SONAR_SEARCH_JAVAOPTS: "-Xmx512m -Xms512m"

  # Telemetry (tùy chọn - vô hiệu hóa nếu muốn)
  SONAR_TELEMETRY_ENABLE: "false"

Các tùy chọn bộ nhớ JVM được chia thành ba thành phần. SONAR_WEB_JAVAOPTS điều khiển máy chủ web, SONAR_CE_JAVAOPTS điều khiển máy chủ tính toán xử lý các báo cáo phân tích và SONAR_SEARCH_JAVAOPTS điều khiển phiên bản Elasticsearch tích hợp. Điều chỉnh các giá trị này dựa trên bộ nhớ có sẵn của máy chủ và kích thước của các cơ sở mã bạn phân tích.

Phân tích Volume

Mỗi volume SonarQube phục vụ một mục đích cụ thể:

Đường dẫn VolumeMục đíchNó lưu trữ gì
/opt/sonarqube/dataDữ liệu phân tíchChỉ mục Elasticsearch và tệp cơ sở dữ liệu tích hợp
/opt/sonarqube/extensionsPluginCác plugin ngôn ngữ đã cài đặt và tiện ích mở rộng cộng đồng
/opt/sonarqube/logsTệp nhật kýNhật ký máy chủ web, máy chủ tính toán và Elasticsearch

Không bao giờ gắn kết volume vào /opt/sonarqube/conf - image Docker quản lý cấu hình nội bộ thông qua các biến môi trường. Ghi đè thư mục conf có thể gây ra lỗi khởi động.

Sử dụng tệp môi trường

Để cấu hình sạch hơn, hãy chuyển các giá trị nhạy cảm vào tệp .env:

# .env
POSTGRES_USER=sonar
POSTGRES_PASSWORD=a_strong_password_here
POSTGRES_DB=sonarqube
SONAR_JDBC_URL=jdbc:postgresql://db:5432/sonarqube

Tham chiếu các biến này trong docker-compose.yml của bạn:

environment:
  SONAR_JDBC_URL: ${SONAR_JDBC_URL}
  SONAR_JDBC_USERNAME: ${POSTGRES_USER}
  SONAR_JDBC_PASSWORD: ${POSTGRES_PASSWORD}

Thêm .env vào .gitignore của bạn để giữ thông tin đăng nhập ra khỏi kiểm soát phiên bản.

Chạy quét đầu tiên với sonar-scanner

Với SonarQube đang chạy, bước tiếp theo là quét một dự án. SonarQube không phân tích mã một mình - nó nhận kết quả từ một máy quét phía máy khách. Tùy chọn dễ nhất cho thiết lập dựa trên Docker là chạy máy quét dưới dạng một container Docker.

Bước 1: Tạo dự án trong SonarQube

  1. Đăng nhập vào http://localhost:9000
  2. Nhấp vào Create Project và chọn Manually
  3. Nhập project key (ví dụ: my-app) và tên hiển thị
  4. Nhấp vào Set Up, sau đó chọn Locally
  5. Tạo token xác thực và sao chép nó

Bước 2: Tạo sonar-project.properties

Trong thư mục gốc của dự án bạn muốn quét, hãy tạo tệp sonar-project.properties:

# Xác định dự án
sonar.projectKey=my-app
sonar.projectName=My Application
sonar.projectVersion=1.0.0

# Cấu hình nguồn
sonar.sources=src
sonar.sourceEncoding=UTF-8

# Loại trừ
sonar.exclusions=\
  **/node_modules/**,\
  **/dist/**,\
  **/build/**,\
  **/coverage/**,\
  **/*.min.js

# Báo cáo độ phủ (nếu có)
sonar.javascript.lcov.reportPaths=coverage/lcov.info

Đừng bao gồm sonar.host.url hoặc sonar.token trong tệp này - hãy chuyển chúng dưới dạng biến môi trường để tránh commit thông tin đăng nhập.

Bước 3: Chạy máy quét

Bạn có thể chạy máy quét cục bộ hoặc qua Docker.

Sử dụng máy quét dựa trên Docker (không cần cài đặt cục bộ):

docker run --rm \
  -e SONAR_HOST_URL="http://host.docker.internal:9000" \
  -e SONAR_TOKEN="your-token-here" \
  -v "$(pwd):/usr/src" \
  sonarsource/sonar-scanner-cli

Tên máy chủ host.docker.internal cho phép container máy quét tiếp cận container SonarQube đang chạy trên máy chủ của bạn. Trên Linux, bạn có thể cần thêm --network host và sử dụng http://localhost:9000 thay thế.

Sử dụng máy quét đã cài đặt cục bộ:

# Cài đặt trên macOS
brew install sonar-scanner

# Chạy quét
sonar-scanner \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.token=your-token-here

Máy quét sẽ phân tích các tệp nguồn của bạn, tải kết quả lên SonarQube và in một URL nơi bạn có thể xem phân tích. Mở bảng điều khiển SonarQube để xem các chỉ số về lỗi, lỗ hổng, mùi code, độ phủ và trùng lặp.

Các cân nhắc cho môi trường sản xuất

Chạy SonarQube trong Docker cho một đội ngũ hoặc tổ chức cần thêm bảo mật vượt ra ngoài thiết lập Docker Compose cơ bản. Các cân nhắc sản xuất này giải quyết các vấn đề về bộ nhớ, tinh chỉnh cơ sở dữ liệu, cấu hình reverse proxy và nâng cấp.

Giới hạn bộ nhớ và tài nguyên

Đặt giới hạn tài nguyên rõ ràng trong tệp Docker Compose của bạn để ngăn SonarQube tiêu thụ tất cả bộ nhớ có sẵn trên máy chủ:

services:
  sonarqube:
    image: sonarqube:lts-community
    deploy:
      resources:
        limits:
          memory: 4G
          cpus: "2.0"
        reservations:
          memory: 2G
          cpus: "1.0"
    # ... phần còn lại của cấu hình

Đối với container PostgreSQL, 1 GB bộ nhớ thường đủ trừ khi bạn có hàng trăm dự án:

  db:
    image: postgres:16
    deploy:
      resources:
        limits:
          memory: 1G

Tinh chỉnh cơ sở dữ liệu

Cấu hình PostgreSQL mặc định khá bảo thủ. Để có hiệu suất tốt hơn với SonarQube, hãy thêm các tham số tinh chỉnh:

  db:
    image: postgres:16
    command:
      - "postgres"
      - "-c"
      - "shared_buffers=256MB"
      - "-c"
      - "effective_cache_size=768MB"
      - "-c"
      - "work_mem=16MB"
      - "-c"
      - "maintenance_work_mem=128MB"
      - "-c"
      - "max_connections=100"

Các giá trị này hoạt động tốt cho một phiên bản SonarQube phục vụ 10 đến 50 dự án. Tăng tỷ lệ shared_bufferseffective_cache_size cho các triển khai lớn hơn.

Reverse Proxy với Nginx

Đối với các triển khai sản xuất, hãy đặt SonarQube sau một reverse proxy với chấm dứt SSL. Thêm dịch vụ Nginx vào tệp Docker Compose của bạn:

  nginx:
    image: nginx:alpine
    container_name: sonarqube-proxy
    ports:
      - "443:443"
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      - sonarqube
    networks:
      - sonarnet
    restart: unless-stopped

Tạo tệp nginx.conf:

upstream sonarqube {
    server sonarqube:9000;
}

server {
    listen 80;
    server_name sonar.yourcompany.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name sonar.yourcompany.com;

    ssl_certificate /etc/nginx/certs/fullchain.pem;
    ssl_certificate_key /etc/nginx/certs/privkey.pem;

    client_max_body_size 50M;

    location / {
        proxy_pass http://sonarqube;
        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 https;
    }
}

Sau khi thiết lập proxy, hãy cho SonarQube biết về URL công khai của nó bằng cách thêm biến môi trường này:

environment:
  SONAR_WEB_CONTEXT: /
  sonar.core.serverBaseURL: https://sonar.yourcompany.com

Chiến lược sao lưu

Sao lưu cả dữ liệu PostgreSQL và các volume SonarQube thường xuyên:

# Sao lưu PostgreSQL
docker exec sonarqube-db pg_dump -U sonar sonarqube > backup_$(date +%Y%m%d).sql

# Sao lưu volume (dừng SonarQube trước để đảm bảo tính nhất quán)
docker compose stop sonarqube
docker run --rm \
  -v sonarqube-docker_sonarqube_data:/data \
  -v $(pwd)/backups:/backup \
  alpine tar czf /backup/sonarqube_data_$(date +%Y%m%d).tar.gz -C /data .
docker compose start sonarqube

Nâng cấp SonarQube

Để nâng cấp lên phiên bản mới:

# Dừng stack
docker compose down

# Cập nhật thẻ image trong docker-compose.yml
# ví dụ: sonarqube:lts-community -> sonarqube:2025.1-community

# Kéo image mới và khởi động lại
docker compose pull
docker compose up -d

SonarQube xử lý việc di chuyển cơ sở dữ liệu tự động khi khởi động. Luôn sao lưu cơ sở dữ liệu của bạn trước khi nâng cấp. Kiểm tra ghi chú phát hành SonarQube để biết bất kỳ thay đổi phá vỡ nào giữa các phiên bản.

Xử lý sự cố các vấn đề phổ biến

SonarQube bị sập khi khởi động với lỗi "max virtual memory"

Đây là vấn đề Docker phổ biến nhất. Elasticsearch tích hợp của SonarQube yêu cầu vm.max_map_count phải ít nhất là 524288.

# Kiểm tra giá trị hiện tại
sysctl vm.max_map_count

# Đặt nó (chỉ Linux)
sudo sysctl -w vm.max_map_count=524288

Trên Docker Desktop cho macOS hoặc Windows, hãy tăng mức cấp phát bộ nhớ trong cài đặt Docker Desktop lên ít nhất 4 GB.

Kết nối cơ sở dữ liệu bị từ chối

Nếu nhật ký SonarQube hiển thị Connection refused hoặc FATAL: database does not exist, hãy kiểm tra các mục sau:

  1. Xác minh PostgreSQL đang chạy: docker compose ps db
  2. Xác nhận tên cơ sở dữ liệu, tên người dùng và mật khẩu khớp giữa các biến môi trường của SonarQube và PostgreSQL
  3. Đảm bảo cả hai container đều trên cùng mạng Docker
  4. Đợi kiểm tra sức khỏe của PostgreSQL vượt qua trước khi SonarQube khởi động (sử dụng điều kiện depends_on được hiển thị ở trên)

Máy quét không thể tiếp cận SonarQube từ container khác

Khi chạy máy quét dưới dạng container Docker, nó không thể tiếp cận localhost trên máy chủ. Sử dụng một trong các cách tiếp cận sau:

  • Trên macOS và Windows: sử dụng http://host.docker.internal:9000
  • Trên Linux với mạng cầu nối mặc định: sử dụng địa chỉ IP của container (tìm nó bằng docker inspect sonarqube)
  • Nếu cả hai container đều trên cùng mạng Docker: sử dụng tên dịch vụ http://sonarqube:9000

Các giải pháp thay thế trên đám mây cho Docker tự lưu trữ

Chạy SonarQube trong Docker mang lại cho bạn toàn quyền kiểm soát dữ liệu và cơ sở hạ tầng, nhưng điều đó cũng có nghĩa là bạn chịu trách nhiệm bảo trì, cập nhật, sao lưu và mở rộng. Nếu bạn thích một trải nghiệm được quản lý, hãy cân nhắc các giải pháp thay thế này.

SonarQube Cloud

SonarQube Cloud (trước đây là SonarCloud) là phiên bản SaaS của SonarQube, được lưu trữ và quản lý bởi SonarSource. Nó sử dụng cùng một động cơ phân tích nhưng loại bỏ tất cả quản lý cơ sở hạ tầng. SonarQube Cloud miễn phí cho các dự án mã nguồn mở và bắt đầu từ $14 mỗi tháng cho các kho lưu trữ riêng tư.

CodeAnt AI

CodeAnt AI tiếp cận chất lượng mã theo một cách khác bằng cách kết hợp phân tích tĩnh với xem xét mã được hỗ trợ bởi AI. Với giá từ $24 đến $40 cho mỗi người dùng mỗi tháng, CodeAnt AI cung cấp các bài đánh giá PR tự động, quét bảo mật, kiểm tra chất lượng mã và tự động sửa lỗi mà không cần quản lý cơ sở hạ tầng.

Kết luận

Docker là cách đáng tin cậy nhất để triển khai SonarQube. Một lệnh docker run duy nhất giúp bạn bắt đầu trong vài phút và một tệp Docker Compose với PostgreSQL mang lại cho bạn thiết lập cấp sản xuất lưu trữ dữ liệu, xử lý khởi động lại và mở rộng cùng đội ngũ của bạn.

Dưới đây là tóm tắt những gì chúng tôi đã đề cập:

  • Khởi động nhanh - lệnh docker run một dòng để đánh giá
  • Docker Compose - thiết lập hoàn chỉnh với PostgreSQL, volume được đặt tên và kiểm tra sức khỏe
  • Cấu hình - biến môi trường, tinh chỉnh JVM và quản lý volume
  • Thiết lập máy quét - chạy sonar-scanner qua Docker hoặc cài đặt cục bộ
  • Bảo mật sản xuất - giới hạn tài nguyên, tinh chỉnh cơ sở dữ liệu, reverse proxy Nginx, sao lưu và nâng cấp
  • Xử lý sự cố - giải pháp cho các vấn đề SonarQube liên quan đến Docker phổ biến nhất
Bài viết được tổng hợp và biên soạn bằng AI từ các nguồn tin tức công nghệ. Nội dung mang tính tham khảo. Xem bài gốc ↗