\newpage

Personnalisation du point d'entrée du conteneur
===============================================

## Point d'entrée basique

Afin de faire bénéficier à nos utilisateurs d'une immersion parfaite, nous
allons faire en sorte que notre image permette d'être utilisée ainsi :

<div lang="en-US">
```
    42sh$ docker run -d -p 80:80 youp0m -bind 80
```
</div>


Plutôt que de laisser l'utilisateur se débrouiller avec le chemin interne dans
lequel il va trouver le bon binaire :

<div lang="en-US">
```
    42sh$ docker run -d -p 80:80 youp0m /srv/youp0m -bind 80
```
</div>

Essayez les deux commandes, si vous avez utilisé l'instruction `CMD` dans votre
`Dockerfile` jusqu'à présent, vous devez vous trouver dans le deuxième cas.

Pour améliorer la situation, définissez
l'[`ENTRYPOINT`](https://docs.docker.com/engine/reference/builder/#entrypoint)
de votre image sur le binaire `/srv/youp0m`.


## Point d'entrée avancé

Dans certains cas, il peut être nécessaire au lancement d'un conteneur, de
faire un minimum d'étapes d'initialisation avant que le conteneur ne soit
opérationnel (rappelez-vous les options que l'on passait à l'image `mysql` pour
créer un utilisateur et une base).

Notre but, dans cette partie, sera de créer un utilisateur administrateur
(pouvant passer le contrôle d'accès <http://localhost:8080/admin/>) :

<div lang="en-US">
```
    42sh$ docker run -i --rm -p 8080:8080 -e YOUP0M_PASSWORD=admin youp0m
```
</div>

### Bases du script

Notre script d'`ENTRYPOINT` sera appelé avec en argument, ceux passés par
l'utilisateur après le nom de l'image, ou, à défaut, le contenu de `CMD`.

C'est donc l'`ENTRYPOINT` qui est responsable de la bonne utilisation de
ceux-ci, de leur modification, ...

À la fin d'un script d'`ENTRYPOINT`, afin de garder comme premier processus du
conteneur le programme qui nous intéresse, on réalise un `execve(2)`, sans
`fork(2)` :

<div lang="en-US">
```shell
    exec /srv/youp0m $@
```
</div>

Dans cet exemple : `exec` est la commande interne à notre shell pour lui
indiquer de remplacer son fil d'exécution par cette commande (sans `exec`, il
va `fork(2)` avant). `$@` est ici pour transmettre tel quel la liste des
arguments passés au script (il s'agit de ceux donnés par l'utilisateur, sur la
ligne de commande du `run`, ou du contenu de `CMD` si l'utilisateur n'a rien
précisé).


### Format du fichier `htpasswd`

Le format attendu est celui d'un fichier `htpasswd` typique d'Apache. Vous
pourriez obtenir un fichier valide avec :

<div lang="en-US">
```shell
    (
    	echo -n "$YOUP0M_USERNAME"
	    echo -n ":"
	    openssl passwd -crypt "$YOUP0M_PASSWORD"
    ) > myhtpasswd
```
</div>

Il faut ensuite passer le fichier sur la ligne de commande grâce à l'option
`-htpasswd`.


### Exercice

Écrivez un script d'`ENTRYPOINT`, analysant les variables d'environnement, à la
recherche de `YOUP0M_USERNAME` et `YOUP0M_PASSWORD` pour initialiser le fichier
`.htpasswd` qui sera ajouté à la liste des arguments à passer au service.

Par exemple :

<div lang="en-US">
```
  42sh$ docker run -d -p 8081:8081 -e YOUP0M_USERNAME=admin -e YOUP0M_PASSWORD=admin youp0m -bind=8081

  42sh$ curl -u admin:badpasswd http://localhost:8081/admin/
  You are not allowed to perform this request.

  42sh$ curl -u admin:admin http://localhost:8081/admin/
  <!DOCTYPE html>
```
</div>
