在 alpine 的容器內使用 poetry

poetry 是個開發過程很方便的好工具,但是當某些特殊狀況我需要把完全一致的環境安裝到 Docker 內的時候卻可以因為它過多的 dependency 造成一些小麻煩。

通常來說直接使用 Debian 為基礎的那些基底 image 就可以繞過問題,但這樣容易直接把成品的 image 衝到超過 1GB,在很多時候感覺還是挺浪費的。

以下丟幾個常用的操作方便以後回來複製貼上。

直接裝

在 Apline 內要裝 poetry 的主要問題來自 cryptography,每次遇到每次被戳...

解法是:

RUN apk update && \
apk add gcc musl-dev libffi-dev

這邊的原因是 cryptography 會應用到 cffi,而它會吃到 limits.hffi.h,對應到 musl-devlibffi-dev 有提供這兩個檔案。

轉換成其他封裝格式

換個思路就是先開一個 builder stage 把 package 打包成其他常見格式,再帶到 alpine 的環境裝起來,這個方法

FROM python:3.8 AS builder
RUN pip install poetry
WORKDIR /build
ADD pyproject.toml poetry.lock .
ADD PKG PKG/
RUN poetry build
RUN find dist -name '*.tar.gz' -exec rm {} \;
RUN poetry export -f requirements.txt > dist/requirements.txt
FROM python:3.8-alpine
WORKDIR /build
COPY --from=builder /build/dist/ .
RUN pip install --no-cache-dir --requirement requirements.txt && \
pip install PKG-*.whl && \
rm -rf /build

兩個小地方注意:

  1. 在 builder stage 中還是會有安裝 poetry 需要面對那堆 depenency 的問題,所以先用 debian 帶過
  2. 在 builder stage 中的 ADD 跟 deploy stage 的 RUN 裡面有置換掉一組 PKG 要記得改成實際的套件名稱