My favorite way to write a Dockerfile for a Python app

There’s more than one way to skin a cat, but this pattern makes my heart flutter.

Containerize a Python app

The asgi.py in our app directory

from fastapi import FastAPI

app = FastAPI()

@app.get(“/”)
def hello():
return “World”

There’s more than one way to skin a cat, but this pattern makes my heart flutter.



Containerize a Python app

The asgi.py in our app directory

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def hello():
  return "World"
Enter fullscreen mode

Exit fullscreen mode



Dockerfile

FROM python:3.7-buster as base

ENV SHELL=/bin/bash \
    USER=python \
    UID=10001

RUN set -eux; adduser \
    --disabled-password \
    --gecos "" \
    --home "/var/lib/python3" \
    --shell "/sbin/nologin" \
    --no-create-home \
    --uid "${UID}" \
    "${USER}"

RUN mkdir -p "/var/lib/python3" && chown -R "${USER}" /var/lib/python3

FROM base as build-local

USER ${USER}
RUN python -m pip install \
      --user \
      'uvicorn[standard]' \
      'fastapi' \
      'wheel'

FROM base

COPY --from=build-local --chown=${USER} /var/lib/python3/.local /var/lib/python3/.local
ENV PATH=$PATH:/var/lib/python3/.local/bin

USER root 
ENTRYPOINT ["docker-entrypoint.sh"]
COPY docker-entrypoint.sh /usr/bin/docker-entrypoint.sh 

USER ${USER}
WORKDIR /usr/lib/python

COPY ./app ./app

CMD ["app.asgi:app"]
Enter fullscreen mode

Exit fullscreen mode



Entrypoint

#!/bin/bash -e

# If the CMD has not changed process it as a pure Python implementation
if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ]; then
  set -- uvicorn "$@" --host 0.0.0.0 --http h11 --loop asyncio
fi

echo 
echo "Running $@"
echo

exec "$@"
Enter fullscreen mode

Exit fullscreen mode



Multi Stage Build

This Dockerfile is separated in a few stages to organized by the function of its build step. The multi-stage build strips our application of unnecessary files.

The first stage is bootstraps our required instructions that the remaining layers share. The user lets us install requirements outside of the root user.

- `--disable-password` prevents prompt for password
- `--home /var/lib/python3` sets the home dir to a well-defined location
- `--no-create-home` instruction to handle that in the Dockerfile
Enter fullscreen mode

Exit fullscreen mode

RUN mkdir -p "/var/lib/python3" && chown -R "${USER}" /var/lib/python3
Enter fullscreen mode

Exit fullscreen mode

The second stage brings in external requirements.

The last stage is the application where everything is tied together. Here the requirements are copied and the application itself is added in the app directory owned by the python user.



References


Print Share Comment Cite Upload Translate
APA
Nickolena | Sciencx (2024-03-29T15:21:41+00:00) » My favorite way to write a Dockerfile for a Python app. Retrieved from https://www.scien.cx/2021/02/24/my-favorite-way-to-write-a-dockerfile-for-a-python-app/.
MLA
" » My favorite way to write a Dockerfile for a Python app." Nickolena | Sciencx - Wednesday February 24, 2021, https://www.scien.cx/2021/02/24/my-favorite-way-to-write-a-dockerfile-for-a-python-app/
HARVARD
Nickolena | Sciencx Wednesday February 24, 2021 » My favorite way to write a Dockerfile for a Python app., viewed 2024-03-29T15:21:41+00:00,<https://www.scien.cx/2021/02/24/my-favorite-way-to-write-a-dockerfile-for-a-python-app/>
VANCOUVER
Nickolena | Sciencx - » My favorite way to write a Dockerfile for a Python app. [Internet]. [Accessed 2024-03-29T15:21:41+00:00]. Available from: https://www.scien.cx/2021/02/24/my-favorite-way-to-write-a-dockerfile-for-a-python-app/
CHICAGO
" » My favorite way to write a Dockerfile for a Python app." Nickolena | Sciencx - Accessed 2024-03-29T15:21:41+00:00. https://www.scien.cx/2021/02/24/my-favorite-way-to-write-a-dockerfile-for-a-python-app/
IEEE
" » My favorite way to write a Dockerfile for a Python app." Nickolena | Sciencx [Online]. Available: https://www.scien.cx/2021/02/24/my-favorite-way-to-write-a-dockerfile-for-a-python-app/. [Accessed: 2024-03-29T15:21:41+00:00]
rf:citation
» My favorite way to write a Dockerfile for a Python app | Nickolena | Sciencx | https://www.scien.cx/2021/02/24/my-favorite-way-to-write-a-dockerfile-for-a-python-app/ | 2024-03-29T15:21:41+00:00
https://github.com/addpipe/simple-recorderjs-demo