0

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 !

1sixunhuit
  • 62
  • 3
  • A Python virtual environment doesn't actually usually contain the Python interpreter _per se_, but rather a link to the `/usr/bin/python3` or similar. If your final image doesn't contain a system Python installation (and probably the exact same Python as in the builder image) then this won't work. – David Maze Jul 21 '22 at 14:05
  • 1
    I'm a little surprised you think you need PM2 to run this, since PM2 duplicates a lot of Docker's core functionality (like restarting the process on failure); [what is the point of using pm2 and docker together?](https://stackoverflow.com/questions/51191378/what-is-the-point-of-using-pm2-and-docker-together) Can you discard the second stage entirely? – David Maze Jul 21 '22 at 14:06
  • Thanks David ! For the 1st point, with `python3 -m venv --copies /opt/venv`, I get a Python inside the environment, not a symlink ;) For the 2nd, why PM2 ? Because I search some ways to do the stuff, I saw PM2 allowed to auto-pull git repository and auto-restart if the code crash when I did a quick search on Google to run a Discord.py bot. And I want to containirize (is it an english word ?) the code, to avoid the troubles on the system of my VPS. So thanks for your message ; I'll try to see a way only with the first stage. – 1sixunhuit Jul 21 '22 at 15:37

0 Answers0