La plus petite image Docker pour des sites web statiques

-

Jusqu’à récemment, je pensais que servir des sites Web statiques à partir de Docker était un gaspillage de bande passante et de stockage. L’intégration de nginx ou de divers autres moteurs d’exécution lourds dans une image Docker dans le seul but de servir des fichiers statiques ne semblait pas être la meilleure idée – Netlify ou les pages Github peuvent gérer cela bien mieux. Mais mon serveur amateur était triste et pleurait des larmes numériques.

J’ai lu récemment un article de HackerNews sur redbean, un serveur de fichiers statiques à single-binary et super minuscule, m’a fait réfléchir. C’est ainsi que commence mon voyage pour trouver l’image Docker la plus efficace en termes de temps et de stockage pour servir un site Web statique.

Après avoir évalué quelques serveurs de fichiers statiques aux caractéristiques similaires, j’ai opté pour thttpd, qui présente une empreinte similaire, mais qui semble un peu plus éprouvé.

L’exécution de thttpd se déroule comme suit :

thttpd -D -h 0.0.0.0 -p 3000 -d /static-website -u static-user -l - -M 60
  • Lancera le serveur en avant-plan (-D),
  • en écoutant sur l’hôte 0.0.0.0 (-h),
  • le port 3000 (-p),
  • en servant tous les fichiers dans /static-website (-d)
  • qui sont accessibles à static-user (-u).
  • Il imprimera les journaux d’accès sur STDOUT (-l -)
  • et fixera l’en-tête Cache-Control à 60 secondes (-M).

Il y a quelques autres fonctionnalités intéressantes, comme l’authentification de base, le throttling et les hôtes virtuels, que vous pouvez lire dans la documentation.

Les premiers tests

Ma première tentative utilise la petite image alpine, qui emballe déjà thttpd :

FROM alpine:3.15.4

# Install thttpd
RUN apk add thttpd

# Create a non-root user to own the files and run our server
RUN adduser -D static
USER static
WORKDIR /home/static

# Copy the static website
# Use the .dockerignore file to control what ends up inside the image!
COPY . .

# Run thttpd
CMD ["thttpd", "-D", "-h", "0.0.0.0", "-p", "3000", "-d", "/home/static", "-u", "static", "-l", "-", "-M", "60"]

Vous pouvez construire et exécuter l’image en appelant :

docker build -t static:latest .
docker run -it --rm -p 3000:3000 static:latest

…puis naviguer jusqu’à http://localhost:3000.

L’image se construit rapidement et, à 7,77 Mo, elle est assez petite :

> docker images | grep static
static              latest              cb1750e32562        About an hour ago    7.77MB

Seconds tests

Nous pouvons aller plus loin en utilisant Docker scratch, qui est en fait une image no-op, légère comme le vide. Le problème avec scratch est que vous ne pouvez pas vraiment faire grand-chose à l’intérieur : vous ne pouvez pas créer de nouveaux utilisateurs, il n’y a pas de gestionnaire de paquets ni d’exécutable d’ailleurs – à part ceux que vous avez copiés vous-même.

L’utilisation de l’image scratch nécessite généralement une approche en plusieurs étapes. Nous partons d’alpine, téléchargeons et compilons thttpd en tant que binaire statique, créons un utilisateur, puis copions ces actifs sur scratch et ajoutons nos fichiers statiques au mélange :

FROM alpine:3.15.4 AS builder

ARG THTTPD_VERSION=2.29

# Install all dependencies required for compiling thttpd
RUN apk add gcc musl-dev make

# Download thttpd sources
RUN wget http://www.acme.com/software/thttpd/thttpd-${THTTPD_VERSION}.tar.gz \
  && tar xzf thttpd-${THTTPD_VERSION}.tar.gz \
  && mv /thttpd-${THTTPD_VERSION} /thttpd

# Compile thttpd to a static binary which we can copy around
RUN cd /thttpd \
  && ./configure \
  && make CCOPT='-O2 -s -static' thttpd

# Create a non-root user to own the files and run our server
RUN adduser -D static

# Switch to the scratch image
FROM scratch

EXPOSE 3000

# Copy over the user
COPY --from=builder /etc/passwd /etc/passwd

# Copy the thttpd static binary
COPY --from=builder /thttpd/thttpd /

# Use our non-root user
USER static
WORKDIR /home/static

# Copy the static website
# Use the .dockerignore file to control what ends up inside the image!
COPY . .

# Run thttpd
CMD ["/thttpd", "-D", "-h", "0.0.0.0", "-p", "3000", "-d", "/home/static", "-u", "static", "-l", "-", "-M", "60"]

Jetons un autre coup d’œil à ces chiffres :

> docker images | grep static
static              latest              ae708220dc8c        About a minute ago   187kB

Les 187Ko qu’il nous reste correspondent à la taille du binaire statique thttpd et des fichiers statiques qui ont été copiés, qui dans mon cas était juste un fichier contenant le texte hello world. Notez que l’étape alpine de la construction en plusieurs étapes est en fait assez grande en taille (~130Mo), mais elle peut être réutilisée à travers les constructions et n’est pas poussée vers le registre.

À ce stade, vous pouvez convertir l’image que nous avons construite jusqu’à présent en une image de base pour tous vos sites Web statiques et la pousser vers un registre, de sorte que vous pouvez sauter l’étape alpine entièrement. Ou vous pouvez simplement utiliser via mon Docker Hub :

FROM alfreddagenais/small-docker-static-website:latest

COPY . .

Cela produit une image mono-couche de 186KB + la taille de votre site web statique et rien d’autre. Si vous avez besoin de configurer thttpd d’une manière différente, vous pouvez simplement remplacer la ligne CMD :

FROM alfreddagenais/small-docker-static-website:latest

COPY . .

CMD ["/thttpd", "-D", "-h", "0.0.0.0", "-p", "3000", "-d", "/home/static", "-u", "static", "-l", "-", "-M", "60"]

En conclusion

Docker peut être utilisé efficacement pour emballer et servir des sites web statiques.

Le code est disponible à l’adresse https://github.com/alfreddagenais/kilukru-dev-small-docker-static-website.

Alfred
Alfredhttps://www.alfreddagenais.com
Salut ! Moi, c'est Alfred, développeur dans l’âme et explorateur de l'infini Web. Je suis constamment à la recherche de nouvelles idées et je pense que le développement web et l'informatique ont le pouvoir de transformer le monde. Je suis un grand admirateur de l'expérimentation, parce que c'est souvent de là que naissent les idées les plus créatives. Je suis convaincu que l'humour est un ingrédient clé de la vie, alors j'essaie toujours de glisser une blague ou deux dans mon code (pas toujours facile à comprendre, mais c'est le risque à prendre). En dehors de la programmation, j'aime passer du temps avec ma famille et mes amis, découvrir de nouveaux endroits et cuisiner des plats délicieux (du moins, j'essaie). Si vous voulez discuter de développement web, d'innovation, ou tout simplement échanger des blagues, n'hésitez pas à me contacter. Je suis toujours partant pour une bonne conversation !

Share this article

Recent posts

Popular categories

LAISSER UN COMMENTAIRE

S'il vous plaît entrez votre commentaire!
S'il vous plaît entrez votre nom ici

Recent comments