# Dockerfiles de Picasoft

**Lisez cette documentation avant toute chose : elle fait office de référence générale et contient des informations supplémentaires par rapport aux README des dossiers :D**

Ce dépôt centralise les Dockerfiles et autre ressources utilisées pour construire **et** déployer les images Docker tournant en production sur l'infrastructure de Picasoft.

## Philosophie

Historiquement, Picasoft procède de la manière suivante :
* Construire les images Docker à partir de Dockerfiles sur une machine quelconque, puis les pousser manuellement sur un registre privé.
* Gérer un fichier Compose global par machine, qui contient la configuration et les secrets.

Cette approche pose plusieurs problèmes. Comment savoir ce qu'il y a dans une image, si on perd le Dockerfile ? Quel Dockerfile correspond à quelle version de l'image ? Si on perd l'accès à la machine, comment récupérer la configuration, remonter rapidement le service ? Comment versionner les changements de configuration ? Revenir à la version d'il y a deux semaines ?

L'objectif de ce dépôt est de rendre possible le déploiement de n'importe quel service Picasoft avec la procédure suivante :
* Cloner le dépôt
* Se rendre dans le répertoire du service
* Lancer un `docker-compose up -d` pour démarrer le service

Son objectif secondaire est de pouvoir revenir à l'état antérieur d'un service. En versionnant toute la configuration nécessaire, revenir à une ancienne version du service revient à :
* Cloner le dépôt
* Checkout un commit quelconque
* Lancer le service normalement

Son dernier objectif est de permettre de rendre publics nos fichiers Compose et la configuration, sans exposer les secrets (mots de passe, etc).

Mises à part les données à proprement parler du service, il n'y a donc aucune différence entre un service lancé sur une de nos machines et un service lancé à partir de ce dépôt sur une machine quelconque, ce qui s'inscrit dans la philosophie Docker.

## Contenu du dépôt

Le dépôt est organisé en dossiers. Chaque dossier correspond à un *service* Picasoft au sens large, c'est-à-dire à un ensemble de conteneurs liés entre eux *techniquement* (*e.g.* Mattermost et sa base de données) et/ou *sémantiquement* (*e.g.* sites web statiques, relai et boîte à mail).

Ainsi, chaque dossier de ce dépôt contiendra, selon les situations :

* Zéro, un ou plusieurs `Dockerfile` permettant de construire des images personnalisées pour Picasoft,
* Un fichier `docker-compose.yml` permettant de lancer le service,
* Si possible, un ou des fichiers de configuration permettant de personnaliser le service selon nos besoins,
* Un fichier d'exemple de secrets (mots de passe...) nécessaires au lancement du service,
* Un `README.md` résumant les paramètres modifiables sur le dépôt, les mécanismes pour en rajouter, etc,
* Pour les images maison, un `CHANGELOG.md` résumant les modifications faites au fil des version.

Chaque service a son propre fichier Compose, lui permettant d'être déployé indépendamment des autres.

Des exemples concrets peuvent être trouvés au niveau de [pica-mattermost](./pica-mattermost) ou [pica-etherpad](./pica-etherpad).

## Guides

### Lancer ou redémarrer un service sur une machine de Picasoft

Lire [la documentation de déploiement et de maintenance](./doc/launch_service.md).

### Mettre à jour un service ou sa configuration

Lire [la documentation de mise à jour des services](./doc/update_and_test.md).

### Mettre en place un nouveau service

Lire [la documentation de versionnage d'un nouveau service](./doc/new_service.md) et [les bonnes pratiques pour Docker](./doc/guide_bonnes_pratiques.md).

### Cloner le dépôt

Si vous clonez le dépôt sur une nouvelle machine virtuelle, il est important de faire quelques opérations.

À moins qu'on ouvre une nouvelle machine, ça ne devrait pas arriver - le dépôt existe déjà dans `/DATA/docker/dockerfiles` sur toutes les machines actuelles.

En effet, le dépôt sera partagé et les fichiers doivent être éditables par tous les membres de Picasoft.

Or, avec Git, tout `git pull` va associer les nouveaux fichiers écrits au compte qui effectue la commande, avec des permissions d'écriture uniquement pour ce membre (pour plus de détails, se référer à la [documentation Git](https://git-scm.com/docs/git-init#Documentation/git-init.txt---sharedfalsetrueumaskgroupallworldeverybody0xxx) et comprendre la notion de `umask`).

Une solution pour rendre le dépôt "partagé" (*i.e.* éditable par tous les membres du groupe `docker`), quelles que soient les permissions initiales, est la suivante.

1. Éditer `/DATA/docker/dockerfiles/.git/config`, et ajouter, sous `[core]` :
```
sharedrepository = group
```

Ainsi, le dépôt sera "partagé", c'est-à-dire que les fichiers créés seront en théorie partagé avec le groupe propriétaire du dépôt, qui devrait être `docker`. Voir [la documentation](https://git-scm.com/docs/git-init#Documentation/git-init.txt---sharedfalsetrueumaskgroupallworldeverybody0xxx).

2. Pour être certain que les fichiers créés manuellement sur la machine par les utilisateurs soient accessibles par le groupe `docker`, on entrera la commande suivante :

```bash
sudo setfacl -Rdm g:docker:rwx /DATA/docker/dockerfiles
```

Ainsi, les fichiers créés auront le groupe `docker` par défaut ainsi que les permissions d'écriture pour le groupe.

3. On terminera, pour être sûr, par :
```bash
sudo chgrp -R docker /DATA/docker/dockerfiles
sudo chmod -R g+w /DATA/docker/dockerfiles
sudo chmod g-w /DATA/docker/dockerfiles/.git/objects/pack/*
find /DATA/docker/dockerfiles -type d -exec sudo chmod g+s {} \;
```