Deployment guide

Scancode Io 38.2.0

Overview

This guide covers launching and verifying ScanCode.io 38.2.0 on Ubuntu 24.04 from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud 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, and choose a pipeline. It scans every file with scancode-toolkit and reports what is in there: the detected licences and copyright notices, the packages and their dependencies, known vulnerabilities, and the exact file each finding came from. You can browse results in a web interface, read them over a REST API, or export them as SPDX or CycloneDX software bills of materials.

What you get:

  • 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 SecureAnyCloud layer on top that applies the Debian security updates (sac/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 admin account 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) and scancodeio-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_AUTHENTICATION is on: every page redirects signed-out visitors to the sign-in page and every API route answers 401 or 403. First boot creates the admin account 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's DOCKER-USER chain, 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 systemd IPAddressDeny for 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, and Secure, HttpOnly session 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 forged X-Forwarded-For, X-Real-IP and Forwarded headers 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

ScanCode.io 38.2.0 runs on Ubuntu 24.04 LTS. Connect over SSH as the user ubuntu.

1

Launch the instance

Option A: AWS Marketplace console

  • Open the SecureAnyCloud 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.large recommended) 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.

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. It takes a little longer on the very first start, while EC2 reads the container images from their snapshot.

During first boot the image sets the name that ScanCode.io is served as (the instance's public DNS name when it has one) and creates the TLS certificate and this instance's secrets. It then starts PostgreSQL, Valkey and ScanCode.io, creates the administrator and the API key, and opens nginx.

The login is in a root-only file. This command 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

The file holds these fields:

scancodeio.url: the address of this instance's ScanCode.io web interface.

scancodeio.admin.user and 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 and 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.

3

Confirm ScanCode.io is running

Check that the first-boot unit has finished and that 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 port 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 sac/scancodeio:38.2.0 127.0.0.1:8000->8000/tcp scancodeio-worker sac/scancodeio:38.2.0 sac/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

sac/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>.

4

Prove the sign-in and the web defaults

These commands show the web defaults. Signed-out requests for the project pages go 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, checks the licences it finds, and deletes the project. It also 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=sac-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.

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.

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.

You can do the same over the REST API, using this instance's API key read straight from the credentials file. The commands upload the image's own sample codebase and wait for the scan. They print a summary and the detected licences, download the results as a CycloneDX SBOM, and delete 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/sac-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}} sac-sample-codebase.zip sac-sample-codebase.zip-extract/README.md apache-2.0 AND (apache-2.0 OR mit) AND (mit AND bsd-new) AND bsd-new sac-sample-codebase.zip-extract/apache_module.py apache-2.0 sac-sample-codebase.zip-extract/bsd_util.c bsd-new sac-sample-codebase.zip-extract/mit_helper.js mit sac-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 SecureAnyCloud 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.

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.

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.

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 SecureAnyCloud pins:

sudo iptables -S DOCKER-USER
sudo ip6tables -S DOCKER-USER
sudo iptables -S SAC-SCIO-EGRESS | grep -cE 'REJECT' cat /run/sac-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 SAC-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 SAC-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/sac/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/sac/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.txt once 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-required exists; 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.service starts 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-web for the web server, sudo docker logs scancodeio-worker for pipeline runs, sudo docker logs scancodeio-db and sudo docker logs scancodeio-valkey for the database and queue; /var/log/nginx/ for web requests; sudo journalctl -u scancodeio-firstboot for first boot.

Troubleshooting

  • The page does not load right after launch: first boot is still running. sudo journalctl -u scancodeio-firstboot -f shows its progress.
  • Browser shows "connection closed": nginx answers only the configured name and closes the connection for any other name. Use scancodeio.url, or run sudo 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 scancodeio and sudo docker logs --tail 50 scancodeio-web show why.
  • The end-to-end check: sudo scancodeio-selftest signs in with this instance's administrator, runs a real scan and prints round-trip OK when 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; SecureAnyCloud is not affiliated with, sponsored by or endorsed by AboutCode or nexB, and the names identify the software this image contains.

Support

SecureAnyCloud 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 sales@secureanycloud.com.

Deploy on AWS

Launch ScanCode.io 38.2.0 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS