ScanCode.io 38.2.0 on AWS User Guide
Overview
This guide covers launching and verifying ScanCode.io 38.2.0 on Ubuntu 24.04 from cloudimg on Amazon EC2. It is one version of the cloudimg Hardened Apache Subversion (SVN) & CI/CD Tools AMIs listing on AWS Marketplace; you pick it as the software version when you launch.
ScanCode.io is AboutCode's open source server for software composition analysis (Apache-2.0 licence). You give it a codebase, an archive, a package URL or a container image, choose a pipeline, and it scans every file with scancode-toolkit and reports what is really in there: the detected licences and copyright notices, the packages and their dependencies, known vulnerabilities, and the exact file each finding came from. Results are browsable in a web interface, available over a REST API, and export as SPDX or CycloneDX software bills of materials.
What is on the image:
- ScanCode.io 38.2.0 from the official upstream image
ghcr.io/aboutcode-org/scancode.io(the core image), pinned by its linux/amd64 manifest digest, with one cloudimg layer on top that applies the Debian security updates (cloudimg/scancodeio:38.2.0) - PostgreSQL 17.11 (
postgres:17.11-alpine3.24) for the database and Valkey 8.1.11 (valkey/valkey:8.1.11-alpine3.24) for the scan job queue, both pinned by digest - Docker CE from Docker's official repository (its signing key pinned by fingerprint), configured so that no container can reach instance metadata, and an egress backstop that keeps the scan containers off your VPC and other private networks
- nginx serving HTTPS on port 443 with a certificate created on your instance; port 80 redirects to HTTPS
- Sign-in required everywhere: a per-instance
adminaccount and REST API key are created on first boot; the Django admin site and self sign-up are off scancodeio-set-hostname(serve ScanCode.io under your own DNS name) andscancodeio-selftest(an end-to-end check that runs a real scan)
Default user: ubuntu · Architecture: x86_64 · Root volume: 40 GiB gp3
Security posture
- No default login and no anonymous access. ScanCode.io ships upstream with authentication off; on a public instance that would let anyone run scan pipelines on your machine. Here
SCANCODEIO_REQUIRE_AUTHENTICATIONis on: every page redirects signed-out visitors to the sign-in page and every API route answers 401 or 403. First boot creates theadminaccount with a 24-character password and a 64-character API key made on your instance, both written only to/root/scancodeio-credentials.txt(mode 0600, root). The API key is stored in the database as a one-way hash. The Django admin site and any sign-up page answer 404, and sign-in attempts are rate limited per client address. - Per-instance secrets. The admin password, the API key, Django's
SECRET_KEY, the PostgreSQL password, the Valkey password and the TLS key are all created on your instance; no two instances share one. They reach the containers through a root-only environment file, never on a command line. - The database and the job queue are private. PostgreSQL and Valkey have no host port and accept only password logins from the ScanCode.io containers on a private Docker network. ScanCode.io's own port 8000 listens on the loopback interface only, so nginx is the only way in.
- Scans cannot reach instance metadata or your network. ScanCode.io fetches project inputs that a signed-in user names (download URLs, git repositories,
docker://images). A rule in Docker'sDOCKER-USERchain, applied before dockerd starts any container, refuses 169.254.169.254, fd00:ec2::254 and 168.63.129.16, so no container can read the instance's IAM role credentials. A second chain (the egress backstop) refuses connections from the ScanCode.io network to this instance's own VPC ranges, the RFC 1918, carrier-grade NAT, link-local, multicast and reserved ranges, and all IPv6; public internet addresses and DNS stay open, so scans of public repositories and registries work. You can allow a private address explicitly (Step 9). Docker, the stack and nginx also carry systemdIPAddressDenyfor the metadata addresses. - Hardened containers. The web and worker containers run as an unprivileged user with every Linux capability dropped and
no-new-privileges; no container is privileged, mounts the Docker socket or uses the host network. Core dumps are off. - HTTPS from first boot. TLS 1.2 and 1.3 only,
Strict-Transport-Security, andSecure,HttpOnlysession cookies. The host name comes from configuration, never from a request: first boot reads the instance's public DNS name from EC2 instance metadata (IMDSv2) and pins nginx and Django to it; requests for any other host name get their connection closed. Cross-site state-changing requests are refused, and forgedX-Forwarded-For,X-Real-IPandForwardedheaders never reach ScanCode.io. - Verified build. The image digests were scanned for known vulnerabilities and their licences checked before the build. SSH allows keys only, no root login and no X11 forwarding; the AMI requires IMDSv2; SSH host keys and the machine ID are generated fresh on every instance.
Trusted users only. A signed-in ScanCode.io user can make the server download and unpack any public archive, repository or image and run the scanners over it. Give accounts and the API key only to people you trust with that, and keep 80 and 443 restricted to the networks your users work from.
Prerequisites
- An AWS account and permission to launch EC2 instances
- An EC2 key pair in the Region you launch in
Recommended instance type: m5.large (2 vCPUs, 8 GiB). ScanCode.io's web server, scan worker, PostgreSQL and Valkey use about 1.5 GiB at rest; scancode-toolkit uses much more while it scans, and large codebases want an m5.xlarge or bigger.
Connecting to your instance
| Version | Operating system | SSH user |
|---|---|---|
| ScanCode.io 38.2.0 on Ubuntu 24.04 | Ubuntu 24.04 LTS | ubuntu |
Step 1: Launch the instance
Option A: AWS Marketplace console
- Open the cloudimg Hardened Apache Subversion (SVN) & CI/CD Tools AMIs listing on AWS Marketplace and choose View purchase options, then Subscribe. One subscription covers every version in the listing.
- Once the subscription is active, choose Launch your software.
- Choose One-click launch from AWS Marketplace (or Launch from EC2 Console for the full launch wizard). In Version, choose ScanCode.io 38.2.0 on Ubuntu 24.04, then choose your Region.
- Pick an instance type (
m5.largerecommended) and your key pair. Make the root volume larger in the storage settings if you will scan large codebases or keep many projects. - Security group: the listing's default group opens SSH (22), HTTP (80) and HTTPS (443). Restrict SSH to your own IP address and restrict 80 and 443 to the networks your users work from. Never open 8000, 5432 or 6379.
- Choose your VPC and subnet. Under Advanced details, leave Metadata version at V2 only (the image already requires it) and set Metadata response hop limit to
1: containers then cannot reach instance metadata even without the image's own filter. - Choose Launch.
Option B: AWS CLI
Run this on your own workstation. Replace the AMI ID with the one shown for your Region on the Marketplace launch page, and the VPC, subnet, key pair and CIDRs with your own:
SG=$(aws ec2 create-security-group --group-name scancodeio \
--description "ScanCode.io" --vpc-id vpc-0123456789abcdef0 \
--query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 22 --cidr <your-mgmt-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 443 --cidr <your-mgmt-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 80 --cidr <your-mgmt-cidr>
aws ec2 run-instances \
--image-id ami-0123456789abcdef0 \
--instance-type m5.large \
--key-name my-key-pair \
--security-group-ids "$SG" \
--subnet-id subnet-0123456789abcdef0 \
--metadata-options HttpTokens=required,HttpPutResponseHopLimit=1,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=scancodeio}]'
Associate an Elastic IP if you want the address to survive a stop and start.
Step 2: Connect and find your login
Connect as ubuntu with the key pair you chose:
ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>
First boot takes two to three minutes after the instance starts (a little longer on the very first start, while EC2 reads the container images from their snapshot). It sets the name ScanCode.io is served as (the instance's public DNS name when it has one), creates the TLS certificate and this instance's secrets, starts PostgreSQL, Valkey and ScanCode.io, creates the administrator and the API key, and then opens nginx. The login is in a root-only file; this shows the address, the user names and the field names without printing any password or key:
sudo grep -E '^scancodeio\.(url|admin\.user|db\.name|db\.user)=' /root/scancodeio-credentials.txt
sudo grep -oE '^[a-z.]+=' /root/scancodeio-credentials.txt
sudo stat -c '%a %U:%G %n' /root/scancodeio-credentials.txt
scancodeio.url=https://ec2-203-0-113-25.compute-1.amazonaws.com/
scancodeio.admin.user=admin
scancodeio.db.name=scancodeio
scancodeio.db.user=scancodeio
scancodeio.url=
scancodeio.admin.user=
scancodeio.admin.pass=
scancodeio.api.key=
scancodeio.db.name=
scancodeio.db.user=
scancodeio.db.pass=
scancodeio.valkey.pass=
600 root:root /root/scancodeio-credentials.txt
| Value | What it is for |
|---|---|
scancodeio.url |
The address of this instance's ScanCode.io web interface |
scancodeio.admin.user / scancodeio.admin.pass |
The administrator's sign-in for the web interface |
scancodeio.api.key |
The administrator's REST API key, sent as Authorization: Token <key> |
scancodeio.db.user / scancodeio.db.pass |
ScanCode.io's PostgreSQL account, for backups and database administration |
scancodeio.valkey.pass |
The password of the Valkey job queue, used by the scan worker |
To read the passwords, run sudo cat /root/scancodeio-credentials.txt in your own session and store them in your password manager.
Step 3: Confirm ScanCode.io is running
The first-boot unit has finished; Docker, the VPC range reader, the egress backstop, the ScanCode.io stack and nginx are active; exactly four containers run. The only public listening sockets are sshd and nginx on 22, 80 and 443; ScanCode.io's 8000 is on 127.0.0.1 only, and PostgreSQL and Valkey have no host port at all:
systemctl is-active scancodeio-firstboot docker scancodeio-vpc-cidrs scancodeio-egress scancodeio nginx
sudo ss -Htlnp | awk '{print $4, $6}' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g' | sort -u
sudo docker ps --format '{{.Names}} {{.Image}} {{.Ports}}' | sort
sudo docker image ls --digests --format '{{.Repository}}:{{.Tag}} {{.Digest}}' | sort
active
active
active
active
active
active
0.0.0.0:22 users:(("sshd"),("systemd"))
0.0.0.0:443 users:(("nginx"),("nginx"),("nginx"))
0.0.0.0:80 users:(("nginx"),("nginx"),("nginx"))
127.0.0.1:8000 users:(("docker-proxy"))
127.0.0.53%lo:53 users:(("systemd-resolve"))
127.0.0.54:53 users:(("systemd-resolve"))
[::]:22 users:(("sshd"),("systemd"))
[::]:443 users:(("nginx"),("nginx"),("nginx"))
[::]:80 users:(("nginx"),("nginx"),("nginx"))
scancodeio-db postgres 5432/tcp
scancodeio-valkey valkey/valkey 6379/tcp
scancodeio-web cloudimg/scancodeio:38.2.0 127.0.0.1:8000->8000/tcp
scancodeio-worker cloudimg/scancodeio:38.2.0
cloudimg/scancodeio:38.2.0 <none>
ghcr.io/aboutcode-org/scancode.io:v38.2.0 sha256:3be4ac0e6aa8d4236db9c4537416d799faa159a88d823405b91954d5630a2c71
postgres:17.11-alpine3.24 sha256:4717f90960a225c2d1c5dac50508c401230f693ff626e06e84e6db0a68ded508
valkey/valkey:8.1.11-alpine3.24 sha256:ac81eb0a7b37e054000af8fdd5e6c3eb17249caa71eba79c003a145e518415e5
cloudimg/scancodeio:38.2.0 is built on the image from ghcr.io/aboutcode-org/scancode.io:v38.2.0 (its upstream image is kept on the instance, and /usr/share/scancodeio/IMAGES records both); a locally built image has no registry digest, so it shows <none>.
Step 4: Prove the sign-in and the web defaults
Signed-out requests for the project pages are sent to the sign-in page and every API route is refused; the Django admin site and sign-up do not exist; plain HTTP redirects to HTTPS; an unknown Host header gets no answer and TLS 1.1 is not offered. The last command is the image's own round-trip check: it signs in with this instance's administrator over https://<your-name>/, uses the API key, runs a real scan_codebase scan of a small sample codebase and checks the licences it finds, then deletes the project, and proves that a wrong password, a wrong API key and wrong database and queue passwords are refused:
H=$(sudo sed -nE 's#^scancodeio\.url=https://([^/]+)/?.*#\1#p' /root/scancodeio-credentials.txt)
for p in / /project/ /project/add/ /accounts/profile/ /api/projects/ /api/ /admin/ /accounts/signup/; do
printf '%-20s %s\n' "$p" "$(curl -sk -o /dev/null -w '%{http_code}' --connect-to ::127.0.0.1: "https://$H$p")"
done
curl -sk -D - -o /dev/null --connect-to ::127.0.0.1: "https://$H/project/" | grep -i '^location'
curl -s -D - -o /dev/null --connect-to ::127.0.0.1: "http://$H/" | grep -iE '^(HTTP|location)'
curl -sk -o /dev/null -w 'unknown Host %{http_code}\n' -H 'Host: evil.example' https://127.0.0.1/ || true
curl -sk -o /dev/null -w 'TLS 1.1 %{http_code}\n' --tls-max 1.1 --connect-to ::127.0.0.1: "https://$H/" || true
sudo scancodeio-selftest
/ 302
/project/ 302
/project/add/ 302
/accounts/profile/ 302
/api/projects/ 401
/api/ 401
/admin/ 404
/accounts/signup/ 404
location: /accounts/login/?next=/project/
HTTP/1.1 301 Moved Permanently
Location: https://ec2-203-0-113-25.compute-1.amazonaws.com/
unknown Host 000
TLS 1.1 000
round-trip OK https://ec2-203-0-113-25.compute-1.amazonaws.com/: 8 protected routes refuse anonymous visitors; /admin/ 404 (disabled), no sign-up; wrong password and wrong API key refused; admin signed in over 443 (302), /project/ 200; API key 200; scan_codebase of the sample codebase succeeded (resources=7 licensed=4 npm=cloudimg-scancodeio-sample), project deleted; PostgreSQL password authenticates, a wrong one refused; Valkey password PONG, anonymous NOAUTH
--connect-to ::127.0.0.1: sends each request to this instance while keeping the real host name in the request, exactly as a browser would send it. 000 means the server closed the connection without an answer.
Step 5: Sign in to ScanCode.io
Browse to scancodeio.url (https://<public-dns-name>/). The certificate is self-signed, so your browser warns once; accept it for this host, or install your own certificate (Step 8). Sign in as admin with the scancodeio.admin.pass value from the credentials file:

The Projects page lists your scan projects with their pipeline runs and the number of resources, packages and findings each one has:

Your Profile page (account menu, top right) shows the first characters of your API key; the full key is only in the credentials file, because ScanCode.io stores a one-way hash of it.
Step 6: Scan your own code
In the web interface choose New Project, give it a name, add your input (upload an archive, or give a download URL, a git repository URL ending in .git, a package URL such as pkg:npm/lodash@4.17.21, or a docker:// image reference), choose a pipeline and Execute. Useful pipelines: scan_codebase (licences, copyrights and packages in a codebase), scan_single_package (one package archive), inspect_packages (dependency manifests and lockfiles), analyze_docker_image (a container image) and load_sbom (import an existing SBOM). Add-on pipelines that query other AboutCode services, such as find_vulnerabilities (VulnerableCode) and enrich_with_purldb (PurlDB), need those services, which this image does not set up.
The same over the REST API, using this instance's API key read straight from the credentials file. This uploads the image's own sample codebase, waits for the scan, prints a summary and the detected licences, downloads the results as a CycloneDX SBOM, and then deletes the project again:
H=$(sudo sed -nE 's#^scancodeio\.url=https://([^/]+)/?.*#\1#p' /root/scancodeio-credentials.txt)
API=(-sk --connect-to ::127.0.0.1: -H "Authorization: Token $(sudo sed -n 's/^scancodeio\.api\.key=//p' /root/scancodeio-credentials.txt)")
UUID=$(curl "${API[@]}" -F "name=guide-scan-$(date +%s)" -F pipeline=scan_codebase -F execute_now=true \
-F "upload_file=@/usr/share/scancodeio/cloudimg-sample-codebase.zip" "https://$H/api/projects/" | jq -r .uuid)
for i in $(seq 1 60); do
S=$(curl "${API[@]}" "https://$H/api/projects/$UUID/" | jq -r '.runs[0].status')
[ "$S" = success ] || [ "$S" = failure ] && break; sleep 5
done
echo "pipeline status: $S"
curl "${API[@]}" "https://$H/api/projects/$UUID/" | jq -c '{resources: .codebase_resources_summary, packages: .discovered_packages_summary}'
curl "${API[@]}" "https://$H/api/projects/$UUID/resources/?page_size=20" | jq -r '.results[] | select(.type == "file") | "\(.path) \(.detected_license_expression)"'
curl "${API[@]}" -o /tmp/guide-scan.cdx.json "https://$H/api/projects/$UUID/results_download/?output_format=cyclonedx"
jq -r '"CycloneDX \(.specVersion): \(.components | length) component(s)"' /tmp/guide-scan.cdx.json
curl "${API[@]}" -o /dev/null -w 'project deleted: %{http_code}\n' -X DELETE "https://$H/api/projects/$UUID/"
rm -f /tmp/guide-scan.cdx.json
pipeline status: success
{"resources":{"application-package":1,"scanned":6},"packages":{"total":1,"with_missing_resources":0,"with_modified_resources":0}}
cloudimg-sample-codebase.zip
cloudimg-sample-codebase.zip-extract/README.md apache-2.0 AND (apache-2.0 OR mit) AND (mit AND bsd-new) AND bsd-new
cloudimg-sample-codebase.zip-extract/apache_module.py apache-2.0
cloudimg-sample-codebase.zip-extract/bsd_util.c bsd-new
cloudimg-sample-codebase.zip-extract/mit_helper.js mit
cloudimg-sample-codebase.zip-extract/package.json
CycloneDX 1.6: 1 component(s)
project deleted: 204
The sample codebase (/usr/share/scancodeio/sample/) was written by cloudimg to exercise the scanner, with a known licence in each file. In the web interface, a finished project shows its packages, dependencies and resources, the download buttons for every results format, and its findings by licence, copyright holder and package:

Resources lists every file with its detected licence:

A project's results download from its project page as JSON, XLSX, SPDX or CycloneDX, or from the API's results_download endpoint with output_format set to json, xlsx, spdx or cyclonedx.
Step 7: Scan inputs, pipelines and the core image
This image runs the upstream core ScanCode.io image. Two optional pipelines need tools that only the much larger upstream -full image carries: scanning virtual-machine disk images (libguestfs and a Linux kernel) and decompiling Android APKs (jadx and a Java runtime). Every other pipeline, including container images, packages, codebases, SBOMs and vulnerability lookups, works as shipped. Scans of public URLs, git repositories, package URLs and registries reach the internet directly; see Step 9 for private ones.
Project files and scan output live in /var/lib/scancodeio/workspace, and the database in /var/lib/scancodeio/postgres. Delete projects you no longer need from the project page (Delete) or with DELETE /api/projects/<uuid>/ to free the space.
Step 8: Serve ScanCode.io under your own DNS name
Point a DNS record (for example sca.example.com) at the instance's public or Elastic IP address, then tell the image to serve that name. It creates a new self-signed certificate for the name, pins nginx, the cross-site guard and Django to it, updates scancodeio.url in the credentials file and keeps the name across reboots:
sudo scancodeio-set-hostname sca.example.com
For a trusted certificate, obtain one for that name (for example from your organisation's CA, or with certbot's certonly mode using its own temporary web server), copy the certificate chain and key over /etc/ssl/scancodeio/scancodeio.crt and /etc/ssl/scancodeio/scancodeio.key (key mode 0600, root), and run sudo systemctl reload nginx.
Step 9: Check the security controls, and allow a private source
The DOCKER-USER rules refuse the metadata addresses and keep other containers off the ScanCode.io network; the egress backstop chain refuses private, link-local and this VPC's own ranges and all IPv6 from the ScanCode.io network. From inside the scan worker, instance metadata and a private address are refused while the public internet still answers (the 200 is that positive control); the PostgreSQL and Valkey ports answer nothing on the host; the services carry IPAddressDeny; and SSH runs with the cloudimg pins:
sudo iptables -S DOCKER-USER
sudo ip6tables -S DOCKER-USER
sudo iptables -S CLOUDIMG-SCIO-EGRESS | grep -cE 'REJECT'
cat /run/cloudimg-scancodeio/vpc-cidrs
for u in http://checkip.amazonaws.com/ http://169.254.169.254/latest/meta-data/ http://10.0.0.1/; do
sudo docker exec scancodeio-worker python3 -c 'import sys,urllib.request
try:
print(sys.argv[1], "->", urllib.request.urlopen(sys.argv[1], timeout=5).status)
except Exception as e:
print(sys.argv[1], "-> refused:", type(e).__name__)' "$u"
done
for p in 5432 6379; do
curl -s -m 5 -o /dev/null -w "host -> 127.0.0.1:$p: %{http_code}\n" "telnet://127.0.0.1:$p" || true
done
systemctl show -p IPAddressDeny docker scancodeio nginx
sudo sshd -T | grep -E '^(passwordauthentication|permitrootlogin|kbdinteractiveauthentication|x11forwarding) '
-N DOCKER-USER
-A DOCKER-USER -i br-scio -j CLOUDIMG-SCIO-EGRESS
-A DOCKER-USER -d 168.63.129.16/32 -j REJECT --reject-with icmp-host-unreachable
-A DOCKER-USER -d 169.254.169.254/32 -j REJECT --reject-with icmp-host-unreachable
-A DOCKER-USER ! -i br-scio -o br-scio -m conntrack --ctstate NEW -j DROP
-N DOCKER-USER
-A DOCKER-USER -i br-scio -j CLOUDIMG-SCIO-EGRESS
-A DOCKER-USER -d fd00:ec2::254/128 -j REJECT --reject-with icmp6-adm-prohibited
-A DOCKER-USER -o br-scio -j DROP
24
# written by scancodeio-vpc-cidrs from EC2 metadata at 2026-11-08T09:58:16Z
source imds
4 172.31.0.0/16
http://checkip.amazonaws.com/ -> 200
http://169.254.169.254/latest/meta-data/ -> refused: URLError
http://10.0.0.1/ -> refused: URLError
host -> 127.0.0.1:5432: 000
host -> 127.0.0.1:6379: 000
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32
IPAddressDeny=169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32
permitrootlogin no
passwordauthentication no
kbdinteractiveauthentication no
x11forwarding no
To let ScanCode.io fetch inputs from a private address, such as a git server or a container registry inside your VPC, add its IPv4 address or CIDR on its own line in /etc/cloudimg/scancodeio-egress-allow and reload the backstop. Only RFC 1918 and carrier-grade NAT ranges can be allowed; metadata and link-local addresses never can. For example:
echo '10.20.30.40/32' | sudo tee -a /etc/cloudimg/scancodeio-egress-allow
sudo systemctl reload scancodeio-egress
Maintenance
- Change the admin password: run
sudo docker exec -it scancodeio-web ./manage.py changepassword admin, then replace the old one in/root/scancodeio-credentials.txtonce you have stored the new one. - Add users: create accounts with Django's management command inside the web container, for example
sudo docker exec -it scancodeio-web ./manage.py create-user <name>, which creates the user and prints its API key. - Operating system updates: unattended security upgrades are on. Reboot when
/var/run/reboot-requiredexists; the metadata filter, the egress backstop, the ScanCode.io stack and nginx start again by themselves. - ScanCode.io updates: the stack runs the pinned images and never pulls one. To move to a newer release, launch the newer version of this image when the listing offers it and move your data across with ScanCode.io stopped. Do not run
docker image prune -a:scancodeio.servicestarts the pinned images only. - Backups: snapshot the root volume, or dump the database with this instance's own password passed through the environment:
sudo bash -c 'PGPASSWORD=$(sed -n "s/^scancodeio\.db\.pass=//p" /root/scancodeio-credentials.txt) docker exec -e PGPASSWORD scancodeio-db pg_dump -U scancodeio scancodeio' > scancodeio.sql. Project files are in/var/lib/scancodeio/workspace. - Logs:
sudo docker logs scancodeio-webfor the web server,sudo docker logs scancodeio-workerfor pipeline runs,sudo docker logs scancodeio-dbandsudo docker logs scancodeio-valkeyfor the database and queue;/var/log/nginx/for web requests;sudo journalctl -u scancodeio-firstbootfor first boot.
Troubleshooting
- The page does not load right after launch: first boot is still running.
sudo journalctl -u scancodeio-firstboot -fshows its progress. - Browser shows "connection closed": nginx answers only the configured name and closes the connection for any other name. Use
scancodeio.url, or runsudo scancodeio-set-hostname <name>for a new name. Use the name rather than an IP address in the browser too: the cross-site guard accepts changes only from the configured name. - Sign-in answers "429" or keeps failing: sign-in is rate limited per client address; wait a minute after several failures, and check the password in the credentials file.
- A project input "could not be fetched": ScanCode.io refuses download URLs that resolve to private or internal addresses, and the egress backstop refuses private destinations for every input type. Use a public URL, upload the archive, or allow the private address (Step 9).
- A pipeline stays "queued": the scan worker runs one pipeline at a time; check
sudo docker logs --tail 50 scancodeio-worker. - 502 Bad Gateway: ScanCode.io is starting (it applies its database migrations at start) or has stopped.
sudo systemctl status scancodeioandsudo docker logs --tail 50 scancodeio-webshow why. - The end-to-end check:
sudo scancodeio-selftestsigns in with this instance's administrator, runs a real scan and printsround-trip OKwhen everything works.
Licensing
ScanCode.io is licensed under the Apache License 2.0; its licence and NOTICE are on the instance in /usr/share/doc/scancodeio/. ScanCode.io's licence detection uses the licence texts and rules of scancode-toolkit, which nexB Inc. and the AboutCode contributors publish under CC-BY-4.0 (attribution: AboutCode, https://aboutcode.org, scancode-toolkit). PostgreSQL is licensed under the PostgreSQL Licence. Valkey is licensed under the BSD 3-Clause licence; its licence text is in /usr/share/doc/scancodeio/third-party/. ScanCode and ScanCode.io are names of the AboutCode project; cloudimg is not affiliated with, sponsored by or endorsed by AboutCode or nexB, and the names identify the software this image contains.
Support
cloudimg provides 24/7 technical support for this image by email and live chat: deployment, first login, HTTPS and DNS setup, pipelines and scan inputs, private sources, storage, upgrades and troubleshooting. Contact support@cloudimg.co.uk.