Skip to content
Stuff I'm Up To
Go back

Multistage Python Container

Updated:
Edit page

When building a python container, I ended up with a huge 450MB image just because I needed it to have psycopg2. Time to chop it down using a multistage build. This technique can be applied to any python module that needs building, too.

FROM python:3-alpine as base

LABEL SPDX-License-Identifier="AGPL-3.0-or-later"

ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1

FROM base as builder

RUN apk add --no-cache \
    gcc \
    musl-dev \
    postgresql-dev \
    python3-dev

RUN mkdir /install && \
    pip3 install --prefix=/install \
    psycopg2 \
    python-dotenv 
    
FROM base

RUN apk add --no-cache libpq

COPY --from=builder /install /usr/local

COPY ./myapp.py /myapp.py

CMD [ "python", "/myapp.py"]

Because pyscopg2 requires building before it can be used we need to install gcc and development tools to compile it. But once compiled, we don’t need to keep the tools we needed to build it.

By using pip3 install --prefix=/install we ensure that our python libraries get installed in a single location we can use to copy from. I then include all the libraries I need for my python project.

Using a multistage build we build and install psycopg2 in a builder container, then make a second container, copy from the builder stage container the built items, and then dispose of the builder container. This leaves us with a tidy 45MB image instead of the 450MB one that includes the build tools.

When running the container, I noticed I wasn’t getting any output from my print() functions that I’d expect to see in the docker logs for stdout. You need to run python unbuffered to get the output to flow - hence the environment variable PYTHONUNBUFFERED=1.

As we build the final container, we need to include libpq - is the C application programmer’s interface to PostgreSQL.

References

https://github.com/psycopg/psycopg2/issues/684#issuecomment-453803835

https://www.rockyourcode.com/install-psycopg2-binary-with-docker/

https://stackoverflow.com/questions/51362213/docker-compose-not-printing-stdout-in-python-app


Edit page
Share this post:

Previous Post
Holy Guacamole!
Next Post
journalctrl