For a personnal project, I want to creat a container with Docker for a Python script (a bot for Discord) to isolate it from the system. I need to use PM2 to run the script, but I can't use the Python from keymetrics/pm2:latest-alpine due to the version (I need the 3.9 and not the 3.8).
So I decided to use a multi stage container to get files from a python container first and then, to execute it inside the other image.
Before calling my bot, I am working step by step. So I'm trying here to get only the version of Python in a first time (and then I'll try to call an hello world script with Python). My trouble is in this first step.
My Dockerfile is :
# =============== Python slim ========================
FROM python:3.9-slim as base
# Setup env
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONFAULTHANDLER 1
FROM base AS python-deps
# Install pipenv and compilation dependencies
RUN pip install pipenv
RUN apt-get update && apt-get install -y --no-install-recommends gcc
COPY requirements.txt .
# Install python dependencies in /opt/venv
# . Create env, activate
RUN python3 -m venv --copies /opt/venv && cd /opt/venv/bin/ && chmod a+x activate && ./activate && chmod a-x activate && cd -
# . Install packages with pip
RUN python3 -m pip install --upgrade pip && pip3 install --no-cache-dir --no-compile pipenv && PIPENV_VENV_IN_PROJECT=1 pip install --user -r requirements.txt
# >> Here, I can call :
# CMD ["/opt/venv/bin/python3.9", "--version"]
# =============== PM2 ================================
# second stage
FROM keymetrics/pm2:latest-alpine
WORKDIR /code
# Copy datas from directory
COPY ./src .
COPY ecosystem.config.js .
# Copy datas from previous
# Copy virtual env from python-deps stage
COPY --from=python-deps /opt/venv /opt/venv
# Install app dependencies : useless... (python3.8 de toute facon, et je dois etre en 3.9)
# RUN apk add --no-cache git python3
# Variables d'environnement Python :
ENV PYROOT=/opt/venv
ENV PYTHONUSERBASE=$PYROOT
ENV PATH="${PYROOT}/bin:${PATH}"
ENV PYTHONPATH="${PYROOT}/lib/python3.9/site-packages/"
# CMD ["ls", "-la", "/opt/venv/bin/python3"] # Ok here : file exists
# CMD ["which", "python3"] # Ok here : output: /opt/venv/bin/python3
CMD ["/opt/venv/bin/python3", "--version"] # not ok (cf below)
# ..... Then I will call after other stuff once Python works ....
# ENV NPM_CONFIG_LOGLEVEL warn
# RUN npm install pm2 -g
# RUN npm install --production
# RUN pm2 update && pm2 install pm2-server-monit # && pm2 install pm2-auto-pull
# CMD ["pm2-runtime", "ecosystem.config.js" ]
My requirements.txt is :
Flask==1.1.1
And my error is
/usr/local/bin/docker-entrypoint.sh: exec: line 8: /opt/venv/bin/python3: not found
I really don't understand why...
I tried to fo inside my image with
$ docker run -d --name hello myimage watch "date >> /var/log/date.log"
$ docker exec -it hello sh
And inside, I saw that Python exists with ls
, which
see it too, but if I go in the directory and I call it with ./python3
, I get the message sh: python: not found
I am a noob with Docker, even if I did some stuff with it before, but I didn't get courses about it because I use it only for few personnal stuff (and it's my 1st big trouble with it).
Thanks !