SonarQube CI/CD Code Quality Pipeline
Run SonarQube locally and automate code quality checks with GitHub Actions.
Introduction
30 Second Summary
Every time a developer pushes code without automated checks, bugs and security vulnerabilities can slip through unnoticed. Professional engineering teams solve this by running static analysis tools that catch issues before code reaches production.
In this project, you will set up SonarQube to automatically scan your code for bugs, vulnerabilities, and code smells. You will then wire it into a GitHub Actions pipeline so every push triggers a quality check.
What You'll Build
A complete code quality pipeline that runs static code analysis automatically via CI/CD every time you push code to GitHub.
By the end of this project, you'll have:
- A running SonarQube Community Build instance on your local machine powered by Docker.
- A sample Python project with intentional code quality issues for SonarQube to detect.
- A GitHub Actions workflow that triggers automated code analysis on every push to your repository.
- Secret Mission: Configure a custom quality gate that fails your pipeline when code quality drops below your standards.
Are there any prerequisites?
You should have basic command line familiarity and a GitHub account. No prior experience with Docker or SonarQube is needed.
Set Up Docker and Run SonarQube
SonarQube needs a server to run its analysis engine and store results. Instead of installing it directly on your machine, you will use Docker to run SonarQube inside a container.
Docker packages software into isolated environments called containers. This means you can spin up a full SonarQube server with one command and remove it cleanly when you are done.
In this step, get ready to:
- Install Docker Desktop and verify it is running.
- Start a SonarQube Community Build container.
- Create a project in SonarQube and generate an authentication token.
Install and verify Docker
Docker Desktop bundles the Docker Engine, CLI, and a graphical interface for managing containers. SonarQube requires Docker Engine version 20.10 or above.
- Check whether Docker is already installed by opening your terminal and running this command:
docker --version
✔️ I see version 20.10 or higher
Docker is ready to go. Make sure Docker Desktop is running (you should see the whale icon in your menu bar or system tray) before continuing.
ⓧ I see an older version
You have Docker installed, but need a newer version. Update Docker Desktop to get the latest Engine:
- Open Docker Desktop.
- Click the gear icon to open Settings.
- Select Software updates and click Check for updates.
- Download and install the update, then restart Docker Desktop.
- Run docker --version again to confirm the version is 20.10 or higher.
ⓧ Command not found
Docker is not installed yet. Follow these steps to install Docker Desktop:
- Visit the Docker Desktop download page: https://www.docker.com/products/docker-desktop/
- Download the installer for your operating system (macOS Apple Silicon, macOS Intel, or Windows).
- Open the downloaded file and follow the installation prompts.
- Once installed, launch Docker Desktop.
- Wait for the whale icon to appear in your menu bar (macOS) or system tray (Windows). This means Docker is running.
- Run docker --version in your terminal to confirm installation.
- Verify Docker is fully functional by running this command:
docker info
You should see a wall of system information including the server version, number of containers, and storage driver. This confirms Docker Engine is running.
Seeing 'Cannot connect to the Docker daemon'?
This means Docker Desktop is not running. Open Docker Desktop and wait for the whale icon to appear in your menu bar or system tray before trying again.
help me fix Docker daemon connection errors
Start SonarQube Community Build
SonarQube Community Build is the free, open-source edition that supports 21 languages including Python. You will run it as a Docker container using the embedded H2 database, which is suitable for learning and testing.
- Start the SonarQube container by running this command:
docker run -d --name sonarqube \
-p 9000:9000 \
-v sonarqube_data:/opt/sonarqube/data \
-v sonarqube_extensions:/opt/sonarqube/extensions \
-v sonarqube_logs:/opt/sonarqube/logs \
sonarqube:community
What does this command do?
- -d runs the container in the background so you get your terminal back.
- --name sonarqube gives the container a friendly name you can reference later.
- -p 9000:9000 maps port 9000 on your machine to port 9000 inside the container.
- -v flags create persistent volumes so your data survives container restarts.
- sonarqube:community pulls the official Community Build image from Docker Hub.
- Wait approximately 1-2 minutes for SonarQube to finish starting up. You can check its status by running:
docker logs sonarqube --tail 5
When you see a line containing "SonarQube is operational", the server is ready.
- Open your browser and navigate to http://localhost:9000.
- Log in with the default credentials: username admin and password admin.
- SonarQube will prompt you to change your password. Choose a new password and click Update.
You should now see the SonarQube dashboard with a welcome message and no projects listed yet.
Page not loading at localhost:9000?
SonarQube takes 1-2 minutes to start. Run docker logs sonarqube --tail 10 to check startup progress. If you see errors about memory, try closing other applications to free up RAM. SonarQube requires approximately 2GB.
help me troubleshoot SonarQube not loading
Create a project and generate a token
SonarQube organizes code analysis results by project. You need to create one so the scanner knows where to send its findings. You also need an authentication token for the scanner to prove it has permission to submit results.
- On the SonarQube dashboard, click Create a local project.
- In the Project display name field, enter my-python-app.
- In the Project key field, enter my-python-app.
- Select Use the global setting for the new code definition.
- Click Create.
What is a project key?
The project key is a unique identifier that the scanner uses to match your local code to the right project in SonarQube. It appears in configuration files and API calls, so keeping it short and memorable helps.
- On the analysis method page, select Locally.
- Under the token section, enter github-actions-token as the token name.
- Click Generate.
- Copy the generated token value and save it somewhere safe (a text file or notes app). You will need this token in a later step.
Why save this token?
This token authenticates the SonarQube scanner when it submits analysis results. You will use it both for running scans locally and for configuring GitHub Actions later in the project.
You should now see your my-python-app project listed on the SonarQube dashboard with a status of "Not yet analyzed".
Don't see the project listed?
Click the SonarQube logo in the top-left corner to return to the main dashboard. Your project should appear in the projects list. If it does not, retrace the creation steps and make sure you clicked Create.
help me find my SonarQube project
Your SonarQube server is up and ready to analyze code. Next up, you will create a sample Python project with intentional code issues for SonarQube to detect.
Create a Sample Project with Code Issues
Your SonarQube server is up and running, ready to analyze code. Now you need to give it something to scan.
In this step, you will create a GitHub repository with a sample Python project that contains intentional code quality issues. These issues include bugs, security vulnerabilities, and code smells that SonarQube will detect during analysis.
In this step, get ready to:
- Create a public GitHub repository and clone it locally.
- Write Python files with intentional code quality issues for SonarQube to detect.
- Push the code to GitHub.
Create a GitHub repository and clone it locally
You need a GitHub repository to store your sample project. Later, you will wire up GitHub Actions to run SonarQube analysis every time you push code to this repo.
- Open your browser and navigate to https://github.com/new.
- In the Repository name field, type sonarqube-demo.
- Set the visibility to Public.
- Check the Add a README file box to initialize the repository.
- Click Create repository.
Why a public repository?
GitHub Actions is free for public repositories. Making this repo public means you can use unlimited Actions minutes for your CI/CD pipeline at no cost.
- Open your terminal. Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Terminal (macOS) or PowerShell (Windows) and press Enter to open it.
- Move to your Desktop by running this command:
cd ~/Desktop
- Clone your new repository by running this command:
git clone https://github.com/[[GITHUB_USERNAME="your-github-username"]]/sonarqube-demo.git
- Move into the cloned repository folder by running:
cd sonarqube-demo
- Confirm you are inside the sonarqube-demo folder by running:
ls
You should see a README.md file listed in the output.
Clone command failed?
Make sure you replaced the GitHub username placeholder in the clone URL with your actual GitHub username. The repository must exist on GitHub before you can clone it.
If you see a permission error, you may need to configure Git authentication. Help me set up Git authentication for cloning.
Write the project configuration and code
The sonar-project.properties file tells the SonarQube scanner where to find your code and how to identify your project. The Python files contain intentional bugs, code smells, and security issues that SonarQube will flag during analysis.
- Create the SonarQube configuration file by running:
touch sonar-project.properties app.py utils.py
- Confirm the files exist by running:
ls
You should see README.md, sonar-project.properties, app.py, and utils.py in the output.
- Open the sonarqube-demo folder in your code editor. If you are using VS Code, run:
code .
- Open sonar-project.properties and paste the following configuration:
sonar.projectKey=my-python-app
sonar.projectName=my-python-app
sonar.sources=.
sonar.sourceEncoding=UTF-8
sonar.python.version=3.12
sonar.exclusions=**/.github/**
What does this configuration do?
Each line tells the SonarQube scanner something about your project:
- sonar.projectKey and sonar.projectName link this scan to the project you created in SonarQube.
- sonar.sources=. tells the scanner to analyze all files in the current directory.
- sonar.python.version=3.12 specifies which Python version rules to apply.
- sonar.exclusions tells the scanner to skip the GitHub Actions workflow folder.
- Open app.py and paste the following code:
import os
import hashlib
def get_user_data(user_id):
"""Fetch user data - contains intentional code smells."""
# Bug: potential None reference
users = None
if user_id > 0:
users = {"1": "Alice", "2": "Bob"}
# Code smell: using format string with user input (security hotspot)
query = "SELECT * FROM users WHERE id = '%s'" % user_id
return users[str(user_id)]
def calculate_score(values):
"""Calculate score - contains complexity issues."""
total = 0
# Code smell: overly complex nested logic
for v in values:
if v > 0:
if v < 10:
if v % 2 == 0:
total += v * 2
else:
total += v
else:
if v > 100:
total += v / 2
else:
total += v * 1.5
else:
total += 0
return total
def process_password(password):
"""Process password - contains security issues."""
# Security: using weak hash algorithm
hashed = hashlib.md5(password.encode()).hexdigest()
# Security: hardcoded credential
admin_password = "admin123"
if hashed == admin_password:
return True
return False
def unused_function():
"""This function is never called - dead code."""
x = 42
y = x
return None
if __name__ == "__main__":
print(get_user_data(1))
print(calculate_score([1, 2, 3, 15, 150]))
print(process_password("test"))
What issues are in this file?
This file is intentionally full of problems for SonarQube to catch:
- get_user_data has a potential None reference bug and a SQL injection security hotspot.
- calculate_score has deeply nested logic that increases cognitive complexity.
- process_password uses the weak MD5 hash algorithm and contains a hardcoded credential.
- unused_function is dead code that is never called.
- The os import at the top is unused.
- Open utils.py and paste the following code:
import sys
import os
import json
# Code smell: unused imports (sys, os, json are not used)
def duplicate_logic_a(items):
"""First instance of duplicated code."""
result = []
for item in items:
if item is not None:
processed = str(item).strip().lower()
if len(processed) > 0:
result.append(processed)
return result
def duplicate_logic_b(items):
"""Second instance of duplicated code - nearly identical to above."""
result = []
for item in items:
if item is not None:
processed = str(item).strip().lower()
if len(processed) > 0:
result.append(processed)
return result
def risky_eval(user_input):
"""Security vulnerability: using eval with user input."""
# Security: code injection risk
result = eval(user_input)
return result
def too_many_params(a, b, c, d, e, f, g, h):
"""Code smell: too many parameters."""
return a + b + c + d + e + f + g + h
What issues are in utils.py?
This file demonstrates additional categories of code quality problems:
- Three unused imports (sys, os, json) that add clutter.
- duplicate_logic_a and duplicate_logic_b are nearly identical functions that SonarQube flags as duplicated code.
- risky_eval uses eval() on user input, which is a critical code injection vulnerability.
- too_many_params takes 8 parameters, which is a maintainability code smell.
- Save all three files (sonar-project.properties, app.py, utils.py).
✔️ Awesome, I've got everything!
Great. Make sure you have saved all three files before moving on.
ⓧ I'd like to double check the full code
Here is the complete content for each file. Compare yours against these:
sonar.projectKey=my-python-app
sonar.projectName=my-python-app
sonar.sources=.
sonar.sourceEncoding=UTF-8
sonar.python.version=3.12
sonar.exclusions=**/.github/**
import os
import hashlib
def get_user_data(user_id):
"""Fetch user data - contains intentional code smells."""
# Bug: potential None reference
users = None
if user_id > 0:
users = {"1": "Alice", "2": "Bob"}
# Code smell: using format string with user input (security hotspot)
query = "SELECT * FROM users WHERE id = '%s'" % user_id
return users[str(user_id)]
def calculate_score(values):
"""Calculate score - contains complexity issues."""
total = 0
# Code smell: overly complex nested logic
for v in values:
if v > 0:
if v < 10:
if v % 2 == 0:
total += v * 2
else:
total += v
else:
if v > 100:
total += v / 2
else:
total += v * 1.5
else:
total += 0
return total
def process_password(password):
"""Process password - contains security issues."""
# Security: using weak hash algorithm
hashed = hashlib.md5(password.encode()).hexdigest()
# Security: hardcoded credential
admin_password = "admin123"
if hashed == admin_password:
return True
return False
def unused_function():
"""This function is never called - dead code."""
x = 42
y = x
return None
if __name__ == "__main__":
print(get_user_data(1))
print(calculate_score([1, 2, 3, 15, 150]))
print(process_password("test"))
import sys
import os
import json
# Code smell: unused imports (sys, os, json are not used)
def duplicate_logic_a(items):
"""First instance of duplicated code."""
result = []
for item in items:
if item is not None:
processed = str(item).strip().lower()
if len(processed) > 0:
result.append(processed)
return result
def duplicate_logic_b(items):
"""Second instance of duplicated code - nearly identical to above."""
result = []
for item in items:
if item is not None:
processed = str(item).strip().lower()
if len(processed) > 0:
result.append(processed)
return result
def risky_eval(user_input):
"""Security vulnerability: using eval with user input."""
# Security: code injection risk
result = eval(user_input)
return result
def too_many_params(a, b, c, d, e, f, g, h):
"""Code smell: too many parameters."""
return a + b + c + d + e + f + g + h
Push the code to GitHub
With all three files written, you need to commit them and push to your remote repository on GitHub.
- Stage all files, commit, and push by running these commands:
git add .
git commit -m "Add sample project with code quality issues"
git push origin main
What do these commands do?
- git add . stages all new and modified files for commit.
- git commit -m creates a snapshot of your staged files with a descriptive message.
- git push origin main uploads your commit to the main branch of your GitHub repository.
- Verify the push succeeded by visiting your repository at https://github.com/your-github-username/sonarqube-demo in your browser.
You should see sonar-project.properties, app.py, and utils.py listed in your repository files.
Push rejected or authentication error?
If you see a rejected push, make sure you are pushing to the correct branch. The default branch may be main. Run git branch to check which branch you are on.
If you see an authentication error, GitHub requires a personal access token or SSH key for pushing. Help me fix a GitHub push authentication error.
Your sample project is on GitHub and ready for analysis. Next, you will configure GitHub Actions to automatically trigger a SonarQube scan every time you push code.
Configure GitHub Actions for SonarQube Analysis
You have a SonarQube server running and a project loaded with intentional code issues ready to be caught.
Now it is time to automate the analysis so every push to your repository triggers a scan without any manual effort. In this step, you will connect your GitHub repository to SonarQube using GitHub Actions, GitHub's built-in CI/CD platform.
In this step, get ready to:
- Add your SonarQube token and server URL to GitHub as secrets and variables.
- Create a GitHub Actions workflow file that runs the SonarQube scan action.
- Push the workflow and confirm it appears in the Actions tab.
Add secrets and variables to your GitHub repository
GitHub Actions needs two pieces of information to communicate with SonarQube: an authentication token and the server URL. You store these as repository-level secrets and variables so they stay out of your code.
- Open your sonarqube-demo repository on GitHub in your browser.
- Click Settings in the repository header. If you do not see the Settings tab, open the dropdown menu and select Settings.
- In the left sidebar under Security, select Secrets and variables, then click Actions.
- Click the Secrets tab.
- Click New repository secret.
- In the Name field, enter SONAR_TOKEN.
- In the Secret field, paste the token you generated in Step 1 (the github-actions-token value from SonarQube).
- Click Add secret.
Now add the server URL as a repository variable.
- On the same Secrets and variables page, click the Variables tab.
- Click New repository variable.
- In the Name field, enter SONAR_HOST_URL.
- In the Value field, enter your SonarQube server URL (for local testing this is http://localhost:9000).
- Click Add variable.
Why a secret AND a variable?
The token authenticates the scan, so it must stay encrypted. GitHub secrets are never exposed in logs.
The host URL is not sensitive, so it goes in a plain repository variable. This makes it easier to update later without touching secrets.
What about localhost?
GitHub Actions runners are remote machines. They cannot reach localhost:9000 on your computer.
You will run the scan locally in the next step to verify everything works. The workflow file is ready for when your SonarQube server is deployed to an internet-accessible address (or exposed via a tunnel service).
Create the GitHub Actions workflow file
A workflow file tells GitHub Actions what to do and when to do it. You will create one that triggers the SonarQube scan on every push to main and on pull requests.
- Return to your terminal in the sonarqube-demo directory.
- Create the workflow directory by running this command:
mkdir -p .github/workflows
- Confirm the directory exists by running:
ls .github/workflows
You should see an empty directory listing with no errors.
- Create the workflow file by running:
touch .github/workflows/sonarqube.yml
- Open .github/workflows/sonarqube.yml in your text editor and paste the following workflow configuration:
name: SonarQube Analysis
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]
jobs:
sonarqube:
name: SonarQube Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v8.0.0
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
What does this workflow do?
- on: push and on: pull_request define the triggers. The scan runs every time you push to main or open/update a pull request.
- actions/checkout@v6 clones your repository onto the runner. fetch-depth: 0 fetches the full git history so SonarQube can track changes between commits.
- SonarSource/sonarqube-scan-action@v8.0.0 is the official SonarSource action that runs the scanner against your code and sends results to your SonarQube server.
- The env block injects the secret token and host URL you configured earlier.
- Save .github/workflows/sonarqube.yml.
File not saving to the right place?
Make sure the file is inside .github/workflows/ (note the leading dot). Folders starting with a dot are hidden by default on macOS and Linux.
Run ls -la .github/workflows/ to confirm sonarqube.yml is listed.
Why is my workflow file not being detected?
✔️ Awesome, I've got everything!
Great. Double check you have saved the file before moving on.
ⓧ I'd like to double check the full code
Here is the complete .github/workflows/sonarqube.yml file:
name: SonarQube Analysis
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]
jobs:
sonarqube:
name: SonarQube Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v8.0.0
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ vars.SONAR_HOST_URL }}
Commit and push the workflow
With the workflow file created, push it to GitHub so it appears in your repository's Actions tab.
- Stage, commit, and push the workflow file by running these commands:
git add .github/workflows/sonarqube.yml
git commit -m "Add SonarQube analysis workflow"
git push
What should I see?
Your terminal should show a successful push to the main branch. Since GitHub Actions cannot reach your local SonarQube server, the workflow run will fail at the scan step. That is expected for now.
- Return to your sonarqube-demo repository on GitHub in your browser.
- Click the Actions tab at the top of the repository.
You should see a workflow run listed called SonarQube Analysis. This confirms GitHub detected your workflow file.
Don't see the Actions tab or workflow?
Make sure your repository is public. GitHub Actions is free for public repositories but may need to be enabled for private ones.
Confirm the file path is exactly .github/workflows/sonarqube.yml. Any typo in the directory name prevents GitHub from detecting the workflow.
Why isn't my GitHub Actions workflow showing up?
Your CI/CD pipeline is wired up. Next, you will run the SonarQube scan locally to verify that your code gets analyzed and explore the results dashboard.
Run Analysis and Review Results
In the previous step, you configured a GitHub Actions workflow that will scan your code automatically on every push.
Now it is time to see SonarQube in action. Since GitHub Actions runners cannot reach your local http://localhost:9000 server, you will run the scan locally first to verify everything works. Then you will explore the results dashboard to understand what SonarQube found in your intentionally flawed code.
In this step, get ready to:
- Run the SonarScanner CLI via Docker against your local SonarQube server.
- Review bugs, vulnerabilities, and code smells on the SonarQube dashboard.
- Understand how quality gates enforce code standards in a pipeline.
Run the SonarQube scan locally
GitHub Actions runners operate on remote servers that have no way to connect to localhost:9000 on your machine. To verify the scanner and your project configuration work correctly, you will run the scan locally using the official sonarsource/sonar-scanner-cli Docker image.
- In your terminal, make sure you are inside your sonarqube-demo project folder (the one containing sonar-project.properties).
- Run the SonarScanner CLI against your local SonarQube server by running this command:
docker run --rm \
--network host \
-e SONAR_HOST_URL="http://localhost:9000" \
-e SONAR_TOKEN="your-token-here" \
-v "$(pwd):/usr/src" \
sonarsource/sonar-scanner-cli
- Replace your-token-here with the project token you generated in Step 1 (the one you named github-actions-token).
What does this command do?
- --rm removes the scanner container after the scan finishes so it does not clutter your system.
- --network host lets the scanner container use your machine's network directly, so it can reach localhost:9000 where SonarQube is running.
- The -e flags pass the server URL and authentication token as environment variables.
- -v "$(pwd):/usr/src" mounts your current project folder into the container at /usr/src, which is where the scanner looks for source code by default.
The scan takes about 30-60 seconds. You should see log output from the scanner showing it analyzing your Python files, followed by a success message indicating the analysis results have been uploaded to your SonarQube server.
Seeing a connection refused error?
- Make sure your SonarQube container is still running. Run docker ps and check that the sonarqube container appears in the list.
- Verify you can access http://localhost:9000 in your browser. If not, restart it with docker start sonarqube and wait 1-2 minutes.
- On macOS, --network host behaves differently than on Linux. If the connection fails, try replacing http://localhost:9000 with http://host.docker.internal:9000 in the command and remove the --network host flag.
Help me troubleshoot my SonarScanner connection error.
Review the analysis results in the SonarQube dashboard
Now that the scan is complete, SonarQube has analyzed every line of your Python code and categorized the issues it found.
- Open http://localhost:9000 in your browser.
- Click on your my-python-app project to open it.
You will land on the Overview page, which shows the overall health of your project at a glance.
- Review the Overview page. It displays a summary of detected issues grouped by severity, along with ratings for Reliability, Security, and Maintainability.
- Click the Issues tab in the project navigation. This shows every individual bug, vulnerability, and code smell detected in your files.
- Click on any issue to see the exact line of code where it was found, along with an explanation of why it is a problem.
- Click the Measures tab. This shows metrics like code complexity, duplications, and maintainability ratings.
What kinds of issues should I see?
Your intentional code issues should produce several findings. In app.py, SonarQube should flag the potential None reference bug, the SQL injection security hotspot, the use of md5 for password hashing, and the hardcoded credential.
In utils.py, it should detect the unused imports, duplicated code blocks, the dangerous eval() call, and the function with too many parameters. The exact number of issues may vary depending on SonarQube's rule set.
Understand quality gates
A quality gate is a set of conditions your code must pass before it is considered acceptable. When integrated into a CI/CD pipeline, a failing quality gate can automatically block merges or deployments.
- In the SonarQube navigation bar at the top, click Quality Gates.
- Click on the Sonar way quality gate. This is the default gate that comes pre-configured with SonarQube.
- Review the conditions listed. These define the thresholds your code must meet to pass the gate.
What is the Sonar way quality gate?
The default Sonar way quality gate focuses on new code. It checks conditions like: no new bugs introduced, no new vulnerabilities, and maintainability rating stays at A.
This approach encourages "clean as you code." Even if existing code has issues, the gate ensures that every new change meets quality standards. In a real pipeline, failing this gate means the pull request cannot merge until the developer fixes the issues.
- Return to your my-python-app project and check the quality gate status on the Overview page. You should see whether your project passed or failed the default gate.
You have now seen SonarQube analyze real code and surface actionable findings. Next up, you will take quality enforcement to the next level by creating a custom quality gate that can fail your pipeline when standards are not met.
Secret mission
Configure a Custom Quality Gate
You have a working SonarQube scan, but right now it only reports issues. It does not block bad code from reaching production. In this secret mission, you will create a custom quality gate with strict conditions and wire it into your GitHub Actions workflow so that the pipeline fails when code quality drops below your standards.
Clean Up Your Resources
Clean Up Your Resources
This project runs entirely locally using Docker, so there are no ongoing cloud costs. The SonarQube container and volumes consume local disk space and RAM while running.
Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
Resources you used:
- Docker container sonarqube running on port 9000.
- Docker volumes: sonarqube_data, sonarqube_extensions, sonarqube_logs.
- GitHub repository sonarqube-demo (public, free to host).
- Local project folder sonarqube-demo on your Desktop.
Keep everything running
No action needed. Choose this if you are still actively building or want to continue experimenting with SonarQube analysis.
- Your SonarQube container stays running and accessible at http://localhost:9000.
- The container uses approximately 2GB of RAM while running.
- Your GitHub repository stays available for future pushes and workflow runs.
Pause - I'll come back to this later
Stop the SonarQube container to free up RAM. Your data is preserved in the Docker volumes, so you can restart later without losing anything.
- Stop the SonarQube container by running:
docker stop sonarqube
- When you are ready to resume, restart the container by running:
docker start sonarqube
After restarting, SonarQube will be available again at http://localhost:9000 within 1-2 minutes.
Delete - I don't want to use this again
Remove all project resources and start fresh. This permanently deletes your SonarQube data, analysis history, and local project files.
- Remove the Docker container and all associated volumes by running:
docker rm -f sonarqube && docker volume rm sonarqube_data sonarqube_extensions sonarqube_logs
- Delete your local project folder by running:
cd ~/Desktop
rm -rf sonarqube-demo
- Delete the GitHub repository:
- Go to your sonarqube-demo repository on GitHub.
- Click Settings in the top navigation bar.
- Scroll down to the Danger Zone section.
- Click Delete this repository and follow the confirmation prompts.
Nice Work!
Nice Work!
You just built a complete code quality pipeline using SonarQube and GitHub Actions. Every push to your repository now triggers automated static analysis that catches bugs, vulnerabilities, and code smells before they reach production.
You've learned how to:
- Set up and ran SonarQube Community Build locally using Docker, including configuring projects and generating authentication tokens.
- Configured a GitHub Actions workflow with the official SonarQube scan action to automatically analyze code on every push to your repository.
- Ran a static code analysis and explored the SonarQube dashboard to identify bugs, security vulnerabilities, and code smells in a Python project.
- Secret Mission: Created a custom quality gate with strict conditions and wired it into the pipeline to fail builds when code quality drops below your standards.
Ready to quiz yourself?