Overview
This PyPi server is hosted under the DNS pypi.nibble.ai.
The host name pypi.nibble.ai is not reachable from a browser, because we filter requests based on User-Agents. Only pip’s user-agent can pass… It’s definitely not a robust protection, but it costs nothing.

DNS Load Balancing
We se CloudFlare Load Balancer.
It maps the domain name pypi.nibble.ai to all of our servers IP (see below).
The LB performs health-checks every minute. In regular usage, traffic is evenly distributed between the servers. If a server becomes unreachable for any reason, all traffic is routed to the healthy servers only.
Servers
Two identical servers are deployed on Scaleway, in two different regions for high-availability setup:
They don’t need to be performance beasts, at least as long as we don’t upload/download like crazy. Current instance type is DEV1-S, with 2 GB or RAM and 2 CPUs.
OS and dependencies
Both machines have identical file systems. They both run on Ubuntu, and run three Docker containers:
- Nginx
- authentication service (a flask app)
- pypiserver itself
A CRON job runs every hour to synchronize the S3 bucket that contains the archives (.whl and .tar.gz) on disk. Volume mounts maps the local disk to Docker container.
The configuration of these servers is versioned in the private-pypi GitHub repo.
TODO
We should add a monitoring layer, at 2 levels:
- Technical monitoring (CPU usage, RAM, bandwidth, uptime…)
- Usage monitoring (download count, identifier)