pypiron

pypiron

Docker app from pypiron's Repository

Overview

Self-hosted PyPI server that does four jobs from one URL and one binary: hosts your private uploads, mirrors an allowlist of public packages, proxies the rest of PyPI on demand, and serves it all from a standard simple index. No database — the files on disk ARE the truth and the indexes are regenerable views, so backups are just the appdata folder. Speaks pip / uv / poetry / pdm / twine unchanged. Point pip or uv at http://YOUR-Unraid-IP:8080/simple/ and you have a working index. Set the Admin Password to enable uploads and admin (publish / delete / yank / mirror); leave it blank for a read-only public index. To proxy public PyPI on demand, set Proxy Upstream to https://pypi.org/simple/. Notes for Unraid: the container runs as the standard appdata user (99:100) so it can write to /data. The Data path IS your registry — back it up. Heads-up: pypiron is early (version 0.0.0 placeholder, beta) — run it where the blast radius is bounded.

pypiron-unraid

Unraid Community Applications template for pypiron — a self-hosted PyPI server in a single binary, with no database. One container hosts your private uploads, mirrors an allowlist of public packages, proxies the rest of PyPI on demand, and serves it all from a standard simple index. Docs: pypiron.com.

This repo exists only to publish and maintain the Unraid listing, kept separate from the source tree so Community Applications scans templates (not the Rust project) and listing tweaks don't need a pypiron release.

Layout

ca_profile.xml          # repository profile shown in Community Applications
LICENSE                 # MIT (mirrors pypiron)
icon.png                # 256×256 brand mark
templates/
  pypiron.xml           # the Docker container template

What the template sets up

  • WebUI / index on port 8080 — dashboard at /, simple index at /simple/.
  • Data at /data (default /mnt/user/appdata/pypiron) — the package storage tree. This is your registry; back it up. Upload/proxy spooling lands here too (PYPIRON_SPOOL_DIR=/data/spool) so multi-GB wheels never spool into container RAM.
  • Admin Password (PYPIRON_ADMIN_PASS) — set it to enable uploads + admin (publish/delete/yank/mirror); blank leaves a read-only public index.
  • Proxy Upstream (PYPIRON_PROXY_UPSTREAM) — set to https://pypi.org/simple/ to lazily proxy and cache PyPI; blank for a private-only index.
  • Advanced: admin user, spool dir, and a Read User/Password pair to make reads private.

Unraid specifics

The pypiron image is distroless — it runs as a fixed non-root uid and has no PUID/PGID and no shell. The template runs the container as the standard appdata owner via --user 99:100 so it can write to /data; the binary does no passwd lookup, so an arbitrary uid is fine. (That's also why there's no console/shell button.)

Publishing to Community Applications

  1. Push this repo to github.com/blackthorn-interstellar/pypiron-unraid on the master branch (the raw URLs in ca_profile.xml and templates/pypiron.xml assume that).
  2. Submit the repo at ca.unraid.net/submit — the validator parses ca_profile.xml + the template, checks for duplicates, and previews the listing before publish.

Updating the listing later is just a push to this repo; CA re-scans.

Before first submission

  • Create the GitHub repo and push (master branch).
  • Create an Unraid support forum thread and swap <Support> in templates/pypiron.xml from the GitHub issues URL to the forum topic (CA prefers a forum thread).
  • Confirm ghcr.io/blackthorn-interstellar/pypiron:latest is public and multi-arch.
  • Optionally add a Screenshot of the dashboard to the template.
  • Run the validator at ca.unraid.net/submit and fix anything it flags.

Install Pypiron on Unraid in a few clicks.

Find Pypiron in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.

Open the Apps tab on your Unraid server Search Community Apps for Pypiron Review the template variables and paths Click Install

Requirements

Outbound internet is only needed if you enable the proxy or sync. A pure private index needs none.

Related apps

Details

Repository
ghcr.io/blackthorn-interstellar/pypiron:latest
Last Updated2026-07-07
First Seen2026-07-02

Runtime arguments

Web UI
http://[IP]:[PORT:8080]/
Network
bridge
Privileged
false
Extra Params
--user 99:100

Template configuration

WebUI PortPorttcp

HTTP port the index and web dashboard listen on.

Target
8080
Default
8080
Value
8080
DataPathrw

The package storage tree — this IS your registry (private uploads + mirrored/proxied cache). Back it up. Upload/proxy spooling also lands here, so multi-GB wheels never spool into container RAM.

Target
/data
Default
/mnt/user/appdata/pypiron
Value
/mnt/user/appdata/pypiron
Admin PasswordVariable

Set this to enable uploads + admin actions (publish / delete / yank / mirror). Leave blank for a read-only public index. Reads stay public unless you also set a Read Password.

Target
PYPIRON_ADMIN_PASS
Proxy UpstreamVariable

Turn on the on-demand pull-through proxy of a public index. Set to https://pypi.org/simple/ to lazily proxy and cache PyPI. Leave blank for a private-only index.

Target
PYPIRON_PROXY_UPSTREAM
Admin UserVariable

Username for the admin credential.

Target
PYPIRON_ADMIN_USER
Default
admin
Value
admin
Spool DirVariable

Where uploads/downloads spool to disk. Kept under /data (real disk) on purpose so large wheels never spool into container RAM.

Target
PYPIRON_SPOOL_DIR
Default
/data/spool
Value
/data/spool
Read UserVariable

Set Read User + Read Password to make the whole index private (reads require auth). Leave both blank to keep reads public.

Target
PYPIRON_READ_USER
Read PasswordVariable

Password for the read credential (see Read User).

Target
PYPIRON_READ_PASS