Home > front end >  How to copy python from one stage to another during a multi-stage docker build
How to copy python from one stage to another during a multi-stage docker build

Time:02-11

I'm using nvidia/cudagl:11.4.2-base-ubuntu20.04, which does not include python. This is ok for me, since I need a very specific python version (3.9.9) anyhow. One way should be to compile python myself (e.g. according to https://askubuntu.com/a/890959). However, I thought maybe I could use a multi-stage build and just copy the required python executables from python:3.9.9-slim, so that I don't have to deal with the compilation and its remnants.

Is that a feasible idea? And what exactly would need to be copied over?

CodePudding user response:

As David Maze pointed out, it is apparently not a good idea to copy over a Python install. Unfortunately, the popular deadsnakes repository that he suggested, does not supply patch versions of Python, i.e. only the latest patch of Python 3.9 (at the time of writing 3.9.10) and not previous versions like 3.9.9.

I found that pyenv is a pretty convenient way to install a specific Python version (originally posted here):

FROM ubuntu:16.04


ENV PYTHON_VERSION 2.7.10

#Set of all dependencies needed for pyenv to work on Ubuntu systems
RUN apt-get update \ 
        && apt-get install -y --no-install-recommends make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget ca-certificates curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev mecab-ipadic-utf8 git

# Set-up necessary Env vars for PyEnv
ENV PYENV_ROOT /root/.pyenv
ENV PATH $PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH


# Install pyenv
RUN set -ex \
    && curl https://pyenv.run | bash \
    && pyenv update \
    && pyenv install $PYTHON_VERSION \
    && pyenv global $PYTHON_VERSION \
    && pyenv rehash

# Optional : Checks Pyenv version on container start-up
ENTRYPOINT [ "pyenv","version" ]

CodePudding user response:

It's not really feasible to copy installed binaries from one image to another. If you know the application is only a static binary, or you know it has very controlled library dependencies, it could work, but Python installs things in many different directories and includes its own library tree. You'll be much better off using the distribution package manager to install the specific version of Python you need.

Since your base image is based on Ubuntu, there's an add-on Ubuntu repository that contains many different Python versions; also see Python 3.7 on Ubuntu 20.04. Translating that answer to Dockerfile format, you'd get something like:

FROM nvidia/cudagl:11.4.2-base-ubuntu20.04
...
# USER root (if you're not already root)
RUN apt-add-repository ppa:deadsnakes/ppa \
 && apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
    apt-get install --no-install-recommends --assume-yes \
      python3.9

As of this writing that includes Python 3.9.10 rather than 3.9.9, but this shouldn't be a significant difference for you.

  • Related