2

Solved

According to this: https://stackoverflow.com/a/57886655/15537469

and to this: https://stackoverflow.com/a/74918400/15537469

I make a Multi-stage Docker build with Poetry and venv

FROM python:3.10-buster as py-build

RUN apt-get update && apt-get install -y \
    build-essential \
    curl \
    software-properties-common \
    && rm -rf /var/lib/apt/lists/*

RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=/opt/poetry python3 -

COPY . /app
WORKDIR /app
ENV PATH=/opt/poetry/bin:$PATH
RUN poetry config virtualenvs.in-project true && poetry install

FROM python:3.10-slim-buster

EXPOSE 8501
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
COPY --from=py-build /app /app
WORKDIR /app
CMD ./.venv/bin/python
ENTRYPOINT ["streamlit", "run", "mtcc/app.py", "--server.port=8501", "--server.address=0.0.0.0"]

My build is going well but when I run my docker container I get this error: docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "streamlit": executable file not found in $PATH: unknown.

I don't know if this is really useful but here is my file structure

mtcc
├── mtcc
│   └── app.py
└── Dockerfile                    
GuiEpi
  • 161
  • 8

2 Answers2

2

With poetry config virtualenvs.in-project true poetry will create a virtual environment in the .venv directory and install all it's dependencies in it.

The typical approach is to activate a virtual environment before using it. Typically this is done with the .venv/bin/activate (or with poetry run / poetry shell). E.g. you could do something like:

CMD source /app/.venv/bin/activate && exec streamlit run ...

Alternatively you can also activate a virtual environment by manipulating the path environment variable. If you prepend the path to the bin directory of the virtual env, the Docker environment will find all binaries:

ENV VIRTUAL_ENV=/app/.venv
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

CMD ["streamlit", "run", ...]

You can find these methods, and extended explanations at https://pythonspeed.com/articles/activate-virtualenv-dockerfile/.

Jakube
  • 3,353
  • 3
  • 23
  • 40
  • In the streamlit doc: https://docs.streamlit.io/knowledge-base/tutorials/deploy/docker, we have to use an ENTRYPOINT, is that a mistake according to you? – GuiEpi May 19 '23 at 13:30
  • 1
    @GuiEpi It's possible to use `ENTRYPOINT` or `CMD`. In practice it shouldn't matter too much. If you use an entrypoint with `streamlit run` instead, you can easily pass new arguments to streamlit, if you run `docker run some_image param1 param2` (which runs `streamlit run param1 param2`). E.g. see the examples here: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#entrypoint If you use CMD, you can't do that. However for a server application like streamlit, it doesn't make a big difference. – Jakube May 20 '23 at 11:35
1

This is the solution what I found:

FROM python:3.10-buster as py-build

RUN apt-get update && apt-get install -y \
    build-essential \
    curl \
    software-properties-common \
    && rm -rf /var/lib/apt/lists/*


RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=/opt/poetry python3 -

COPY . /app
WORKDIR /app
ENV PATH=/opt/poetry/bin:$PATH
RUN poetry config virtualenvs.in-project true && poetry install

FROM python:3.10-slim-buster

EXPOSE 8501
HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
COPY --from=py-build /app /app
WORKDIR /app
ENTRYPOINT [".venv/bin/python", "-m", "streamlit", "run", "mtcc/app.py", "--server.port=8501", "--server.address=0.0.0.0"]

I think I misled myself with the example posts I put up. However when I reread the docker documentation

The main purpose of a CMD is to provide defaults for an executing container. These defaults can include an executable, or they can omit the executable, in which case you must specify an ENTRYPOINT instruction as well.

That's what I want to do: provide default values

and after

If CMD is used to provide default arguments for the ENTRYPOINT instruction, both the CMD and ENTRYPOINT instructions should be specified with the JSON array format.

CMD is used to provide default arguments for the ENTRYPOINT

And in my case it is not an argument, I think

GuiEpi
  • 161
  • 8