CodeChecker 6
Overview
CodeChecker is an open-source static analysis platform. It drives established analysers over your C and C++ source, collects everything they report into a single database, and gives your team a web interface for triaging the results. You can mark a finding as a real bug or a false positive, leave a comment, and track whether a defect is new, still outstanding, or fixed compared with a previous run.
The value is in the workflow as well as the analysis. Running clang-tidy by hand produces a wall of text that is lost when the terminal closes. CodeChecker stores each analysis as a named run, so you can compare today's results with last week's, suppress a false positive once, and give reviewers a link to a specific defect with its full execution path highlighted in the source.
This SecureAnyCloud image serves CodeChecker 6.28.2 on a hardened Ubuntu 24.04 LTS base, patched at build time. Clang Static Analyzer, Clang-Tidy and Cppcheck are installed and pinned, so you can analyse a project as soon as the VM boots, without installing a compiler first. The server runs in its own Python virtualenv as a dedicated service account, listens only on the loopback interface, and is published by nginx on port 80.
Authentication is switched on. Upstream CodeChecker ships with authentication disabled, so anyone who can reach the port can read every stored finding, including file paths, source snippets and defect locations from your own code. This image does not ship that configuration. A unique administrator credential is generated on the first boot of every VM, only a salted SHA-512 hash of it is written to disk, and the server refuses to start at all if no credential is configured.
The image includes a working sample. A small C project with four deliberate defects ships with the image and is analysed at build time. First boot stores that analysis as a run called sac-sample-c, so the first time you sign in you see real findings with real bug paths rather than an empty database. You can re-run the whole cycle at any time with a single command, and you can delete the run once your own code is in the database.
What you get:
- CodeChecker 6.28.2 in a dedicated Python 3.12 virtualenv, managed by systemd
- The analyser toolchain: Clang Static Analyzer and Clang-Tidy 18.1.3, Cppcheck 2.13.0, GCC 13.3.0
- The web interface and the full API on
:80, behind CodeChecker's own authentication from the first request - A per-VM administrator credential generated on first boot, holding the
SUPERUSERpermission - Only a salted SHA-512 hash of that credential stored on disk, never the password itself
- The server bound to
127.0.0.1:8001only, never exposed directly to the network - A bundled SQLite database, so there is no external database service to run or pay for
- A sample analysis stored on first boot, so you can confirm the product works on day one
- An open
/liveendpoint for Azure Load Balancer health probes - 24/7 SecureAnyCloud support
Trademark notice: CodeChecker is an open-source project maintained by Ericsson AB and released under Apache-2.0 WITH LLVM-exception. "Ericsson" is a trademark of Telefonaktiebolaget LM Ericsson. "LLVM" and "Clang" are trademarks of the LLVM Foundation. They are used in this guide only to describe the software's provenance and the analysers it invokes. SecureAnyCloud is not affiliated with, endorsed by, or sponsored by any of them.
Prerequisites
Before you deploy, make sure you have:
- An Azure subscription
- A VM size with at least 2 vCPUs and 4 GiB of memory.
Standard_B2sis the recommended size and is the size this guide uses. - Inbound TCP 80 open to the networks you want to serve, and TCP 22 open if you want SSH access
Step 1 - Deploy from the Azure Marketplace
Search the Azure Marketplace for CodeChecker 6 on Ubuntu 24.04 by SecureAnyCloud, and select Create. Choose Standard_B2s, and allow inbound TCP 80 and TCP 22.
Complete the wizard and wait for the deployment to finish.
Step 2 - Deploy from the Azure CLI
az group create --name codechecker-rg --location eastus
az vm image terms accept --urn sac1647283583153:codechecker-ubuntu-24-04:default:latest
az vm create \
--resource-group codechecker-rg \
--name codechecker-vm \
--image sac1647283583153:codechecker-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
az vm open-port --resource-group codechecker-rg --name codechecker-vm --port 80First boot generates the administrator credential, starts the server and stores the sample analysis. This takes about a minute. The steps below wait for it where it matters.
Step 3 - Confirm the services are running
SSH to the VM and check the two units. codechecker.service is the analysis server, and nginx.service is the only routable listener.
systemctl is-active codechecker nginxactive activeConfirm the server is bound to loopback and only nginx is exposed:
ss -ltn | grep -E ':80 |:8001 'LISTEN 0 511 0.0.0.0:80 0.0.0.0:* LISTEN 0 511 127.0.0.1:8001 0.0.0.0:* LISTEN 0 511 [::]:80 [::]:*Port 8001 is bound to 127.0.0.1 only. The server is never reachable directly from the network, and every request arrives through nginx on port 80.
The /live endpoint is the one unauthenticated path. It lets an Azure Load Balancer health probe confirm that the VM is up without a credential, and it returns a fixed string rather than any product data:
curl -s http://127.0.0.1/liveokStep 4 - Confirm the analysers shipped with the image
CodeChecker is a driver that orchestrates other analysers, and this image installs them for you. Ask CodeChecker which analysers it can see:
/opt/codechecker/venv/bin/CodeChecker analyzers --detailclangsa /usr/lib/llvm-18/bin/clang 18.1.3 clang-tidy /usr/lib/llvm-18/bin/clang-tidy 18.1.3 cppcheck /usr/bin/cppcheck 2.13.0 gcc /usr/bin/x86_64-linux-gnu-g++-13 13.3.0 infer NOT FOUNDFour analysers are available. infer (Facebook Infer) is not included. It is a large JVM-based toolchain with its own licensing, so install it separately if you need it.
The exact versions are also recorded in a file at build time:
cat /etc/codechecker/analyzer-versions.txt# Analyser toolchain shipped in this sac CodeChecker image.
# Recorded at build time from the Ubuntu 24.04 archive packages. clang=Ubuntu clang version 18.1.3 (1ubuntu1) clang-tidy=Ubuntu LLVM version 18.1.3 cppcheck=Cppcheck 2.13.0 gcc=gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 gpp=g++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 python3=Python 3.12.3All of these packages come from the Ubuntu 24.04 archive, so they keep receiving security updates through the VM's standard unattended-upgrades configuration.
Step 5 - Retrieve the per VM administrator credential
First boot generates the credential and writes it to a root-only file:
sudo cat /root/codechecker-credentials.txtThe key lines are:
CODECHECKER_URL=http://<vm-public-ip>/ codechecker.admin.user=<CC_ADMIN_USER> codechecker.admin.pass=<CC_ADMIN_PASSWORD>This account holds the SUPERUSER permission, so it can administer products and grant access to other users from the web interface.
The password is unique to this VM and is generated from the kernel CSPRNG on first boot. It is not known to SecureAnyCloud and is not derived from anything predictable. The server configuration stores only a salted SHA-512 hash of it:
sudo python3 -c "import json; e=json.load(open('/etc/codechecker/server_config.json'))['authentication']['method_dictionary']['auths'][0]; f=e.split(':'); print('user :', f[0]); print('algorithm :', f[2]); print('hash :', f[1][:32] + '...'); print('salt :', f[3])"user : ccadmin algorithm : sha512 hash : 4d0afceddc54962cf5b4054091c094cf... salt : 1f3c9ab27d4e5068bb1cf0a4e7d29c31The plaintext password appears nowhere except the root-only credentials file above.
Step 6 - Confirm there is no default login
Two conditions must hold before you expose this appliance: authentication must be enabled, and no guessable credential may work. Confirm the first condition:
sudo grep -A2 '"authentication"' /etc/codechecker/server_config.json | head -4"authentication": { "enabled": true, "super_user": "ccadmin",Now confirm that a well-known guess is refused:
export HOME=/root
sudo rm -f /root/.codechecker.session.json
sudo CC_PASSWORD=<set-at-first-boot> /opt/codechecker/venv/bin/CodeChecker cmd login ccadmin --url http://127.0.0.1 2>&1 | tail -3 || trueA refused login also exits non-zero, which is why the command ends with || true. That keeps the shell from stopping while still showing you the refusal.
[ERROR 2026-08-07 16:41:08] - Authentication denied Invalid credentials supplied for user 'ccadmin'. Refusing authentication! Note: Invalid credentials.Finally, confirm that an unauthenticated client cannot read stored results:
sudo CC_PASSWORD=<set-at-first-boot> /opt/codechecker/venv/bin/CodeChecker cmd runs --url http://127.0.0.1/Default 2>&1 | tail -2 || true[ERROR 2026-08-07 16:41:08] - Invalid pre-configured credentials. [ERROR 2026-08-07 16:41:08] - Your password has been changed or personal access token has been removed which is used by your "/root/.codechecker.passwords.json"Step 7 - Sign in to the web interface
Browse to http://<vm-public-ip>/. Because authentication is enabled, an anonymous visitor is redirected to the login form and sees no data.
Sign in with the username and password from Step 5. You land on the product list, which holds a single product, Default. First boot creates it, and the bundled SQLite database backs it.
Select Default to see its runs. First boot stored the sac-sample-c run here.
Step 8 - Read the findings that are already there
Open the REPORTS tab. The sample run contains seven findings across four source files, each with its checker name, severity, message and bug path length.
The same list is available from the command line:
export HOME=/root
sudo rm -f /root/.codechecker.session.json
sudo CC_PASSWORD='<CC_ADMIN_PASSWORD>' /opt/codechecker/venv/bin/CodeChecker cmd login '<CC_ADMIN_USER>' --url http://127.0.0.1 >/dev/null
sudo /opt/codechecker/venv/bin/CodeChecker cmd results sac-sample-c --url http://127.0.0.1/Default | head -12File | Checker | Severity | Message | Bug path length | Analyzer name | Review status | Detection status /opt/codechecker/sample-project/src/null_deref.c @ 24 | core.NullDereference | HIGH | Access to field 'id' results in a dereference of a... | 2 | clangsa | UNREVIEWED | UNRESOLVED /opt/codechecker/sample-project/src/div_zero.c @ 16 | core.DivideZero | HIGH | Division by zero | 2 | clangsa | UNREVIEWED | UNRESOLVED /opt/codechecker/sample-project/src/uninit_value.c @ 8 | core.uninitialized.Assign | HIGH | The left expression of the compound assignment is ... | 4 | clangsa | UNREVIEWED | UNRESOLVED /opt/codechecker/sample-project/src/uninit_value.c @ 10 | core.uninitialized.UndefReturn | HIGH | Undefined or garbage value returned to caller | 4 | clangsa | UNREVIEWED | UNRESOLVED /opt/codechecker/sample-project/src/uninit_value.c @ 8 | clang-diagnostic-uninitialized | HIGH | variable 'total' is uninitialized when used here | 2 | clang-tidy | UNREVIEWED | UNRESOLVED /opt/codechecker/sample-project/src/mem_leak.c @ 22 | unix.Malloc | MEDIUM | Potential leak of memory pointed to by 'label' | 6 | clangsa | UNREVIEWED | UNRESOLVED /opt/codechecker/sample-project/src/null_deref.c @ 13 | cert-err33-c | MEDIUM | the value returned by this function should not be ... | 2 | clang-tidy | UNREVIEWED | UNRESOLVEDClick any finding in the web interface to open the report detail. Here CodeChecker goes beyond raw analyser output: it overlays the full execution path that leads to the defect on the real source, step by step.
The STATISTICS tab summarises the run by checker and severity.
Step 9 - Analyse your own project
CodeChecker needs a compilation database, a compile_commands.json file that describes how each source file is compiled. There are three ways to get one. Pick the first that applies to your project.
If you build with CMake, ask CMake for it directly:
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -S . -B buildIf you build with make or a custom script, let CodeChecker observe the build:
CodeChecker log --build "make" --output ./compile_commands.jsonOtherwise, write the file by hand. The format is a list of objects with directory, command and file. The bundled sample uses this approach, and it works well for a small project.
The following commands run the whole cycle on a throwaway example, so you can see each command produce real output:
mkdir -p /tmp/demo-project && cd /tmp/demo-project cat > example.c <<'EOF' #include <stdlib.h> int main(void) { int *p = malloc(sizeof(int)); return *p; } EOF cat > compile_commands.json <<'EOF' [{"directory":"/tmp/demo-project","command":"/usr/bin/gcc -c /tmp/demo-project/example.c -o /tmp/demo-project/example.o","file":"/tmp/demo-project/example.c"}] EOF /opt/codechecker/venv/bin/CodeChecker analyze compile_commands.json -o ./reports --analyzers clangsa 2>&1 | tail -4[INFO 2026-08-07 16:42:02] - Analysis finished. [INFO 2026-08-07 16:42:02] - To view results in the terminal use the "CodeChecker parse" command. [INFO 2026-08-07 16:42:02] - To store results use the "CodeChecker store" command. [INFO 2026-08-07 16:42:02] - Analysis length: 0.13 sec.Read the results in the terminal without storing them:
cd /tmp/demo-project && /opt/codechecker/venv/bin/CodeChecker parse ./reports 2>&1 | head -8 || true[HIGH] /tmp/demo-project/example.c:4:5: Undefined or garbage value returned to caller [core.uninitialized.UndefReturn] return *p; ^ Found 1 defect(s) in example.cThe analyser correctly reports that malloc may return uninitialised memory, which is then returned to the caller.
Exit codes matter if you script this. CodeChecker parse exits 2 when it finds defects and 0 when it finds none, so that a CI job can fail a build on new findings. This is also why the command above ends with || true: without it, a shell running under set -e would stop at the first defect.
Now store the results as a named run so that they appear in the web interface alongside the sample:
export HOME=/root cd /tmp/demo-project
sudo rm -f /root/.codechecker.session.json
sudo CC_PASSWORD='<CC_ADMIN_PASSWORD>' /opt/codechecker/venv/bin/CodeChecker cmd login '<CC_ADMIN_USER>' --url http://127.0.0.1 >/dev/null
sudo /opt/codechecker/venv/bin/CodeChecker store ./reports --name demo-project --url http://127.0.0.1/Default 2>&1 | tail -3Refresh the RUNS tab. The demo-project run now appears next to sac-sample-c.
To analyse a real project, generate compile_commands.json, run CodeChecker analyze, then run CodeChecker store --name <a-name-you-choose>. Store each analysis under the same run name to enable the new and resolved comparison between builds.
Step 10 - Re-run the bundled sample at any time
A helper script runs the full analyse-and-store cycle against the bundled sample project. It reads the per-VM credential itself, so run it with sudo:
sudo codechecker-analyze-sampleTo store the run under a different name, pass the name as an argument, for example sudo codechecker-analyze-sample my-baseline. This is a good way to confirm that the whole pipeline is healthy after a configuration change.
Step 11 - Add users and products
The account from Step 5 holds SUPERUSER, so it can add users and products from the web interface.
Users. CodeChecker's dictionary authentication is configured in /etc/codechecker/server_config.json under authentication.method_dictionary.auths. Entries use the format username:hash:algorithm:salt, where the hash is the hex digest of the password with the salt appended. Generate an entry as follows, add it to the auths list, and restart the server:
python3 -c " import hashlib, secrets, string pw = ''.join(secrets.choice(string.ascii_letters + string.digits) for _ in range(28)) salt = secrets.token_hex(16) print('password :', pw) print('entry : newuser:%s:sha512:%s' % (hashlib.sha512((pw + salt).encode()).hexdigest(), salt)) "Record the password somewhere safe, because it cannot be recovered from the hash. Then add the entry and restart the server:
sudo nano /etc/codechecker/server_config.json
# add the entry to authentication.method_dictionary.auths
sudo systemctl restart codecheckerCodeChecker also supports PAM, LDAP and OAuth authentication if you prefer to delegate to an existing identity provider. See the upstream authentication documentation for the configuration blocks.
Products. A product is a separate results database, and most teams use one per codebase. Add one from the PRODUCTS tab, or from the command line, giving it its own SQLite file:
CodeChecker cmd products add myproduct --name "My Product" \
--sqlite /var/lib/codechecker/workspace/myproduct.sqlite \
--url http://127.0.0.1/Step 12 - Verify the stack
Run these checks at any time to confirm the stack is healthy:
echo "--- services ---" systemctl is-active codechecker nginx
echo "--- server is loopback only ---" ss -ltn | grep ':8001 '
echo "--- authentication is enabled ---" sudo python3 -c "import json;a=json.load(open('/etc/codechecker/server_config.json'))['authentication'];print('enabled =',a['enabled']);print('dictionary =',a['method_dictionary']['enabled']);print('credentials configured =',len(a['method_dictionary']['auths']))"
echo "--- credential is hashed, not plaintext ---" sudo grep -c ':sha512:' /etc/codechecker/server_config.json
echo "--- analysers ---" /opt/codechecker/venv/bin/CodeChecker analyzers 2>/dev/null | head -5
echo "--- open probe ---" curl -s http://127.0.0.1/live--- services --- active active --- server is loopback only --- LISTEN 0 511 127.0.0.1:8001 0.0.0.0:* --- authentication is enabled --- enabled = True dictionary = True credentials configured = 1 --- credential is hashed, not plaintext --- 1 --- analysers --- clangsa clang-tidy cppcheck gcc --- open probe --- okStep 13 - Back up your data
All of your data lives in the workspace directory: the configuration database (products, users, sessions) and one SQLite file per product.
sudo systemctl stop codechecker
sudo tar czf /root/codechecker-backup-$(date +%F).tar.gz -C /var/lib/codechecker workspace
sudo systemctl start codechecker ls -lh /root/codechecker-backup-*.tar.gzStopping the server first guarantees a consistent SQLite snapshot. Copy the archive to Azure Blob Storage or another durable location.
This archive deliberately does not include /etc/codechecker/server_config.json or /root/codechecker-credentials.txt. Those files hold your credential material, so handle them separately and with extra care.
Security notes
- Authentication cannot be switched off silently. A guard runs before every start and refuses to launch the server unless authentication is enabled, the dictionary method is on, and a real credential in salted-hash format is present. If you edit the configuration to disable authentication, the server stops starting instead of quietly exposing your findings.
- Only a hash is stored. The per-VM password exists in plaintext solely in
/root/codechecker-credentials.txt(mode 0600, owned by root). The server configuration holds a salted SHA-512 hash. - The server is not directly reachable. It binds
127.0.0.1:8001, and all external traffic arrives through nginx on port 80. - Restrict port 80. Analysis results describe your source code in detail, including file paths, code snippets and defect locations. Limit inbound port 80 in your network security group to the networks that need it.
- Terminate TLS in front of the appliance. The image serves plain HTTP so that it can sit behind whatever your organisation already uses. Before you expose it beyond a trusted network, put an Azure Application Gateway, a Load Balancer with TLS termination, or your own reverse proxy in front of it. Credentials are submitted through a login form, so this matters.
- Delete the sample run when you no longer need it. Once your own code is in the database, remove
sac-sample-cfrom the RUNS tab if you prefer not to keep it. - Keep the OS patched. Unattended-upgrades is enabled, and every analyser comes from the Ubuntu archive, so all of them are covered. CodeChecker itself is a pinned install inside its virtualenv and is deliberately not upgraded automatically, because its report database schema is tied to the version. Upgrade it deliberately, and take a backup first.
Support
SecureAnyCloud publishes this image and provides 24/7 support for it. Contact us at secureanycloud.com and include the VM size, the region and the output of Step 12.
CodeChecker is an open-source project maintained by Ericsson AB under the Apache-2.0 WITH LLVM-exception licence. SecureAnyCloud is not affiliated with, endorsed by, or sponsored by Ericsson, the LLVM Foundation, or the Cppcheck project.
Deploy on Azure
Launch CodeChecker 6 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com