Skip to content

Installation

Minimum Notes
OS Linux, macOS, or Windows with WSL2 amd64 or arm64 (Apple Silicon included). On Windows, clone the repository inside Linux (~/...), not under /mnt/c.
Docker Engine 24+ and Compose v2.24+ Docker Desktop, OrbStack or Docker Engine.
make and git any version make ships with macOS; on Debian/Ubuntu, sudo apt install make git. On Windows, inside WSL2.
Memory 4 GB free The app uses ~200 MB at rest; each scan runs one engine at a time, capped at 3 GB.
Disk 8 GB free Images (~1 GB), Trivy’s vulnerability database (~1.3 GB), Grype’s (~2.1 GB, only if you scan container images), the local NVD copy (~0.7 GB) and your runs.
Outbound network HTTPS to GitHub, NVD, CISA and EPSS; for the images, ghcr.io (its layers come from pkg-containers.githubusercontent.com) and Docker Hub Details in security.md. No inbound access from the internet is needed.
Account GitHub (personal, or an organization you administer) To create your GitHub App.

You don’t need to install Python, Node or the scanning engines: everything runs in containers. make doctor checks the requirements and tells you how to fix anything missing.

Terminal window
git clone https://github.com/Pitangus-Dev/pitangus.git
cd pitangus
make up

make up creates .env from .env.example with your host user (PITANGUS_UID/PITANGUS_GID, so data/ and config/ belong to you and not to root), builds, starts and waits until the panel responds. Without make: sh scripts/init-env.sh && docker compose up --build -d.

The first build takes a few minutes: it compiles the panel, downloads the Opengrep binary and checks its SHA-256. You’ll see four services: api (the pitangus container, panel and API), worker (runs the scans) and postgres (the pitangus-postgres container, the database) keep running; opengrep only builds the engine image and exits right away. That’s expected.

To skip the build, run make setup PREBUILT=1 before make up: it pulls the published, signed images for the version you checked out (pitangus/version.py) instead of building them. It’s still a local install on http://127.0.0.1:8766; with cosign installed, make up checks their signatures first and pins the checked digest in .env (without it, it starts anyway and says so).

When it finishes it prints the setup code (also available with make setup-code, or in the logs):

================================================================
First start: create the administrator in the panel with this code
ABCD-EFGH-JKLM
(it works once, and only while there are no users)
================================================================

Open http://127.0.0.1:8766, enter that code and create your admin user. The code proves you’re the one who controls the server: without it, whoever opened the URL first could take over the instance. If you restart before using it, a new one is generated.

The panel follows your browser’s language; you can switch it from the sidebar or the sign-in screen. Everything Pitangus writes without a person asking (PR comments, notifications, Jira, reports and CLI output) uses PITANGUS_DEFAULT_LOCALE (en or es, default en); set it in .env if your team works in Spanish. See configuration.md.

Then:

  1. Account → Two-factor: turn on TOTP with your authenticator app and save the backup codes. It’s mandatory for admins.
  2. Integrations: create and connect your GitHub App following the panel’s guide (also in github-app.md).
  3. Repositories: pick one and click Scan.

The local NVD copy for the CVE tracker downloads in the background: a few hours without an API key, much less with PITANGUS_NVD_API_KEY (free at https://nvd.nist.gov/developers/request-an-api-key). Everything else works in the meantime.

New versions are listed on the Releases page, with what changed and anything to do before upgrading (also in CHANGELOG.md). To see which one you’re running: git describe --tags in the repository folder, or the version in the panel’s top bar (/api/health answers it too).

If you installed a release (git clone --branch v0.12.x, as in the quickstart), the repository stays on that version on purpose, and make update alone won’t move it: it says On v0.12.x (a fixed version): not pulling. Check out the new one first:

Terminal window
git fetch --tags
git checkout v0.12.2 # the version you want
make update

If you follow main (you cloned without --branch), make update is enough: it pulls the latest code.

make update takes a backup first (make backup), then pulls the code and restarts. data/, config/ and the database are kept. If the new version changes the format of any data, it converts it on startup, once, after saving a copy of what it touches in data/backups/: there’s nothing to do by hand. Before upgrading, take a backup (see below) and check under Scans that nothing is running: a restart marks any running scan as failed.

Folder Contents How to handle it
Database (pitangus-pg volume) Runs, finding history and triage (PostgreSQL) make backup dumps it with pg_dump into database.dump.
data/ Users (passwords hashed with scrypt), settings, logs, NVD copy and caches No plaintext secrets. You can leave out data/feeds/, data/trivy-cache/ and data/grype-cache/: they’re downloaded again.
config/ master.key (unless PITANGUS_MASTER_KEY is set) This is the key to your credentials, which are stored encrypted in the database. make backup leaves it out unless the backup is encrypted: keep a copy in your password manager, never with the backups.
Terminal window
make backup # backups/<date>/database.dump, data.tgz and master-key.sha256 (which key it needs)

The app pauses for a few seconds so the backup is consistent, and the command refuses to run while scans are in progress (FORCE=1 overrides it). The master key isn’t in the backup, so a stray copy of it reveals no secret; on a new machine, put config/master.key back before restoring. To copy backups off the machine, encrypt them with age (PITANGUS_BACKUP_AGE_RECIPIENT, deploy-vps.md): then the key goes in too, encrypted. To restore:

Terminal window
make restore FROM=backups/<date> CONFIRM=restore # saves the current state in backups/pre-restore-<date>/ first
make up

Scheduled backups (a Compose service with retention), cron and offsite copies: deploy-vps.md.

If you lose config/master.key (or change PITANGUS_MASTER_KEY), the stored secrets can’t be decrypted: you’ll have to reconnect the GitHub App and re-enter the Jira token. No other data is lost.

By default the port is only published on 127.0.0.1. To reach it from other machines you need HTTPS: the server refuses to start if PITANGUS_PUBLIC_URL isn’t loopback and doesn’t start with https://. For a server with a domain, make setup DOMAIN=pitangus.example.com adds Caddy with automatic certificates: the full guide (sizing, firewall, backups, upgrades, monitoring, Coolify and Dokploy) is deploy-vps.md.

On a laptop the worker controls Docker through its socket, which is equivalent to root on the host; server mode (DOMAIN=…) runs the engines inside the worker instead. Either way, only expose the panel to people you trust.

Terminal window
make clean # containers and images; keeps data/ and config/
make purge CONFIRM=delete # also deletes data and secrets: only if you no longer need them

Also delete your GitHub App on GitHub (Settings → Developer settings → GitHub Apps → your App → Advanced → Delete), or at least revoke its private key.