OmniRepo is a self-hosted registry that speaks OCI, RPM, APT, PyPI, Helm, Go, npm, Maven, Git, S3 & raw blobs natively — with built-in Trivy vulnerability scanning, project-scoped RBAC, and an air-gap invariant enforced in CI. Drop it on a host, point your build tools at it, done.
One container sits between what your team builds and everything that consumes those artifacts. No agents, no sidecars, no shared file systems.
Trivy ships inside the container with an air-gap-baked vulnerability database. RPM cpio payloads and PyPI wheel transitive deps are unpacked before the scan — so Trivy sees real filesystem entries, not just metadata. Per-repo gates refuse pulls of artifacts whose latest scan found findings at or above your threshold.
Set block_on_severity to critical, high, medium or low. Pulls of unscanned-or-vulnerable artifacts return 403.
RPM cpio payloads walked. PyPI wheel transitive deps resolved. OCI layers fully extracted. Trivy sees real filesystem trees, not artifact metadata.
Ship with a vuln DB baked into the image. Refresh via Admin → Trivy DB — upload a tarball, or (if allowed) click to pull. Nothing phones home without you.
Scan jobs run in a worker pool. Results are indexed in SQLite FTS5 — searchable by CVE ID, artifact, or project from the sidebar.
One Go binary. One HTTP/HTTPS port. One mounted volume. Multiplex every build tool in your shop through a registry that's auditable, scanned, and project-scoped by default.
Every handler mounts as an http.Handler on the same chi router. No sidecars, no reverse proxy, no adapter glue. Same auth, same audit log, same storage primitives.
Embedded subprocess with an air-gap-baked DB. Per-repo gates refuse pulls above a severity threshold.
A single SHA-256 blob tree underneath every protocol. No duplicates across repos; atomic renames; fsync'd parents.
Auth decisions, uploads, admin changes — all logged to SQLite plus an NDJSON mirror you can tail.
User-owned or project-owned. Prefix-indexed SHA-256. Shown exactly once.
Flat user / project / member model. Every artifact lives under a project; non-members get a 403.
Full-text search across repos, artifacts, CVEs and packages — one WAL-mode database, one binary. Filter by Kind (repos · artifacts · CVEs), Severity, or Project.
Mirror APT, RPM, PyPI, and Helm upstreams into OmniRepo's local cache — with per-protocol allowlist filters and optional stored upstream credentials, encrypted at rest. Native clients pull from your host — not the internet. Triggered on demand from the UI, or by your existing scheduler hitting /sync.
When an upstream removes a package, OmniRepo's mirror reflects it — drifted artifacts move to the trash (7-day retention, restorable). If a sync would purge more than 50% of a repo, OmniRepo blocks it and shows an admin-confirm dialog so a broken upstream can't accidentally wipe your cache.
Pull a specific tag or digest from Docker Hub, GHCR, or Quay into a local repo. Cherry-pick what you need — no full mirror required.
A GOPROXY module proxy for go get, an npm registry with native npm publish and immutable versions, and a full Maven layout for mvn deploy / Gradle. Landed on main right after v1.0.1 — shipping in the next tagged release.
Every repo page shows ready-to-use commands pre-filled with your host, project, and tag — docker pull, pip install, helm repo add, apt source lists, GOPROXY exports, .npmrc config, and Maven pom.xml blocks.
Seed users, projects, repos, and API keys from a single bootstrap.json on first boot. Fully automatable — no manual clicks.
Full REST API spec at /api/docs/. Explore endpoints, try requests, and generate client SDKs — all shipped inside the container.
React 19 + shadcn/ui, embedded via go:embed. No extra container, no CDN, no third-party panel. Manage everything from one place — repos, scans, keys, S3 buckets, mirrors, and audit logs.
No outbound HTTP from the binary without an explicit admin action. We assert it with make test-airgap on every PR — the binary boots in a sandboxed net namespace and must make zero outbound calls.
Fonts embedded. Icons tree-shaken into the bundle. Swagger UI copied at build time. Trivy shipped with a baked DB. The binary makes zero outbound HTTP calls of its own — asserted in CI.
m=64MiB, t=3, p=4 for passwords. API keys are prefix-indexed SHA-256. Docker JWTs are HS256 with a per-install 32-byte secret. Sessions are 12h sliding cookies.
Upload a PEM pair through Admin → TLS. The live listener swaps without restarting the server. Old certs archived for rollback.
Pull the image, mount a volume, open the web UI. On first boot OmniRepo lays out the data root, applies migrations, and mints a self-signed TLS cert.
One HTTP port, one HTTPS port, one mounted volume. That's the whole deployment.
Seed from bootstrap.json or rotate the temp password on first login. Argon2id, session cookies, 12h sliding TTL.
Repos live under projects. Pick a type — docker, rpm, deb, pypi, helm, go, npm, maven, raw, git, s3 — and point your build tool at it.
Artifacts land in the CAS tree. Trivy scans in a background pool. Gates block severity thresholds on pull.
$ quick start · bash # 1. Run it docker run -d --name omnirepo \ -p 8080:8080 -p 8443:8443 \ -v /srv/omnirepo:/var/lib/omnirepo \ ghcr.io/vladoportos/omnirepo:latest # 2. Push an OCI image docker login https://host:8443 docker tag nginx:latest \ host:8443/platform/docker/images/nginx:latest docker push host:8443/platform/docker/images/nginx:latest ✓ sha256:f3e4… 2.1 MB / 2.1 MB pushed # 3. Publish a Python wheel twine upload --repository omnirepo dist/*.whl ✓ mypkg-1.2.0-py3-none-any.whl scan: 0 CVE # 4. Serve an APT repo (on the client) echo "deb https://host:8443/platform/deb/stable/ bookworm main" \ | sudo tee /etc/apt/sources.list.d/omnirepo.list sudo apt update && apt install myapp
OmniRepo is built for small-to-mid teams and air-gapped corporate environments. If you need federation and HA clustering, grab a commercial tool. If you need one pane of glass on a single host, read on.
| OmniRepo v1.0.1 | Artifactory | Nexus Repository | Harbor | |
|---|---|---|---|---|
| Single static binary | ● pure-Go, scratch | ○ JVM + WAR | ○ JVM | ◐ Go, but split |
| OCI / Docker | ● native /v2 | ● native | ● native | ● native |
| RPM · APT · PyPI · Helm | ● all four, native | ● all four | ● all four | ○ OCI only |
| Go proxy · npm · Maven | ● native, on main | ● all three | ● all three | ○ |
| Git hosting | ● Smart HTTP | ○ | ○ | ○ |
| S3 API (SigV4) | ● gofakes3 + SigV4 | ◐ via gateway | ○ | ○ |
| Built-in vulnerability scan | ● Trivy, baked DB | ● Xray (paid) | ◐ IQ Server (paid) | ● Trivy |
| Air-gap invariant in CI | ● make test-airgap | ○ | ○ | ○ |
| License | ● Apache-2.0 | ◐ commercial | ◐ open core | ● Apache-2.0 |
OmniRepo is open source under the Apache-2.0 license — the whole Go binary, web UI, and protocol handlers are on GitHub. The container image is free to self-host, forever. File a bug, request a protocol, or send a pull request — issues and contributions are open.
Short, honest answers. If something's missing, open an issue on GitHub.
v1.0.1 is the current release. Pull and run it: docker run -d -p 8080:8080 -p 8443:8443 -v /srv/omnirepo:/var/lib/omnirepo ghcr.io/vladoportos/omnirepo:latest — or pin ghcr.io/vladoportos/omnirepo:1.0.1 for reproducible deploys. Source code and releases are on GitHub; the install steps cover first-boot login.main right after v1.0.1 and ship in the next tagged release. You get an npm registry (packuments, tarballs, native npm publish, immutable versions), a GOPROXY module proxy (go get with GOPROXY pointed at OmniRepo), and a full Maven repository layout (mvn deploy / Gradle maven-publish with checksums and metadata). OCI/Docker, RPM, APT, PyPI, Helm, Git, S3, and raw are all in the current release.Apache-2.0. There's no paid tier, no "open core" trap, and no license server phoning home.docker run, your data never leaves your network.v1.0 — once the core protocol work is locked down and we can give enterprise auth the attention it deserves.linux/amd64; arm64 / Raspberry Pi support is on the roadmap for a follow-up release.make test-airgap, which boots the binary in a sandboxed network namespace and fails if a single byte leaves. The only network egress that ever happens is when an admin clicks Update on the Trivy DB page, and even that is optional — you can drop a tarball onto disk instead.public_read: true on any repo. Anonymous GET and HEAD requests are allowed so native clients (pip, apt, helm, docker pull) can pull without credentials. Writes always require an authenticated user or API key. Useful for serving packages to CI runners that don't carry tokens, or for public open-source mirrors.POST /api/v1/projects/<p>/repos/<type>/<repo>/sync. We made this call early on: the right scheduler for your environment is the one you already have — crontab, systemd timers, Kubernetes CronJob, GitLab schedules, Jenkins, Argo, whatever. Adding one inside OmniRepo would mean re-implementing all of those badly. A one-line crontab entry beats a scheduler goroutine + a cron parser + next-run state + UI surface every time.Deploy OmniRepo on any Linux host with one docker run. Bring your build tools, bring your air-gap policy, bring your audit requirements.