🥷

Docker上でPoetryをインストールしようとしたらはまった話

2024/05/13に公開

よく読めばすぐわかる問題だったけど、こういう時遠回りしちゃうんだよなー
後々考えた適切と思われる解析のやり方と一緒に、備忘録として残しておく

前提

対象のDockerfile

Dockerfile
FROM python:3.11.9
ENV PYTHONUNBUFFERED=1

WORKDIR /app

# poetryのインストール
RUN curl -sSL https://install.python-poetry.org | python3
COPY pyproject.toml* poetry.lock* ./

RUN poetry config virtualenvs.in-project true
RUN poetry install --no-dev

COPY src/ /app

# entrypoint
ENTRYPOINT ["poetry", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--reload"]

現象

ログ

Docker上でpoetryをインストールするDockerfileをビルド中にエラーを吐いた
RUN poetry config virtualenvs.in-project trueした時に
poetry: not found poetryがないと言っていらっしゃる

docker build ./ -t test_container

[+] Building 1.7s (9/11)                                                             docker:desktop-linux
 => [internal] load .dockerignore                                                                    0.0s
 => => transferring context: 107B                                                                    0.0s
 => [internal] load build definition from Dockerfile                                                 0.0s
 => => transferring dockerfile: 547B                                                                 0.0s
 => [internal] load metadata for docker.io/library/python:3.11.9                                     1.6s
 => [1/7] FROM docker.io/library/python:3.11.9@sha256:e453eb723bc8ecac7a797498f9a5915d13e567620d48d  0.0s
 => [internal] load build context                                                                    0.0s
 => => transferring context: 1.49kB                                                                  0.0s
 => CACHED [2/7] WORKDIR /src                                                                        0.0s
 => CACHED [3/7] RUN curl -sSL https://install.python-poetry.org | python3                           0.0s
 => CACHED [4/7] COPY pyproject.toml* poetry.lock* ./                                                0.0s
 => ERROR [5/7] RUN poetry config virtualenvs.in-project true                                        0.1s
------
 > [5/7] RUN poetry config virtualenvs.in-project true:
0.108 /bin/sh: 1: poetry: not found
------
Dockerfile:12
--------------------
  10 |     COPY pyproject.toml* poetry.lock* ./
  11 |
  12 | >>> RUN poetry config virtualenvs.in-project true
  13 |     RUN poetry install --no-dev
  14 |
--------------------
ERROR: failed to solve: process "/bin/sh -c poetry config virtualenvs.in-project true" did not complete successfully: exit code: 127

原因

原因想定

考えられるのは

  • Pathが通ってない
  • インストールが正常にいっているように見えるがこけてる
  • などなど

何にせよログをよく読んだ方がいいね
build中のログを吐かせる方法は以下
(キャッシュで何を試しているかわからなくなる可能性もあるから、--no-cacheオプションを入れているよ)

docker build ./ -t test_container --no-cache --progress plain

検証

docker build ./ -t test_container --no-cache --progress plain
#0 building with "desktop-linux" instance using docker driver

#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 547B done
#1 DONE 0.0s

#2 [internal] load .dockerignore
#2 transferring context: 107B done
#2 DONE 0.0s

#3 [internal] load metadata for docker.io/library/python:3.11.9
#3 DONE 0.9s

#4 [1/7] FROM docker.io/library/python:3.11.9@sha256:e453eb723bc8ecac7a797498f9a5915d13e567620d48dcd3568750bac3b59f31
#4 DONE 0.0s

#5 [2/7] WORKDIR /src
#5 CACHED

#6 [internal] load build context
#6 transferring context: 1.49kB done
#6 DONE 0.0s

#7 [3/7] RUN curl -sSL https://install.python-poetry.org | python3
#7 0.477 Retrieving Poetry metadata
#7 0.734
#7 0.739 # Welcome to Poetry!
#7 0.739
#7 0.739 This will download and install the latest version of Poetry,
#7 0.739 a dependency and package manager for Python.
#7 0.739
#7 0.739 It will add the `poetry` command to Poetry's bin directory, located at:
#7 0.739
#7 0.739 /root/.local/bin
#7 0.739
#7 0.739 You can uninstall at any time by executing this script with the --uninstall option,
#7 0.739 and these changes will be reverted.
#7 0.739
#7 0.740 Installing Poetry (1.8.3)
#7 0.740 Installing Poetry (1.8.3): Creating environment
#7 3.053 Installing Poetry (1.8.3): Installing Poetry
#7 32.19 Installing Poetry (1.8.3): Creating script
#7 32.19 Installing Poetry (1.8.3): Done
#7 32.19
#7 32.19 Poetry (1.8.3) is installed now. Great!
#7 32.19
#7 32.19 To get started you need Poetry's bin directory (/root/.local/bin) in your `PATH`
#7 32.19 environment variable.
#7 32.19
#7 32.19 Add `export PATH="/root/.local/bin:$PATH"` to your shell configuration file.
#7 32.19
#7 32.19 Alternatively, you can call Poetry explicitly with `/root/.local/bin/poetry`.
#7 32.19
#7 32.19 You can test that everything is set up by executing:
#7 32.19
#7 32.19 `poetry --version`
#7 32.19
#7 DONE 32.3s

#8 [4/7] COPY pyproject.toml* poetry.lock* ./
#8 DONE 0.0s

#9 [5/7] RUN poetry config virtualenvs.in-project true
#9 0.266 /bin/sh: 1: poetry: not found
#9 ERROR: process "/bin/sh -c poetry config virtualenvs.in-project true" did not complete successfully: exit code: 127
------
 > [5/7] RUN poetry config virtualenvs.in-project true:
0.266 /bin/sh: 1: poetry: not found
------
Dockerfile:12
--------------------
  10 |     COPY pyproject.toml* poetry.lock* ./
  11 |
  12 | >>> RUN poetry config virtualenvs.in-project true
  13 |     RUN poetry install --no-dev
  14 |
--------------------
ERROR: failed to solve: process "/bin/sh -c poetry config virtualenvs.in-project true" did not complete successfully: exit code: 127

これを見ると丁寧に、

To get started you need Poetry's bin directory (/root/.local/bin) in your PATH environment variable.
Add export PATH="/root/.local/bin:$PATH" to your shell configuration file.
Alternatively, you can call Poetry explicitly with /root/.local/bin/poetry.
You can test that everything is set up by executing: poetry --version
(DeeepL翻訳)
PATH環境変数にPoetryのbinディレクトリ(/root/.local/bin)が必要です。
シェルの設定ファイルにexport PATH=「/root/.local/bin:$PATH 」を追加してください。
あるいは、/root/.local/bin/poetryでPoetryを明示的に呼び出すこともできます。
すべての設定が完了したことを確認するには、以下を実行してください: poetry --version

て書いてあるんだよね。それができてなさそうなので、「Pathが通ってない」が原因ということかな?

対応

Dockerfile修正

そんなに難しい内容ではないので、Dockerfileを修正します。
poetryをインストール後、poetryのコメントにあるように/root/.local/binをPATHに追加してあげまあす。

Dockerfile
FROM python:3.11.9
ENV PYTHONUNBUFFERED=1

WORKDIR /app

# poetryのインストール
RUN curl -sSL https://install.python-poetry.org | python3
ENV PATH /root/.local/bin  # ここ追加
COPY pyproject.toml* poetry.lock* ./

RUN poetry config virtualenvs.in-project true
RUN poetry install --no-dev

COPY src/ /app

# entrypoint
ENTRYPOINT ["poetry", "run", "uvicorn", "app.main:app", "--host", "0.0.0.0", "--reload"]

結果

よさそう

docker images
REPOSITORY         TAG       IMAGE ID       CREATED         SIZE
test_container     latest    42020db5134c   6 seconds ago   1.21GB

Discussion