Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Containerize your Python apps like it's 2024

Containerize your Python apps like it's 2024

There are a lot of resources on containerizing Python applications with Docker, but most are basic and outdated. Following them results in slow builds and potentially insecure applications. Let’s see how we can build better containers using recent Docker features!

This talk will show how to speed up your builds and make your images smaller and more secure. We’ll use features such as multi-stage builds or cache mounts to build containers with Python apps. We will also discuss how to improve the security of your container.

Tips from the talk are valid for applications of all sizes and kinds: from hobby projects to enterprises, from CLI tools to web applications and APIs. You will be able to apply them immediately after the talk.

Basic knowledge of Docker and its key concepts (images, layers, Dockerfile commands) is required. You’ll learn something new even if you have used Docker for some time.

Avatar for Jan Smitka

Jan Smitka

July 11, 2024
Tweet

More Decks by Jan Smitka

Other Decks in Programming

Transcript

  1. 10

  2. musl libc: slower memory allocator 12 Performance comparison musl glibc

    Tiny allocation & free 0.005 0.002 Big allocation & free 0.027 0.016 https://www.etalabs.net/compare_libcs.html
  3. Installing build dependencies FROM python:3.12-slim - bookworm RUN apt -

    get update & & apt - get install - y \ default - libmysqlclient - dev \ build - essential \ pkg - conf i g \ & & rm - rf /var/lib/apt/lists / * COPY requirements.txt ./ RUN pip install - r requirements.txt # . . . 21 0 upgraded, 58 newly installed, … Need to get 69.7 MB of archives. After this operation, 313 MB of additional disk space will be used.
  4. Multi-stage builds FROM python:3.12-slim - bookworm AS builder RUN python

    - m venv /opt/venv # TODO : Install dependencies FROM python:3.12-slim - bookworm AS production COPY - - from=builder /opt/venv /opt/venv # . . . 23
  5. Multi-stage in Python FROM python:3.12-slim - bookworm AS builder RUN

    apt - get update & & apt - get install - y \ default - libmysqlclient - dev build - essential pkg - conf i g \ # . . . RUN python - m venv /opt/venv & & . /opt/venv/bin/activate \ & & pip install - - no - cache - dir - r requirements.txt FROM python:3.12-slim - bookworm AS production RUN apt - get update & & apt - get install - y \ libmariadb3 \ # . . . COPY - - from=builder /opt/venv /opt/venv # . . . 29 0 upgraded, 3 newly installed, … Need to get 193 kB of archives. After this operation, 886 kB of…
  6. Activating the virtualenv COPY - - from=builder /opt/venv /opt/venv ENV

    VIRTUAL_ENV="/opt/venv" \ PATH="/opt/venv/bin:$PATH" 33
  7. 35

  8. 36

  9. docker buildx build - - push - t <image> \

    - - cache - to type=inline \ - - cache - from type=registry,ref=<prev - image> \ . 39 Use inline cache
  10. docker buildx build - - push - t <image> \

    - - cache - to type=registry,ref=<cache - image>,mode=max \ - - cache - from type=registry,ref=<prev - cache - image> \ . 41 Use registry cache
  11. - - cache - to type=gha - - cache -

    from type=gha 43 GitHub Actions Cache
  12. cache mount 48 RUN - - mount=type=cache,target=/tmp/pip - cache \

    pip install - - cache - dir=/tmp/pip - cache …
  13. Stays on the build machine 49 Work-around for GitHub Actions:

    https://github.com/reproducible-containers/buildkit-cache-dance
  14. secret mount RUN \ - - mount=type=secret,id=pip,target=/home/user/.netrc,\ uid=1000,gid=1000,mode=0400 \ pip

    install - r requirements.txt $ docker buildx build - - secret id=pip,src=.netrc . 50
  15. RUN groupadd - - gid 1000 app \ & &

    useradd - - create - home - - uid 1000 - - gid app app USER app WORKDIR /home/app/example - app 53 Change user in Docker image
  16. COPY - - chown=app:app . /home/app/example - app COPY -

    - chmod=700 ./run.sh /home/app/run.sh 54 Change owner/permissions
  17. Running upgrade RUN apt - get update \ & &

    apt - get upgrade - y \ & & rm - rf /var/lib/apt/lists / * 56
  18. Update as last step FROM python:3.12-slim - bookworm AS production

    # . . . USER root RUN apt - get update & & apt - get upgrade \ & & rm - rf /var/lib/apt/lists / * USER app CMD ["gunicorn", "wsgi:app"] 57
  19. Update as the first step FROM python:3.12-slim - bookworm AS

    production RUN apt - get update & & apt - get upgrade & & apt - get install - y \ libmariadb3 \ & & rm - rf /var/lib/apt/lists / * \ # . . . 58
  20. docker buildx build - - no - cache . .

    . 59 Build without cache
  21. docker run - - rm \ - - user root

    \ - - entrypoint /bin/bash \ <image> \ - c 'apt - get update - qq \ & & ( \ apt - get upgrade - - dry - run \ | grep -E "\\(.* (Debian-Security:|Ubuntu:[^/] * / [^-]* - security)" \ )' 60 Check your image for security updates
  22. Caching • MIN or MAX mode? • Cache provider: •

    Inline cache • Registry cache + compression • GitHub Actions (gha) 63