1+ ARG PYTHON_IMAGE=3.13-slim
2+
13# --------------- `base` stage ---------------
2- FROM python:3.13-slim AS base
4+ FROM python:${PYTHON_IMAGE} AS base
35
4- # Define variables
6+ # Define global values. Define them as ARG so they are not present in the final image, and so they can be modified
57ARG USER=twyn
68ARG GROUP=twyn
79ARG WORKDIR=/app
810ARG VENV_PATH=${WORKDIR}/.venv
911
10- # Set `WORKDIR`
1112WORKDIR ${WORKDIR}
1213
1314# Create a non-root user and group
1415RUN groupadd -g 1001 ${GROUP} && \
15- useradd -m -u 1001 -g ${GROUP} -s /bin/bash ${USER}
16-
17- # Copy all the needed files, setting their user and group ownerships to the ones we just created
18- COPY --chown=${USER}:${GROUP} src src
19- COPY --chown=${USER}:${GROUP} pyproject.toml pyproject.toml
20- COPY --chown=${USER}:${GROUP} README.md README.md
21- COPY --chown=${USER}:${GROUP} poetry.lock poetry.lock
16+ useradd -m -u 1001 -g ${GROUP} -s /bin/false ${USER}
2217
2318# --------------- `build` stage ---------------
2419FROM base AS build
2520
21+ # Define stage variables
22+ ARG POETRY_VERSION=2.1.2
23+ ARG POETRY_PLUGIN_EXPORT_VERSION=1.9.0
24+
25+ # These should never change, define as ENV
26+ ENV POETRY_HOME="/opt/poetry"
27+ ENV PATH="${POETRY_HOME}/bin:${PATH}"
28+
29+ # Create venv and upgrade pip
30+ RUN python -m venv ${VENV_PATH} && \
31+ ${VENV_PATH}/bin/pip install --no-cache-dir --upgrade pip
32+
2633# Install poetry and set up the virtualenv configs
27- RUN pip install --upgrade pip && \
28- pip install poetry && \
29- poetry config virtualenvs.in-project true && \
30- poetry config virtualenvs.path ${VENV_PATH}
34+ RUN apt-get update && apt-get install -y curl \
35+ && curl -sSL https://install.python-poetry.org | POETRY_VERSION=$POETRY_VERSION python3
36+
37+ RUN poetry self add poetry-plugin-export==${POETRY_PLUGIN_EXPORT_VERSION}
38+
39+ # Copy all the needed files, without write permissions
40+ COPY poetry.lock pyproject.toml ./
3141
32- # Install `twyn` in the virtual environment
33- RUN poetry install --only main
42+ # Export dependencies to requirements.txt (no dev deps)
43+ RUN poetry export --without-hashes --only main -f requirements.txt > requirements.txt
44+
45+ # Create and install dependencies in the virtual env
46+ RUN ${VENV_PATH}/bin/pip install --no-cache-dir -r requirements.txt
3447
3548# --------------- `final` stage ---------------
3649FROM base AS final
@@ -39,8 +52,17 @@ FROM base AS final
3952USER ${USER}:${GROUP}
4053
4154# Copy over the virtual environment with all its dependencies and the project installed
42- COPY --from=build --chown=${USER}:${GROUP} ${VENV_PATH} ${VENV_PATH}
55+ COPY --from=build ${WORKDIR}/requirements.txt requirements.txt
4356ENV PATH="${VENV_PATH}/bin:$PATH"
4457
45- # Set `ENTRYPOINT`
58+ # Copy venv with all its dependencies along with pyproject.toml
59+ COPY --from=build --chown=${USER}:${GROUP} ${VENV_PATH} ${VENV_PATH}
60+ COPY --from=build --chown=${USER}:${GROUP} ${WORKDIR}/pyproject.toml .
61+
62+ # Copy source code
63+ COPY src src
64+
65+ # Install the CLI tool
66+ RUN $VENV_PATH/bin/pip install --no-cache-dir .
67+
4668ENTRYPOINT [ "twyn" ]
0 commit comments