メインコンテンツまでスキップ

PyPiServerのセットアップ記録

最近、私のパッケージインストールファイルを保管するためにPyPi Serverを立てました。UbuntuシステムとDockerを使用して設定を行い、その過程をここに記録します。

ヒント

読者がすでにUbuntuにDockerをインストールしており、Dockerの基本操作に慣れていることを前提としています。もしそうでない場合は、関連する知識を補ってから進めてください。

イメージの取得

docker pull pypiserver/pypiserver:latest

ディレクトリの作成

無駄にしないために、ホームディレクトリにPythonパッケージを保存するためのディレクトリを作成します。

mkdir ~/packages

好きな名前に変更しても構いませんが、その後の設定ファイルも変更する必要があります。

htpasswdの設定

ヒント

もしパスワードを設定したくない場合、この手順はスキップできます。

htpasswdはユーザー名とパスワードを保存するファイル形式で、pypiserverはこのファイルを使ってユーザー認証を行います。これは簡単で有効な方法であり、pypiserverのセキュリティを強化する手段となります。

まず、apache2-utilsをインストールします:

sudo apt install apache2-utils

次に、以下のコマンドを使って新しい.htpasswdファイルを作成します:

htpasswd -c ~/.htpasswd [username]

このコマンドを実行すると、usernameのパスワードを入力するよう求められます。パスワードを入力後、.htpasswdファイルがホームディレクトリに作成されます。ファイルが作成されたら、前述のdocker runコマンドを使ってpypiserverを起動し、.htpasswdファイルで認証を行います。

バックグラウンドサービスとしての設定

Dockerコンテナをバックグラウンドサービスとして実行するために、Docker ComposeとSystemdを解決策として使用します。

まだDocker Composeをインストールしていない場合は、インストールが必要です。以下を参照してください:

最近、Docker Composeは大規模なアップデートを行い、多くの使い方が以前と異なっています。最も顕著な変更は、従来のdocker-composeコマンドがdocker composeに変更されたことです。

最新のDocker Composeをインストールするには:

sudo apt update
sudo apt install docker-compose-plugin

Docker Composeが正しくインストールされているか確認します:

docker compose version

設定ファイルの作成

任意の場所にdocker-compose.ymlを作成し、以下の内容を入力します:

docker-compose.yml
version: "3.3"
services:
pypiserver:
image: pypiserver/pypiserver:latest
volumes:
- /home/[ユーザー名]/auth:/data/auth
- /home/[ユーザー名]/packages:/data/packages
command: run -P /data/auth/.htpasswd -a update,download,list /data/packages
ports:
- "8080:8080"
  • 上記の[ユーザー名]を実際のユーザー名に置き換えてください。
  • 外部のポートマッピングを変更することもできます。例えば、"18080:8080"に変更できます。
ヒント

pypiserverが提供するテンプレートを参考にできます:docker-compose.yml

パスワードを設定したくない場合、上記のcommandを以下のように変更します:

command: run -a . -P . /data/packages --server wsgiref

Systemdサービスの作成

設定ファイルを作成します:

sudo vim /etc/systemd/system/pypiserver.service

以下の内容を記入します:

/etc/systemd/system/pypiserver.service
[Unit]
Description=PypiServer Docker Compose
Requires=docker.service
After=docker.service

[Service]
WorkingDirectory=/path/to/your/docker-compose/directory
ExecStart=/usr/bin/docker compose up --remove-orphans
ExecStop=/usr/bin/docker compose down
Restart=always

[Install]
WantedBy=multi-user.target
  • /path/to/your/docker-compose/directoryを実際のdocker-compose.ymlのディレクトリに置き換えてください。ファイル名は不要です。
  • Dockerのパスが正しいことを確認してください。which dockerで確認できます。

サービスの起動

systemdに新しいサービス設定を読み込ませます:

sudo systemctl daemon-reload

サービスを起動します:

sudo systemctl enable pypiserver.service
sudo systemctl start pypiserver.service

サービスの状態確認

サービスの現在の状態を確認するには、以下のコマンドを使用します:

sudo systemctl status pypiserver.service

これにより、pypiserverサービスの現在の状態や、実行中かどうか、最新のログ出力が表示されます。

pypiserver status

使用開始

これで、pipを使ってパッケージのインストールとアップロードができるようになりました。

パッケージのアップロード

例えば、example_package-0.1-py3-none-any.whlというパッケージがあると仮定します。次にtwineツールを使ってパッケージをアップロードします:

pip install twine
twine upload --repository-url http://localhost:8080/ example_package-0.1-py3-none-any.whl
  • localhost:8080はあなたのpypiserverサービスのアドレスとポートであることを確認してください。

パッケージのインストール

インストール時には、pypiserverサービスのアドレスとポートを指定する必要があります:

pip install --index-url http://localhost:8080/ example_package

基本認証の使用

もしpypiserverが基本認証を設定している場合、アップロードまたはダウンロード時に認証情報を提供する必要があります:

  • パッケージをアップロード:

    twine upload \
    --repository-url http://localhost:8080/ \
    --username [username] \
    --password [password] \
    example_package-0.1-py3-none-any.whl
  • パッケージをインストール:

    pip install \
    --index-url http://[username]:[password]@localhost:8080/ \
    example_package

pip.confの設定

もしこのサーバーから頻繁にパッケージをインストールする場合、毎回pip install時に--index-urlを指定するのが面倒なら、pip.confに設定情報を記入することを検討できます。

設定ファイル

pip.confファイルは複数の場所に配置できます。優先順位順に探してください:

  • 優先順位 1: サイトレベルの設定ファイル:

    • /home/[ユーザー名]/.pyenv/versions/3.x.x/envs/main/pip.conf
  • 優先順位 2: ユーザー単位の設定ファイル:

    • /home/[ユーザー名]/.pip/pip.conf
    • /home/[ユーザー名]/.config/pip/pip.conf
  • 優先順位 3: グローバル設定ファイル:

    • /etc/pip.conf
    • /etc/xdg/pip/pip.conf

現在のPython環境がどのファイルを使用しているかを確認し、そのファイルに以下の内容を追加します:

[global]
index-url = http://[サービスのIP]:8080/
trusted-host = [サービスのIP]

再度、[サービスのIP]:8080を正しいpypiserverのアドレスとポートに置き換えてください。

設定後、pip install [package_name]を実行すると、システムは自動的にpip.confに設定されたサーバーアドレスをパッケージのソースとして使用します。

結語

これで、自分のPyPIサーバーを立て、パッケージのアップロードとインストールができるようになりました。

この記事が役に立ち、問題解決に繋がることを願っています。