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.

diagram

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:

  • LYNCH: 51.158.189.200 in AMS-1 (Amsterdam)
  • DUPIEUX: 51.15.230.78 in PAR-1 (Paris)

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)