共用サーバーでDockerを使うときはUIDにご用心
投稿日: 2025/05/03
共用サーバーでDockerを使うときにはUIDに気を付けましょう
皆さんはPythonの環境構築にuv
は使っていますか?
比較的新しい、Pythonの様々なものを管理できるツールです。
少し前まではPyTorch
の環境構築には、CUDAを含めた環境構築が楽にできるAnaconda
が使われていたりしましたが、Anaconda
は公式のPyTorch
チャンネルを廃止してしまいました。
機械学習ライブラリ「PyTorch」、公式の「Anaconda」チャンネルを廃止へ/使われていないのに労力がかかりすぎる
「Python」の機械学習ライブラリ「PyTorch」が、公式の「Anaconda」チャンネルを廃止するとのこと。「Anaconda」はデータサイエンス向けPython/Rパッケージのディストリビューションで、そのパッケージ管理システム「conda」は広く使われているが、機械学習で人気を集める「PyTorch」が簡単にインストールできなくなる影響は小さくなさそうだ。
forest.watch.impress.co.jp
この記事では、docker
を使ってCUDAが使えるコンテナを用意し、uv
でPyTorch
が使える環境を作る手順を紹介します(ついでにJupyter Lab
も入れられます)。
docker
は使わないという場合は後半部分(「uvでPyTorchを使えるようにする」以降)を参照してください(CUDAを使える環境であることが前提条件となります)。
Jupyter LabでできることはほとんどVSCodeでできてしまうので、Jupyter Labの需要はあまりないかもしれません。
VSCodeではRemote Development
という拡張機能を入れることで、リモートサーバーで動いているコンテナを開くことができます。
ホストの環境
Ubuntu 24.04.1 LTS
前提条件
docker
とnvidia-container-toolkit
がインストールされているdocker
がない場合は以下の公式ページを参考にインストールしてください。
Install
Learn how to choose the best method for you to install Docker Engine. This client-server application is available on Linux, Mac, Windows, and as a static binary.
docs.docker.com
nvidia-container-toolkit
がない場合は以下の公式ページを参考にインストールしてください。
Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit
docs.nvidia.com
さっそくDockerfile
を作っていきます。
基本形は以下の通りです。このDockerfile
で作ることのできるイメージは以下のようなものです。
CUDA12.6
を使うことができる特筆すべき点はこの後に記載します。
# ベースイメージを指定
FROM nvidia/cuda:12.6.3-cudnn-devel-ubuntu24.04
# 引数
ARG USERNAME=user
ARG UID=1000
ARG GID=1000
# 必要なパッケージを一度にインストール
RUN apt-get update && apt-get install -y \
sudo \
curl \
wget \
git \
software-properties-common \
gnupg \
libcusparselt-dev \
&& rm -rf /var/lib/apt/lists/*
# sudo権限を持つユーザーを作成
RUN groupadd -g $GID $USERNAME &&\
useradd -m -u $UID -g $GID -s /bin/bash -G sudo $USERNAME && \
echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# 作業ディレクトリを切り替え
USER $USERNAME
WORKDIR /home/$USERNAME
ENV PATH="/home/$USERNAME/.local/bin:$PATH"
# GitHub CLIのインストール
RUN sudo mkdir -p -m 755 /etc/apt/keyrings \
&& wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
&& sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& sudo apt update \
&& sudo apt install gh -y
# uvのインストール
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
# Jupyter Labのインストール
RUN uv venv /home/$USERNAME/.venv
ENV PATH="/home/$USERNAME/.venv/bin:$PATH"
RUN uv pip install notebook jupyterlab
# ポートを開放
EXPOSE 8888
# Jupyter Labを起動する
CMD ["jupyter", "lab", "--no-browser", "--ip=0.0.0.0", "--port=8888"]
# ベースイメージを指定
FROM nvidia/cuda:12.6.3-cudnn-devel-ubuntu24.04
# 引数
ARG USERNAME=user
ARG UID=1000
ARG GID=1000
# 必要なパッケージを一度にインストール
RUN apt-get update && apt-get install -y \
sudo \
curl \
wget \
git \
software-properties-common \
gnupg \
libcusparselt-dev \
&& rm -rf /var/lib/apt/lists/*
# sudo権限を持つユーザーを作成
RUN groupadd -g $GID $USERNAME &&\
useradd -m -u $UID -g $GID -s /bin/bash -G sudo $USERNAME && \
echo "$USERNAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# 作業ディレクトリを切り替え
USER $USERNAME
WORKDIR /home/$USERNAME
ENV PATH="/home/$USERNAME/.local/bin:$PATH"
# GitHub CLIのインストール
RUN sudo mkdir -p -m 755 /etc/apt/keyrings \
&& wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
&& sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& sudo apt update \
&& sudo apt install gh -y
# uvのインストール
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
# なにもしないプロセスを作成
CMD ["sleep", "infinity"]
最初にベースイメージを指定しています。ここでCUDAのバージョンと使用するOSを決めます。
# ベースイメージを指定
FROM nvidia/cuda:12.6.3-cudnn-devel-ubuntu24.04
CUDAのバージョンとPyTorch
のバージョンの対応はよく確認してください。
CUDAのバージョンによって使えるPyTorch
のバージョンが異なります(下記折りたたみを参照してください)。
下記Docker Hubのページから使用するnvidia/cuda
のイメージを探します。タグが大量にあるので、使用したいCUDAのバージョンなどでフィルターをかけるのが良いと思います。
https://hub.docker.com/r/nvidia/cuda/tags
{使用したいCUDAバージョン}-cudnn-devel-{OS名}
となっているタグを選びましょう。そうでないと、後々足りないものが出てきて面倒なことになります。
また、PyTorch
が対応しているCUDAのバージョンを選ぶことも重要です。
PyTorch
公式の下記ページにCUDAのバージョンとPyTorch
のバージョンの対応が書かれているので、使いたいPyTorch
のバージョンが決まっている場合などはこれを参考にしてください。
https://pytorch.org/get-started/previous-versions/
選んだら、ベースイメージを指定している部分を以下のように書き換えます。
# ベースイメージを指定
FROM nvidia/cuda:{選択したタグ}
あるかわかりませんが、ここでapt
を使えないOSを選んだ場合はapt install
などをうまく書き換えてください。
以下の部分では引数を定義しています。
# 引数
ARG USERNAME=user
ARG UID=1000
ARG GID=1000
このDockerfile
では以下の値をビルド時に指定できます。
共用サーバーでこれを使う人は、ビルド時にUIDとGIDを指定することを推奨します。
以下の記事を見ると理由がわかります。
https://tech.n-island.dev/posts/20250503/
作成したDockerfileを使ってビルドしてみましょう。
以下のコマンドでビルドできます。このようにすることで、コンテナ内のユーザー名とUID・GIDをホストのものと一致させることができます。
docker build \
--build-arg USERNAME=$(whoami) \
--build-arg UID=$(id -u) \
--build-arg GID=$(id -g) \
-t {イメージの保存名} .
ビルドには時間がかかるので気長に待ちましょう。
💡
「途中でエラーが出てしまった」などの理由でログを保存したい場合は、以下のように
tee
コマンドを使います。docker build \ --build-arg USERNAME=$(whoami) \ --build-arg UID=$(id -u) \ --build-arg GID=$(id -g) \ -t {イメージの保存名} . 2>&1 | tee build.log
ビルドしたイメージを使ってコンテナを立ち上げてみましょう。
以下のコマンドを実行します。ホスト側ポートは他のアプリケーションが使っていないものを選択しましょう。
{イメージ名}
はビルドの際に指定した{イメージの保存名}
です。
docker run --gpus all -d -p {任意のホスト側ポート}:8888 --name {任意のコンテナ名} {イメージ名}
Jupyter Labがない場合はポートを気にする必要がありません。
docker run --gpus all -d --name {任意のコンテナ名} {イメージ名}
Jupyter Labを入れた場合、下記コマンドをホストから実行することでブラウザからアクセスするための情報を得られます。
docker exec -u {ビルド時に作成したユーザー名} {コンテナ名} jupyter server list
以下のような結果が得られます。
Currently running servers:
http://{コンテナ名}:8888/?token={トークン} :: /home/{ユーザー名}
この結果を基に、Jupyter Labには以下のURLでブラウザからアクセスできます。
http://127.0.0.1:{docker runで指定したポート}/lab?token={トークン}
{docker runで指定したポート}
はdocker run
において{任意のホスト側ポート}
として指定したポート。
http://{リモートサーバーのIPアドレス}:{docker runで指定したポート}/lab?token={トークン}
ようやく本題です。
プロジェクトを作成したい場所で以下のコマンドを実行します。
プロジェクト名を省略した場合は現在のディレクトリが初期化されます。
uv init {プロジェクト名}
cd {プロジェクト名} # 移動
上記コマンドを実行するとディレクトリの中は以下のような構成になっていると思います。
{プロジェクト名}
|--.gitignore
|--.python-version
|--README.md
|--main.py
|--pyproject.toml
uv
ではpyproject.toml
を用いてプロジェクトを管理します。
pyproject.toml
を開いて以下のように追記します。
CUDAのバージョンに合わせてcu126
と書かれた部分を書き換えてください。例えば、CUDA11.8であればcu118
です。
[project]
name = "{プロジェクト名}"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []
# 追記
[tool.uv.sources]
torch = { index = "pytorch-cu126" }
torchvision = { index = "pytorch-cu126" }
torchaudio = { index = "pytorch-cu126" }
[[tool.uv.index]]
name = "pytorch-cu126"
url = "https://download.pytorch.org/whl/cu126"
explicit = true
ここで、以下のサイトでCUDAのバージョンとPyTorch
のバージョンの対応を調べます。
Previous PyTorch Versions
Access and install previous PyTorch versions, including binaries and instructions for all platforms.
pytorch.org
これを基に、以下のコマンドを実行します。このコマンドはCUDAのバージョンやPyTorch
のバージョンに合わせて変えてください。
今回はCUDA12.6を入れたので、使えるPyTorch
のバージョンは2.6.0
のみのようです。
uv add torch==2.6.0+cu126 torchvision==0.21.0+cu126 torchaudio==2.6.0+cu126
これを実行すると、torch
がインストールされます。
最後にCUDAが使えるか確認してみましょう。
uv run python
Python 3.12.3 (main, Feb 4 2025, 14:48:35) [GCC 13.3.0] on linux
>>> import torch
>>> torch.cuda.is_available()
True
ちゃんと使えていそうです。
今回はdocker上でCUDAが動くようにしてuv
でPyTorch
の環境構築をしました。
Dockerfileはある程度使いまわせるとは思いますが、環境によってはライブラリが足りないなどの問題が起こる可能性もあり、その際は柔軟に対応する必要があります。
少なくとも今回紹介したDockerfileをそのまま使う分には問題は起きないと思われます。