Servir son contenu statique avec Docker
Posted on jeu. 17 mai 2018 in adminsys
Docker est la technologie incontournable dans le monde de l'IT d'aujourd'hui. Elle peut être utilisée pour beaucoup de chose, mais ici, nous allons voir un cas d'usage simple : servir un contenu web statique en l'utilisant. En étant le plus minimaliste et le plus simple dans notre approche.
On va aussi se rajouter une contrainte supplémentaire, sinon, c'est pas drôle : je veux que le docker container soit aussi le plus minimaliste en termes d'utilisation ressources (disque, RAM, CPU), une fois en route. Et aussi, il faut que ça soit un peu rigolo à faire et sans prise de tête à configurer.
La voie royale : Nginx
Le plus simple et qui vient immédiatement à l'esprit est Nginx. Enfin, dans mon cas, car je le connais plutôt bien et qu'il est vraiment performant.
Pourquoi
Heu... vous connaissez Nginx, bien sûr, non ?
Ok, alors, présentons Nginx :
Nginx (pronounced "engine-x") is an open source reverse proxy server for HTTP, HTTPS, SMTP, POP3, and IMAP protocols, as well as a load balancer, HTTP cache, and a web server (origin server). The nginx project started with a strong focus on high concurrency, high performance and low memory usage.
En gros, Nginx est ultra performant pour du servir du contenu statique, il a été conçu pour ça et est beaucoup plus performant qu'Apache à tout point de vue pour cet usage particulier.
Code
Ok, comment fait-on, alors ? Simple : mettez juste le Dockerfile qui suit à la racine du contenu que vous voulez servir, buildez, et runnez, et fini.
FROM nginx:alpine
COPY . /usr/share/nginx/html
En détail, placez un fichier Dockerfile
avec le contenu précédent (oui, juste ces 2 lignes) à la racine de votre dépôt git contenant vos fichiers statiques, puis faites ceci :
docker build -t static-content-server .
docker run -d -p "80:80" --name static-server static-content-server
Voilà. Je peux pas faire plus simple, je vous promets.
La voie de l'amusement
Le serveur web proprement dit
- "Dis papa, comment on fait les serveurs web ?"
- "Regarde ma fille, c'est facile. Tu peux même le faire toi-même"
Bon, c'est faisable en 15 lignes en go, mais si on en veut plus, un serveur web, avec doc incluse et quelques options sympa, ça se fait en ~250 lignes de go sur https://github.com/halverneus/static-file-server/blob/master/serve.go
Il faut git-cloner ce code, le builder et ensuite, on peut l'utiliser en l'incluant facile dans nos propre dépôt git.
D'abord, on build :
git clone https://github.com/halverneus/static-file-server.git
cd static-file-server
docker build -t static-file-server .
On met ça à la racine de notre dépôt git contenant les ressources statiques à servir:
FROM static-file-server
COPY . /web
Et ensuite, il faut builder et runner ce nouveau docker :
docker build -t static-content-server .
docker run -d -p "80:8080" --name static-server static-content-server
Avec Ansible
Et si on rajoutait du fun avec Ansible ? Commençons par un état des lieux :
user@computer:~/code$ tree startpage/
startpage/
├── Dockerfile
├── index.html
└── robots.txt
0 directories, 3 files
user@computer:~/code$ git -C startpage/ remote -v
origin ssh://git@git.example.net/user/startpage.git (fetch)
origin ssh://git@git.example.net/user/startpage.git (push)
user@computer:/home/code$ cat startpage/Dockerfile
FROM registry.example.net/static-file-server
COPY . /web
(Parce que je suis trop fainéant pour vous mettre des captures d'écran de dépôts git)
Voilà un petit playbook Ansible qui buildera, mettra dans une registry privée et fera tourner le serveur web pour vous servir le contenu de notre startpage contenu dans le dépôt git git.example.net/user/startpage.git.
- hosts: mon-super.serveur-perso.example.net
tasks:
- name: Get static-file-server code
git:
repo: https://github.com/halverneus/static-file-server.git
dest: "{{ app_code_dir }}/static-file-server"
register: git_pull_server
- name: Build static-file-server
docker_image:
path: "{{ app_code_dir }}/static-file-server"
name: medusa
tag: latest
push: yes
force: yes
repository: registry.example.net/static-file-server
when: git_pull_server.after != git_pull_server.before
- name: Get StartPage code
git:
repo: ssh://git@git.example.net/user/startpage.git
dest: "{{ app_code_dir }}/startpage"
key_file: "{{ app_data_dir }}/.ssh/id_rsa"
register: git_pull
- name: Build Startpage
docker_image:
path: "{{ app_code_dir }}/startpage"
name: startpage
tag: latest
push: yes
force: yes
repository: registry.example.net/startpage
when: git_pull.after != git_pull.before
- name: Deploy StartPage
docker_container:
pull: yes
name: StartPage
image: registry.example.net/startpage:latest
ports:
- "80:8080"
restart_policy: unless-stopped
PS : le playbook ansible est moche, il faut le découper en rôles, avec des handler, et tout et tout, mais ça, je vous laisse le faire ;-)