プライベートなPyPIをpypiserverとDockerで簡単に作成する

イントラネット環境からのみアクセス可能なPyPI(
The Python Package Index)を作りたい場合。 Dockerとpypiserverを利用すれば、簡単にプライベートなPyPIが作れます。

github.com

プライベートのPyPIを構築

例えばEC2のLinux上なら、単純に認証無しの場合は2ステップで構築完了です。(以下の例はAmazon Linux使ってます)

# dockerをインストール
sudo yum install -y docker
sudo systemctl start docker
sudo systemctl enable docker

### pypiserverを起動
sudo docker run --name pypiserver  -d --rm -p 80:8080 -v pypiserver_packages:/data/packages pypiserver/pypiserver:latest -P .  -a . packages

Dockerコマンド打ったらブラウザでアクセスすれば、pypiserverサーバーが起動しているのが確認できるはずです。

※今回はこの 13.231.250.39 というグローバルIP使って話進めます。(この記事書き終わったら消すのでアクセスしても繋がりません。)

f:id:yomon8:20190509000429p:plain

なお、上記のDockerコマンドでDocker Volumeをマウントしているので、このVolume削除しない限りは登録したパッケージも永続します。

$ sudo docker volume ls 
DRIVER              VOLUME NAME 
local               pypiserver_packages

プライベートPyPIにパッケージを登録してみる

起動したpypiserverに適当なCLIを作って登録してみます。

真っ皿なpython実行環境立ち上げます。

docker run --rm -it python:3.6.8 /bin/bash

とりあえず作業ディレクトリ作成。

$ mkdir yomon-clii && cd yomon-clii

CLIの実行ファイルを作成します。

$ cat <<EOF > yomon-cli
#!/usr/bin/env python
import sys
def main():
   print('TEST!!TEST!!TEST!!')
if __name__ == '__main__':
    sys.exit(main())
EOF

setup.py を作ります。

$ cat <<EOF > setup.py
from setuptools import setup

setup(
    name="yomon-cli",
    version="1.0.0",
    scripts=["yomon-cli"]
)
EOF

プライベートなpypiに上げるために .pypirc 設定します。

$ cat <<EOF > ~/.pypirc
 [distutils]
 index-servers =
   privatepypi

 [privatepypi]
 repository: http://13.231.250.39
 username: 
 password: 
EOF

twine使わずにそのままsetuptoolsでプライベートpypiにパッケージ上げてしまいます。 コマンド打つとパスワード聞かれますが、今回は認証設定してないので、そのままEnterで続行できます。

$ python setup.py sdist upload -r privatepypi

プライベートPyPIからパッケージをインストールしてみる

pip searchで登録したパッケージが存在しているか確認します。其の際に --index オプションでpypiserverのアドレスを指定します。

$ pip search --index http://13.231.250.39 yomon-cli 
yomon-cli (1.0.0)  - 1.0.0

インストール時も同様に、--extra-index-url でアドレス指定します。また、httpの場合は --trusted-host も指定するとpypiserverからパッケージのインストール可能です。

$ pip install --extra-index-url http://13.231.250.39 --trusted-host 13.231.250.39 yomon-cli
Looking in indexes: https://pypi.org/simple, http://13.231.250.39 
Collecting yomon-cli 
  Downloading http://13.231.250.39/packages/yomon-cli-1.0.0.tar.gz 
Building wheels for collected packages: yomon-cli 
  Building wheel for yomon-cli (setup.py) ... done 
  Stored in directory: /root/.cache/pip/wheels/01/85/7a/6672f73e357aad05bff7f68348f43379922a1493e093e95b7f 
Successfully built yomon-cli
Installing collected packages: yomon-cli 
Successfully installed yomon-cli-1.0.0 

先程登録したパッケージがインストールできているみたいです。

$ pip show yomon-cli  
Name: yomon-cli 
Version: 1.0.0
Summary: UNKNOWN
Home-page: UNKNOWN 
Author: UNKNOWN
Author-email: UNKNOWN
License: UNKNOWN
Location: /usr/local/lib/python3.6/site-packages
Requires:
Required-by:

実行してみたところ。

$ yomon-cli 
TEST!!TEST!!TEST!! 

Docker Compose and Poetry版(2021/11/22追記)

docker-composeとPoetryでも便利なので載せておきます。

Docker ComposeでPypiServer立ち上げ

まずはDocker Composeです。Basic認証入れています。

---
version: "3.3"

services:
    pypiserver:
        container_name: pypiserver
        image: pypiserver/pypiserver:v1.4.2
        volumes:
            - type: bind
              source: ./packages
              target: /data/packages
            - type: bind
              source: ./auth
              target: /data/auth
              read_only: true
        command: -P /data/auth/.htpasswd -a update,download,list /data/packages
        ports:
            - "8080:8080"

PoetryでBuild and Publish

PoetryからのPublishはとても楽ちんです。

poetry config repositories.myrepo https://mypypi.yourdomain.com/
poetry publish --build -r myrepo -u basicuser -p basicpasswd

参考

GitHub - pypiserver/pypiserver: Minimal PyPI server for uploading & downloading packages with pip/easy_install

https://hub.docker.com/r/pypiserver/pypiserver