Documentation

Command line

velodex <COMMAND>

Commands

CommandPurpose
serveRun the server
initCreate the data directory and its stores, then exit
config-snippetPrint pip.conf, uv.toml, or .pypirc for one configured index
indexList and inspect the configured indexes
cacheInspect, validate, and clean the on-disk cache
backupCreate and verify offline backups
restoreRestore an offline backup into a data directory
import-dirImport local wheels and sdists into a hosted index
policyPreview index policy decisions against cached records
mirrorPlan, populate, and verify mirror cache contents
openapiPrint the OpenAPI description of the HTTP API as JSON
self updateReplace the binary with the newest release (installer-managed builds only; see below)

serve and init options

FlagMeaningDefault
--config <path>TOML configuration file(none)
--host <addr>Bind address127.0.0.1
--port <port>Bind port4433
--data-dir <path>Data directory (redb store and blob cache)velodex-data
--offlineServe configured cached indexes from cache onlyfalse

Logging

FlagMeaningDefault
--log-level <dir>tracing directive: error, warn, info, debug, trace, or per-moduleinfo
-v, -vvRaise the level to debug / trace
--log-format <f>pretty or jsonpretty
--log-sink <s>stdout, file, journald, syslogstdout
--log-file <path>Log file path, required with --log-sink file(none)

Flags override the config file; see Configuration for the full precedence and the [[index]] schema.

index

Read the configured topology without starting the server. list prints one tab-separated row per index (name, route, ecosystem, kind, uploads); show prints one index's details, including a virtual index's layer stack and upload target or a cached index's upstream. --ecosystem filters list to one ecosystem (only pypi today; the flag reserves the axis for future ecosystems).

velodex index list [--ecosystem pypi] [--config <path>] [--data-dir <path>]
velodex index show <index> [--config <path>] [--data-dir <path>]

config-snippet

velodex config-snippet --base-url <url> [--config <path>] [--index <route>] <pip.conf|uv.toml|.pypirc>

--base-url is required because the CLI cannot know the public URL in front of the server. Use the origin clients see, with any proxy path prefix and without the index route:

velodex config-snippet --base-url https://packages.example --index root/pypi pip.conf
velodex config-snippet --base-url https://packages.example --index root/pypi uv.toml
velodex config-snippet --base-url https://packages.example --index root/pypi .pypirc

pip.conf and uv.toml are available for read-only and writable indexes. .pypirc is available only when the route has a configured hosted upload target with an upload_token; the output uses <upload-token> instead of the configured secret.

mirror

Mirror commands read the same config, --data-dir, and logging flags as serve. The index argument is a configured index name or route. It may point at a cached index directly, or at a virtual index with one cached layer.

velodex mirror plan root/pypi --package "requests>=2,<3"
velodex mirror sync root/pypi --requirements requirements.txt
velodex mirror sync pypi --mode all --python-tag py3 --abi-tag none --platform-tag any
velodex mirror verify pypi --mode all

plan prints the selected projects and files without writing cache records. sync stores selected Simple pages, PEP 658 metadata siblings, and artifacts. verify checks cached pages and blob digests for the selected set. Output is tab-separated with one row per page, metadata sibling, file, or summary count.

Selection starts from [index.prefetch] in the config and the CLI flags add or override it:

FlagMeaning
--mode selectedUse configured and CLI package selectors
--mode allRead the upstream root Simple project list and visit projects
--mode metadata-onlySelect packages and skip artifact downloads
--package <selector> / -pAdd a package selector such as flask>=3,<4
--requirements <path> / -rRead selectors from a requirements or constraints file
--metadata-onlyFetch pages and metadata siblings, skip artifacts
--no-wheelsSkip wheel files
--no-sdistsSkip source distributions
--python-tag <tag>Keep wheels with this Python tag; repeat for more tags
--abi-tag <tag>Keep wheels with this ABI tag; repeat for more tags
--platform-tag <tag>Keep wheels with this platform tag; repeat for more tags
--max-file-size-bytes <n>Skip files larger than n when upstream reports a size

--mode all can walk a large upstream. Pair it with artifact filters when you only need part of the wheel matrix.

cache

Cache commands read the same config and --data-dir flags as serve. Output is tab-separated with a header row, so it can be piped to cut, awk, or a spreadsheet without scraping prose.

velodex cache list --data-dir /var/lib/velodex
velodex cache list --index pypi --project flask
velodex cache list --digest 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
velodex cache list --stale --min-age-secs 600 --min-size-bytes 1048576
velodex cache size
velodex cache fsck
velodex cache purge project --index pypi --project flask
velodex cache purge project --index pypi --project flask --yes
velodex cache purge orphaned-blobs
velodex cache purge orphaned-blobs --yes

cache list streams metadata rows and blob paths. The index/project filters apply to cached simple-index pages; the digest filter applies to blob files. Age and size filters apply before output.

cache size reports cached page counts, stale page counts, page record bytes, blob counts and bytes, invalid blob-path counts, and metadata table row counts.

cache fsck checks cached page records, file URL rows, PEP 658 metadata rows, project rows, uploads, overrides, and blob hashes. It prints ok when it finds no problem; otherwise it prints one row per problem and a problems total.

cache purge project removes one project's cached simple page and project-display row. It also removes file URL and PEP 658 metadata rows for digests that no other cached page or upload record references. It does not delete blob files; run cache purge orphaned-blobs after a project purge to reclaim unreferenced blobs.

Purge commands dry-run by default. Add --yes to delete the planned rows or blob files.

backup

backup create reads the same config and --data-dir flags as serve.

velodex backup create --data-dir /var/lib/velodex /backups/velodex-2026-07-03
velodex backup verify /backups/velodex-2026-07-03

backup create writes a directory containing manifest.json, config.toml, metadata/velodex.redb, blobs.tsv, and the referenced files under blobs/sha256/.... It copies only blob digests referenced by metadata records and streams file copies with hash checks. It refuses an existing non-empty backup directory.

config.toml is an effective config snapshot. Treat the backup directory as sensitive when the config contains upload tokens or upstream credentials.

backup verify rehashes the config snapshot, blob index, and each blob. It also opens the copied metadata store and checks that every referenced digest appears in blobs.tsv. It prints ok on success; on failure it prints problem rows and exits non-zero.

restore

velodex restore /backups/velodex-2026-07-03 --data-dir /var/lib/velodex
velodex restore /backups/velodex-2026-07-03 --data-dir /var/lib/velodex --force

restore verifies the backup before writing. It refuses a non-empty target data directory unless --force is passed. With --force, it replaces the target directory, then writes velodex.redb, config.toml, and the referenced blobs. It warns when the config snapshot in the backup names a different data_dir than the restore target.

import-dir

velodex import-dir root/pypi ./dist --data-dir /var/lib/velodex
velodex import-dir hosted ./dist --config velodex.toml

The index argument may be a hosted index name, a hosted route, or a virtual-index route with a hosted upload target. import-dir walks the directory tree, validates .whl and .tar.gz files through the same archive and metadata checks used for uploads, and stores accepted artifacts in the hosted index. Unsupported files are skipped; invalid distribution files are rejected.

Output is tab-separated:

status  filename  project  version  reason

The status field is imported, skipped, or rejected. Each row includes the file name and reason, followed by a summary row with imported, skipped, and rejected counts.

policy

Policy commands read the same config and --data-dir flags as serve.

velodex policy dry-run --data-dir /var/lib/velodex
velodex policy dry-run --index root/pypi --project flask

policy dry-run scans cached Simple pages and uploaded file records, then prints tab-separated denial rows:

action  index  project  filename  version  rule  field  reason
serve   pypi   flask             project-block-list  project  project "flask" is blocked

It does not fetch upstreams and does not change the served index. Use it after editing [index.policy] and before running serve with the same config.

self update

Only binaries placed by the release installer scripts carry this command: those builds compile the self-update feature and read the install receipt the installer wrote. pip-, uv-, and cargo-installed copies neither show nor need it; their package manager owns the file (installation).

On this page