I can produce working image for my python app with following simple Dockerfile
:
FROM python:3.7
WORKDIR /myapp
COPY Pipfile* ./
RUN pip install pipenv
RUN pipenv install --system --deploy
COPY src .
CMD ["python3", "app.py"]
However, it will produce ~1 GB image, which can contain temporary files, and is heavy to deploy. And I only need full python image for building purposes. My app can successfully run on alpine variant, so I can make two-pass Dockerfile
:
FROM python:3.7 as builder
COPY Pipfile* ./
RUN pipenv lock --requirements > requirements.txt
RUN python3 -m venv /venv
RUN /venv/bin/pip install --upgrade pip
RUN /venv/bin/pip install -r requirements.txt
FROM python:3.7-alpine
COPY --from=builder /venv /venv
WORKDIR /myapp
COPY src .
CMD ["/venv/bin/python3", "app.py"]
So far so good, it also works, being 6 times smaller. But this scheme was considered as some "stub", having some drawbacks:
COPY --from=builder
steppipenv
but needs also pip
for installing (+1 extra step, pipenv lock
+pip install
is always slower than just pipenv install
)/venv
, which is to be avoided inside a containerHow to combine these two approaches, to get lightweitht alpine-based image with pipenv
, lacking mentioned drawbacks?
Or can you offer your production Dockerfile
ideas?
I am using micropipenv for the job, which describes itself as
A lightweight wrapper for pip to support requirements.txt, Pipenv and Poetry lock files or converting them to pip-tools compatible output. Designed for containerized Python applications but not limited to them.
An image created from it would look like the following.
Since the alpine base image lacks a toml parser we have to use the version of micropipenv that includes the toml extras (micropipenv[toml]
instead of micropipenv
).
FROM python:3.9-alpine
WORKDIR /myapp
COPY Pipfile Pipfile.lock ./
RUN \
# Install dependencies
&& pip install --no-cache-dir micropipenv[toml] \
&& micropipenv install --deploy \
&& pip uninstall -y micropipenv[toml]
COPY src .
CMD ["python3", "app.py"]
How about,
FROM python:3.7-alpine
WORKDIR /myapp
COPY Pipfile* ./
RUN pip install --no-cache-dir pipenv && \
pipenv install --system --deploy --clear
COPY src .
CMD ["python3", "app.py"]
--no-cache-dir
option for pip
and --clear
option for pipenv
.You can also add && pip uninstall pipenv -y
after pipenv install --system --deploy --clear
in the same RUN
command to eliminate space taken by pipenv
if that extra image size bothers you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With