Comment utiliser python-ldap en Production ?

Florian Courouge
3 min readJun 21, 2021

Lors de mes développement je devais m’interconnecter a un ldap pour inserer/verifier des groupes depuis mon API (Fastapi ❤). Pour cela rien de mieux que d’utiliser python-ldap.

Le hic c’est quand on souhaite conteneuriser l’app!

On commence par crée le Dockerfile (dans le style de cet article).

FROM python:3.9.2 AS ldap-build

RUN apt-get update -y && \
apt-get install -y libsasl2-dev python-dev libldap2-dev libssl-dev && \
python -m pip wheel --wheel-dir=/tmp python-ldap==3.3.1

FROM python:3.9.2
COPY --from=ldap-build /tmp/*.whl /tmp
RUN python -m pip install /tmp/*.whl

On build et là surprise la taille de l’image est juste énorme 1Go. Le scan de l’image dans jfrog-xray est pas fameux. Best pratices sur Docker:

  1. multistage
  2. limiter le nombre de layer

C’est déjà le cas dans notre Dockerfile… Le problème c’est que l’image de base python:3.9.2 est trop volumineuse. Pour résoudre ça on a plusieurs choix :

  1. Ubuntu LTS
  2. Debian Buster
  3. lightweight distros (Alpine)
  4. Distroless image (Google)

Je vais pas me lancer dans un comparatif (deja fait ici !) mais je vais résumer un peu mes attentes:

  • Ne pas passer trop de temps a builder l’image
  • Image pas trop volumineuse
  • Adapté pour l’environnement de production
  • Réduire au maximun la surface d’attaque de l’image
  • Profiter de fonctionnalité avancé de python dans les dernières versions

Quand le drame arrive !

Dockerfile distroless (exemple de base)

FROM debian:buster-slim AS build
RUN apt-get update && \
apt-get install --no-install-suggests --no-install-recommends --yes libsasl2-dev python-ldap libldap2-dev libssl-dev python3-venv &&
python3 -m venv /venv && \
/venv/bin/pip install --upgrade pip && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
FROM build AS build-venv
COPY requirements.txt /requirements.txt
RUN /venv/bin/pip install --disable-pip-version-check -r /requirements.txt
FROM gcr.io/distroless/python3-debian10
COPY --from=build-venv /venv /venv
COPY . /app
WORKDIR /app
ENTRYPOINT ["/venv/bin/python3", "app.py"]

Le problème c’est qu’il y a des dependances systemes a injecter dans l’image distroless et la j’ai beau demander a google il sait pas… J’ai trouvé un sujet similaire ici sans réponse :-( .

Dans la FAQ de python-ldap

Q: During build there are warning messages displayed telling Lib/ldap.py and Lib/ldap/schema.py are not found:

warning: build_py: file Lib/ldap.py (for module ldap) not found
warning: build_py: file Lib/ldap/schema.py (for module ldap.schema) not found

A: ldap and ldap.schema are both module packages (directories containing various sub-modules). The messages above are falsely produced by DistUtils. Don’t worry about it.

Q: While importing module ldap, some shared lib files are not found. The error message looks similar to this:

ImportError: ld.so.1: /usr/local/bin/python: fatal: liblber.so.2: open failed: No such file or directory

A1: You need to make sure that the path to liblber.so.2 and libldap.so.2 is in your LD_LIBRARY_PATH environment variable.

A2: Alternatively, if you’re on Linux, you can add the path to liblber.so.2 and libldap.so.2 to /etc/ld.so.conf and invoke the command ldconfig afterwards.

Je ne suis pas un spécialiste de l’image de base de debian… comment trouver les fameux fichiers a copier ?

La réponse est sur le site officiel de debian :-)

https://debian.pkgs.org/10/debian-main-amd64/libldap2-dev_2.4.47+dfsg-3+deb10u6_amd64.deb.html

Il suffit de copier le path de la lib vers l’image distroless !

Solution Finale

FROM debian:buster-slim AS build
RUN apt-get update && \
apt-get install --no-install-suggests --no-install-recommends --yes libsasl2-dev python-ldap libldap2-dev libssl-dev python3-venv && \
python3 -m venv /venv && \
/venv/bin/pip install --upgrade pip && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

FROM build AS build-venv
COPY requirements.txt /requirements.txt
RUN /venv/bin/pip install --disable-pip-version-check -r /requirements.txt

FROM gcr.io/distroless/python3-debian10
COPY --from=build-venv /venv /venv
COPY --from=build-venv /usr/lib/x86_64-linux-gnu/ /usr/lib/x86_64-linux-gnu/
ENV LD_LIBRARY_PATH="/usr/lib"
COPY app /app
WORKDIR /app
EXPOSE 80
ENTRYPOINT ["/venv/bin/python3", "main.py"]

Disponible sur ce repo git !

La taille de l’image est de 161 Mb (ça reste beaucoup…)

Une dernière astuce pour diminuer la taille de l’image c’est de builder avec docker-slim. On arrive a une taille d’image de 56.9MB !

Merci d’avoir lu jusqu’a la fin :-)

--

--