Run a private PyPI server for faster pip installs (and less data burn in India)
Set up a lightweight private PyPI server to speed pip installs, avoid rate limits, and save mobile data — practical steps for Indian devs and small teams.
Written by: Rohan Deshpande
A few months into supporting a product for clients across tier‑2 Indian cities I started getting panicked Slack pings: CI jobs timing out, failed deploys, developers stuck while pip crawled through package installs on flaky connections. The culprit wasn’t bad code — it was repeated hits to pypi.org from dozens of machines, occasional throttling, and a lot of wasted mobile data.
Running a small private PyPI server changed that. Not magic — just predictable installs, cached wheels, and far fewer surprises during demos on unreliable networks. If you care about developer time, CI speed, and keeping data costs down in India, this is the most practical infra tweak you can add for minimal effort.
Why a private PyPI server helps (quick):
- Caches packages locally so first install pulls from pypi.org but subsequent installs are fast and small.
- Avoids pypi rate limits when many developers/CI runners hit the public index.
- Lets you host internal wheels and guaranteed builds without spraying credentials.
- Saves mobile data when working off a hotspot (warm cache = little network traffic).
Main keyword note: I’ll refer to the private PyPI server setup as the private PyPI server below.
What I run (simple, low-cost)
- devpi-server as the cache + simple upload host (lightweight, battle-tested).
- Nginx reverse proxy for TLS and basic auth (optional, recommended).
- A tiny VPS (₹300–800/month) or a home NAS/VM if you prefer — 1–2GB RAM is fine. This combination gives you a private PyPI server that proxies pypi.org, stores wheels, and serves your private packages.
Quick setup (the exact commands are the real thing I use)
- Install devpi:
- On the server: python3 -m venv /opt/devpi && source /opt/devpi/bin/activate
- pip install —upgrade pip devpi-server devpi-web
- Initialize and start:
- devpi-server —start —host 0.0.0.0 —port 3141 —serverdir /var/lib/devpi
- (Check logs at /var/lib/devpi/.xproc or run without —start for foreground debugging.)
- Configure a user and the proxied index:
- devpi use http://localhost:3141
- devpi login root —password=”
- devpi index -c root/pypi mirror_url=https://pypi.org/simple/
- Put Nginx in front for TLS and a friendly hostname (pypi.yourdomain.com), and add basic HTTP auth if you want to lock down access.
Point pip at the cache:
- Create or edit ~/.config/pip/pip.conf (Linux) or %APPDATA%\pip\pip.ini (Windows) with: [global] index-url = https://pypi.yourdomain.com/root/pypi/+simple/
Now all pip installs will go through your private PyPI server. First time a package is requested it fetches from pypi.org and stores a wheel/sdist; after that your network only transfers the cached artifact.
Practical tips that saved me real time and money
- Warm your cache in CI: run pip download -r requirements.txt in a scheduled job to pre-populate commonly used packages before a run. That transforms CI from minutes to seconds.
- Build and upload wheels for internal packages. devpi makes this trivial and keeps installs deterministic.
- For flaky mobile hotspots, sync a wheelhouse locally (pip download) and use —no-index —find-links pointing to local dir for installs.
- Configure pip’s cache-dir on CI runners to share the same disk (or mount an NFS/SMB share) so runners reuse caches.
Tradeoffs and limits (be honest)
- Maintenance: you need to monitor disk usage and upgrade devpi occasionally. Packages and wheels consume space — plan pruning or set a quota.
- Stale caches: if a package is yanked or updated upstream, your private PyPI server might keep an old copy. Decide on a cache eviction policy and a clear way to force fetch-from-upstream.
- Security: running a server increases your attack surface. Always run behind TLS, keep auth for private artifacts, and restrict access by IP where sensible.
- Initial misses: the very first install of any package still hits pypi.org and is slow. The benefit grows over time and with a team.
Cost and India context
- A cheap ₹300–800/month VPS (local provider or a light Linode/Hetzner-equivalent) is enough for small teams. If you’re working solo and want zero recurring cost, run the same stack on a home machine or Raspberry Pi.
- Mobile data is expensive in certain workflows (tethering, remote sites). A warmed cache turns multi-megabyte installs into kilobyte metadata requests — real savings over time.
- If your company already uses Artifactory/Nexus, they do the same job. The difference here is a low-friction, open‑source private PyPI server you can spin up in hours.
When this isn’t worth it
- If you are a one-person hobbyist who rarely reinstalls environments, the overhead might not be worth it.
- If your org has strict compliance or needs enterprise support, consider a commercial artifact manager.
Closing note The private PyPI server isn’t a silver bullet — it’s a small, focused infrastructure investment that pays back in saved developer time and fewer CI surprises. For teams in India where bandwidth and throttling are real problems, it’s one of the few tweaks that feels instantly impactful. Set it up, warm the cache, and enjoy pip installs that behave like someone finally came and fixed the plumbing.
If you want, I can share a ready-to-run devpi systemd unit, nginx snippet, and a pip.conf you can drop into CI.