#+SETUPFILE: /home/vaab/dev/el/org-html-themes/setup/theme-readtheorg.setup
#+PROPERTY: Effort_ALL 0 0:30 1:00 2:00 0.5d 1d 1.5d 2d 3d 4d 5d
#+PROPERTY: Max_effort_ALL 0 0:30 1:00 2:00 0.5d 1d 1.5d 2d 3d 4d 5d
#+PROPERTY: header-args:python :var filename=(buffer-file-name)
#+PROPERTY: header-args:sh :var filename=(buffer-file-name)
#+TODO: TODO WIP BLOCKED POSTPONED | DONE CANCELED
#+LATEX_HEADER: \usepackage[margin=0.5in]{geometry}
#+LaTeX_CLASS: article
#+OPTIONS: H:8 ^:nil prop:("Effort" "Max_effort") tags:not-in-toc
#+COLUMNS: %50ITEM %Effort(Min Effort) %Max_effort(Max Effort)

#+begin_LaTeX
  \hypersetup{
    linkcolor=blue,
    pdfborder={0 0 0 0}
  }
#+end_LaTeX

#+TITLE: Architecture 0k.io

#+LATEX: \pagebreak

* Process de déploiement

Description du process de déploiement pour une nouvelle installation

** Base myc

*** Qu'est ce c'est ?

A partir d'une debian 9, on peut installer la machine pour être prête
à utiliser un déploiement myc.

Une fois executé, la machine aura toute les deps pour lancer une
commande compose qui fera peut-être appel à des registry de
mycéliandre. Un compose de base est aussi proposé.

*** Déploiement

**** Hôte linux base debian 9 et debian 10

***** Accès ssh standardisé

Via la commande =0km=, depuis votre poste, permet de standardiser
l'accès avec vos clés SSH, et positionner le nom de domaine si
nécessaire.

#+BEGIN_SRC sh
0km vps-setup HOST
#+END_SRC

Note: ceci fonctionnera que si vous avez un fichier de configuration
dans =/etc/0km/config.yml= (si vous allez l'utiliser en root) ou dans
=~/.config/0km/config.yml= autrement. Ce fichier doit au moins contenir
une clé ssh (ou plusieurs) ainsi:

#+begin_src yaml
ssh-access:
  public-keys:
    - ssh-rsa AAAAB3NzaC1yc2EAAAAD...qGy20KlAOGPf nom_clef
#+end_src


***** Déploiement de la solution

Depuis le VPS, en root:

#+BEGIN_SRC sh
export WITHOUT_DOCKER_CLEAN=1  ## only if you want to remove docker clean from cron
wget https://justodooit.myceliandre.fr/r/deploy -qO - | bash
#+END_SRC

Si vous souhaitez positionner le nom de domaine:

#+BEGIN_SRC sh
export WITHOUT_DOCKER_CLEAN=1  ## only if you want to remove docker clean from cron
export DOMAIN=myhost.com
wget https://justodooit.myceliandre.fr/r/deploy -qO - | bash
#+END_SRC

**** Hôte macosx

- install bash, docker
- Uncheck "Securely store docker logins in macOS keychain"

*** Ce que cela fait
**** Mettre la machine en état charm-ready

- installation du strict minimu pour lancer les =charms=

- téléchargement de la dernière version des =0k-charms= (collection
  de recettes d'installation et de gestion de docker)

**** Mettre la machine en état compose ready (notre docker qui va bien)

via le lancement du charm =docker-host= qui installe:

  - docker, docker-compose, compose avec des versions qui vont bien
  - paquets maisons (kal-scripts, 0k-manage, 0k-pgm, lxc-scripts, 0k-docker)
  - accès pour le repository deb de kalysto.org
  - clé SSH pour repos git.kal.fr
  - login sur le docker registry docker.0k.io

**** Commandes spécifique à myc

- login sur le registry myc
- téléchargement du compose de base dans =/opt/apps/myc-deploy=


** Modification du compose

*** Qu'est-ce que c'est ?

Il y a des update client à faire souvent sur le compose. Cette étape
doit être externalisée au plus possible, sont consigné ici ce qu'il
faut encore faire à la main.

*** Commande

**** Création de clé OVH pour letsencrypt/lexicon

Ceci n'est nécessaire qu'en cas d'utilisation de la méthode DNS
pour valider la possession du domaine auprès de letsencrypt.

#+BEGIN_SRC shell
APPLICATION_KEY=XXXXXXXXXXXXXXXXX
REDIR_WEBSITE=https://0k.io

req=$(cat <<EOF
{
    "accessRules": [
        {
            "method": "GET",
            "path": "/*"
        },
        {
            "method": "POST",
            "path": "/*"
        },
        {
            "method": "PUT",
            "path": "/*"
        },
        {
            "method": "DELETE",
            "path": "/*"
        }
    ],
    "redirection":"$REDIR_WEBSITE"
}
EOF
)
res=$(curl -X POST \
     -H "X-Ovh-Application: ${APPLICATION_KEY}" \
     -H "Content-type: application/json" \
     https://eu.api.ovh.com/1.0/auth/credential \
     -d "$req")
consumer_key=$(echo "$res" | jq -r .consumerKey)
validation_url=$(echo "$res" | jq -r .validationUrl)
echo "Visit: $validation_url"
echo "ConsumerKey: $consumer_key"
#+END_SRC

Il s'agit alors de remplir le compose.yml

#+BEGIN_SRC yaml
    ovh:
      ## see: https://api.ovh.com/g934.first_step_with_api
      entrypoint: ovh-eu
      application:
        key: XXXXXXXXXXXXXXXX
        secret: YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
      consumer_key: ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
#+END_SRC

Puis de valider que tout est ok:

#+BEGIN_SRC shell
check-compose-ovh-credentials compose.yml
#+END_SRC


** Lancement/Deploy de service odoo

*** Qu'est ce que c'est ?

A partir d'une base myc, cette commande permet d'envoyer la
construction et l'assemblage de tous les services décrit dans le
=compose.yml= fourni par défaut.

*** commandes

#+BEGIN_SRC sh
cd /opt/apps/myc-deploy
compose --debug up odoo frontend
#+END_SRC

De manière générale:

#+BEGIN_SRC sh
compose [--debug] up [SERVICES...]
#+END_SRC

*** Ce que ça fait

Les charms vont s'occuper de séparer la config des
donnée, de tout stocker dans =/srv/datastore=, il vont
s'occuper de la petite maintenance:

- le charm postgres (qui est une dépendance du service odoo) va créer
  un mot de passe et le filer à odoo
- le charm apache (qui implémente le service frontend)
  va créer les fichiers de conf apache pour déclarer un virtualhost
  et mettre les clés SSL s'il y a lieu.


* Gestion

Description des process de gestion d'une installation existante.

** Connection aux serveurs


*** installation commande =st=

Le mieux est d'utiliser la commande =st= que l'on peut installer ainsi
sur un poste linux ayant =apt=:

Se mettre en =root=:

#+begin_src sh
cat <<'EOF' > /usr/local/bin/st
#!/bin/bash

echo "Trying mosh to $1"
TERM=xterm-256color mosh "$1" -- bash -c "tmux attach || { tmux; }"
if [ "$?" == "5" ]; then
  echo "Fallback to ssh $1"
  ssh "$1" -tM "TERM=xterm-256color tmux attach || TERM=xterm-256color tmux"
fi
EOF
chmod +x /usr/local/bin/st
apt install mosh
#+end_src

*** utilisation de la commande =st=

=st= utilise =ssh= ou =mosh= et se met dans un =tmux= sur la destination.

#+begin_src sh
st root@monvps.fr
#+end_src

On note qu'il faut penser à mettre les clé SSH sur la destination.

** Mise à jour de l'ensemble

Pour mettre à jour un VPS:

#+BEGIN_SRC sh
myc-update
#+END_SRC

Cette commande va ré-appliquer l'installation du charm =docker-host=
qui installe ou met à jour chaque composant.

** Gestion des dockers
*** Relancement

si on veut relancer parce que le compose a changé :

on fait pareil qu'au lancement : lors du "up", docker-compose se
rend compte que la définition des services a changé et relance les
docker voulu.

*** Arrêt

#+BEGIN_SRC sh
compose --debug down
#+END_SRC

*** Voir les logs

#+BEGIN_SRC sh
cd /opt/apps/myc-deploy
compose --debug logs odoo
#+END_SRC

*** Obtenir les IPs des dockers

#+BEGIN_SRC sh
docker-ip
#+END_SRC

** Par services

*** odoo
**** Backups
***** Backuping odoo account (filestore and database)

There are still some quirks, so be sure:
- to change your current directory to =/opt/apps/myc-deploy=
- your odoo instance should be already up.
- to have =admin-password= defined in your =compose.yml=, in your
  =odoo= service's =options=.

#+BEGIN_SRC yaml
odoo:
  options:
    admin-password: XXXXXX
#+END_SRC


#+BEGIN_SRC sh
MYODOOSERVICENAME=odoo
DBNAME="$MYODOOSERVICENAME"
OUTPUTFILE=backup-odoo.zip
cd /opt/apps/myc-deploy &&
compose save "$MYODOOSERVICENAME" "$DBNAME" "$OUTPUT_FILE"
#+END_SRC

The backup file should be in the same directory.

***** Restoring odoo account (filestore and database)

There are still some quirks, so be sure:
- to change your current directory to =/opt/apps/myc-deploy=
  and put your backup file in the same directory
- your odoo instance should be already up.
- to have =admin-password= defined in your =compose.yml=, in your
  =odoo= service's =options=.

#+BEGIN_SRC yaml
odoo:
  options:
    admin-password: XXXXXX
#+END_SRC

*IMPORTANT* you might want to consider the usage of docker-cutoff if
you are restoring a production odoo onto a dev or staging odoo that you
don't want to allow to go mess around with sending mails or fetching mails.

#+BEGIN_SRC yaml
docker-cutoff 25 993 465
#+END_SRC

These are the normal loading instructions:

#+BEGIN_SRC sh
MYODOOSERVICENAME=odoo
DBNAME="$MYODOOSERVICENAME"
SOURCEFILE=backup-odoo.zip
cd /opt/apps/myc-deploy &&
compose load "$MYODOOSERVICENAME" "$SOURCEFIE" "$DBNAME"
#+END_SRC

***** charger un dump SQL dans odoo

Supporte *.dump ou sql (non compressé), *.gz ou *.bz2:

#+BEGIN_SRC sh
compose load-db odoo MONFICHIER.dump.bz2
#+END_SRC

***** sauvegarder dump db de odoo

Pour l'instant on passe par pgm

#+BEGIN_SRC sh
compose save-db odoo MONFICHIER.dump.bz2
#+END_SRC

**** Update de modules

#+BEGIN_SRC sh
compose update odoo MABASE [MODULE [MODULE ...]]
#+END_SRC


**** lancement d'une commande odoo

Si l'ensemble n'est pas up:

#+BEGIN_SRC sh
compose --debug run odoo --help
#+END_SRC


**** Mod dev d'odoo

Il est souhaitable de lancer odoo en mode dev avec un terminal prêt à
accueillir un pdb par exemple, et pouvoir changer facilement la ligne de commande.

On peut tout a fait lancer odoo directement, par exempe:

#+BEGIN_SRC sh
compose run --rm --use-aliases odoo --dev=wdb --config=/opt/odoo/auto/odoo.conf
#+END_SRC

On récupère ainsi tous les volumes et autres options (sauf ce qui est
dans =command:=) défini dans =compose.yml=.

Un problème cependant: si on utilise apache comme frontend, celui-ci
ne pourra pas résoudre le nom =odoo= à cause de problèmes autour de
=docker-compose= et/ou =docker network=. En effet, si on fait un =up=
comme d'habitude, et qu'on souhaite simplement arrêter le service
classique pour ensuite le remplacer par la commande au dessus, cela ne
fonctionnera pas.  En effet, l'alias réseau =odoo= n'est plus adjoignable
(même avec les commandes =docker network {dis,}connect=), et même si
le container original de odoo est détruit ou éjecté du réseau, ou que l'on
essaye de connecter soi-même le nouveau container.

Un moyen (bancal) de passer outre cependant:
- =down= pour fermer le réseau
- =create= sur le service apache, puis =restart=.
- enfin, le =run= tel que décrit au dessus

Soit:

#+BEGIN_SRC sh
compose down &&
compose create apache &&
compose restart apache &&
compose run --rm --use-aliases odoo --dev=wdb --config=/opt/odoo/auto/odoo.conf
#+END_SRC

Le container odoo crée par la dernière ligne se retirera proprement des tables DNS
interne, et donc peut tout a fait être relancée autant de fois que l'on souhaitera.

*** letsencrypt

Le service letsencrypt fourni des certificat SSL à la demande et les
renouvelle automatiquement.

**** configuration dans compose
***** Authentification HTTP

Il n'y a besoin d'aucune option dans le service =letsencrypt=.

Le charm =apache= doit trouver un service utilisant le charm =letsencrypt=, cette
connection se fera automatiquement si un servce de type =letsencrypt= est lancé soit
parce que directement mentionné dans la racine ou dans une relation explicite.

La relation construite automatiquement (ou manuellement) d'un service
=apache= vers un service =letsencrypt= s'appelle =cert-provider=.

Une fois que ce service est relié à apache, on peut s'en servir comme clé dans
la configuration =ssl= des relations =*-->web-proxy-->apache=.

Par défaut, =apache= utilisera du ssl pour tout se virtual-host s'il trouve un
=cert-provider= à disposition.

Aussi la configuration suivante est suffisante pour avoir un site publié en SSL:
#+BEGIN_SRC yaml

www.mydomain.org:
  charm: odoo

apache:

letsencrypt:

#+END_SRC


Cela équivaut à :


#+BEGIN_SRC yaml

www.mydomain.org:
  charm: odoo
  relations:
    web-proxy:
      myapache:
        domain: www.mydomain.org
        ssl:
          myletsencrypt:
            challenge-type: http

myapache:
  charm: apache

myletsencrypt:
  charm: letsencrypt

#+END_SRC



***** Authentification DNS
****** créer un nouveau jeu de clé OVH pour l'authentification DNS

  When =letsencrypt= is setup and running::

  #+BEGIN_SRC sh
  compose --debug add letsencrypt DOMAIN [DOMAIN...]
  #+END_SRC

  Exemple de setup (dans =compose.yml=):

  #+BEGIN_SRC yaml
  letsencrypt:
    options:
      email: admin@0k.io
      ovh:
        entrypoint: ovh-eu
        application:
          key: ZZZ
          secret: XXX
        consumer_key: YYYYY
  #+END_SRC

  Le résultat est dans =/srv/datastore/data/letsencrypt/etc/letsencrypt/live/DOMAIN1=
  Il apparaît entre 30sec et 1 minute après la demande.

****** Vérifier que le jeu de clé ovh est bon

  Cette commande prend le compose yml et va vérifier que les accès sont valides:

  #+BEGIN_SRC shell
  check-compose-ovh-credentials compose.yml
  #+END_SRC

**** Utilisation manuelle

On peut utiliser le service =letsencrypt= manuellement

***** creation d'un certificat http

#+BEGIN_SRC shell
compose crt letsencrypt create DOMAIN [DOMAIN...]
#+END_SRC

Cette action crée un certificat (et force le renouvellement si existant).

On peut y injecter une configuration via =--add-compose-content= si nécessaire::

#+BEGIN_SRC shell
compose --add-compose-content='
letsencrypt:
  ovh:
    ## see: https://api.ovh.com/g934.first_step_with_api
    entrypoint: ovh-eu
    application:
      key: XXX
      secret: YYY
    consumer_key: ZZZ
  challenge-type: dns
  #renew-before-expiry: 30' crt letsencrypt create DOMAIN [DOMAIN...]
#+END_SRC

***** Renew de tous les certificats

Cela renew uniquement les certificats dont la date de validité est inférieure à 30j

#+BEGIN_SRC shell
compose crt letsencrypt renew
#+END_SRC


***** Liste des certificats gérés et infos connexes

#+BEGIN_SRC shell
compose run letsencrypt crt list
#+END_SRC

***** suppression d'un certificat

#+BEGIN_SRC shell
compose run letsencrypt certbot delete --cert-name DOMAIN
#+END_SRC

*** apache

**** Utiliser letsencrypt

Pour ajouter la fonctionalité de génération automatique de certificat
 via le service =letsencrypt=, il faut:
- déclarer un service =letsencrypt= si cela n'est pas déjà fait
- le lier au charm apache via une relation =cert-provider=:

#+BEGIN_SRC yaml
frontend:
  charm: apache
  relations:
    cert-provider: letsencrypt

letsencrypt:
  ...
#+END_SRC

Et l'on peut alors utiliser la valeur =letsencrypt= (le nom du service qui implémente
qui est en relation =cert-provider= avec apache) dans le champ =ssl=::

#+BEGIN_SRC yaml
  web-proxy:
    apache:
      ...
      ssl: letsencrypt
#+END_SRC

**** Changer les clés SSL

Voici un exemple de ce qu'on peut mettre dans les options de la relation apache
pour déclarer le certificat que l'on souhaite:

#+BEGIN_SRC yaml

  ssl:
    ca-cert:
      -----BEGIN CERTIFICATE-----
      MIIF6TCCA9GgAwIBAgIQBeTcO5Q4qzuFl8umoZhQ4zANBgkqhkiG9w0BAQwFADCB
      iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
      ...
      m9T8bJUox04FB6b9HbwZ4ui3uRGKLXASUoWNjDNKD/yZkuBjcNqllEdjB+dYxzFf
      BT02Vf6Dsuimrdfp5gJ0iHRc2jTbkNJtUQoj1iM=
      -----END CERTIFICATE-----
      -----BEGIN CERTIFICATE-----
      MIIFdzCCBF+gAwIBAgIQE+oocFv07O0MNmMJgGFDNjANBgkqhkiG9w0BAQwFADBv
      MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk
      ...
      Le9Gclc1Bb+7RrtubTeZtv8jkpHGbkD4jylW6l/VXxRTrPBPYer3IsynVgviuDQf
      Jtl7GQVoP7o81DgGotPmjw7jtHFtQELFhLRAlSv0ZaBIefYdgWOWnU914Ph85I6p
      0fKtirOMxyHNwu8=
      -----END CERTIFICATE-----
    cert: |
      -----BEGIN CERTIFICATE-----
      MIIF/TCCBOWgAwIBAgIRALUydpTpCApfYMuJchDJv5AwDQYJKoZIhvcNAQELBQAw
      XzELMAkGA1UEBhMCRlIxDjAMBgNVBAgTBVBhcmlzMQ4wDAYDVQQHEwVQYXJpczEO
      ...
      lIxY9HJanHrWvjiz7+eToxXpZJtAPXTx5hxzcJrtWROlq7IJCMIhzr/EVA37jTCk
      Xs5S6mr0T6Dqx6MQkPATSsEEJlLH5wq3DxXQcrMqnM/WHMRYUCkoTl37sXplflHe
      jw==
      -----END CERTIFICATE-----
    key: |
      -----BEGIN PRIVATE KEY-----
      MIIJRQIBADANBgkqhkiG9w0BAQEFAASCCS8wggkrAgEAAoICAQDONqqTCS4CiSi/
      XeNpp2nUsq1299spGc7mlRs+PDrXNHscB5lUB5/yo2yEetYXrJacQ8n4NV9hkID5
      ...
      44eHDYsofcnRbidGR+QT8PQgiiDNCkbpi2u4QnLTs0w4oW+53ZTyHYEYF2rcLbIb
      vRt4kR4KG6ULXrmsRA4WQjBDJ9vZw2aK+w==
      -----END PRIVATE KEY-----

#+END_SRC

**** Ajouter des rêgles particulière de apache


#+BEGIN_SRC yaml
    relations:
      web-proxy:
        apache:
          ...
          apache-custom-rules: |
            RewriteEngine On
            RewriteCond %{HTTPS} off
            RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L,QSA]

#+END_SRC

**** Vérification des derniers logs de renouvellement automatique

#+BEGIN_SRC shell
tail -f /srv/datastore/data/cron/var/log/cron/letsencrypt-renew_script.log -n 200
#+END_SRC


*** postgres

**** utilisation de pgm

récupérer l'IP du docker postgres via =docker-ip=

#+BEGIN_SRC sh
PGHOST=172.19.0.2 PGUSER=postgres pgm ls
#+END_SRC


**** base corrompue, réparation

Il s'agit de lancer un =pg_resetwal=, il faut veiller à plusieurs élément:
- bien arréter tout process utilisant le répertoire de =data= du
  postgres en question, généralement un =compose stop postgres=
  suffit.
- utiliser l'image du postgres via son nom (habituellement =myc_postgres=).
- monter le répertoire data =directement=

Le tout peut se faire ainsi dans une installation qui fait tourner un postgres 
actuellement:

#+begin_src sh
compose stop postgres &&
docker run --rm --entrypoint pg_resetwal \
    -u postgres -v /srv/datastore/data/postgres/var/lib/postgresql/data:/var/lib/postgresql/data \
    myc_postgres \
    /var/lib/postgresql/data &&
docker start myc_postgres_1
#+end_src


*** mysql

**** sur installation mailcow

Le script =mailcow-backup-install= fourni via =myc-manage= s'occupe
de mettre en place le dump de =mysql=, et le système pour envoyer les
backup régulièrement via rsync.

**** docker sans compose

#+begin_src sh
export MYSQL_ROOT_PASSWORD=xxx
export MYSQL_CONTAINER=mailcowdockerized_mysql-mailcow_1

/srv/charm-store/mysql/hooks/install.d/60-backup.sh
#+end_src


*** rsync-backup

**** Installation du backup via compose

A faire depuis le serveur ayant des services géré par =compose= à
backupper.

#+begin_src sh
DOMAIN=xxx.fr

## CODE
BACKUP_SERVER=core-06.0k.io:10023

ssh-keygen -t rsa -N "" -f /root/.ssh/rsync_rsa -C "rsync@$DOMAIN"
cat <<EOF >> /opt/apps/myc-deploy/compose.yml

rsync-backup:
  options:
    ident: $DOMAIN
    target: $BACKUP_SERVER
    private-key: |
$(cat /root/.ssh/rsync_rsa | sed -r 's/^/      /g')
EOF

dest="$BACKUP_SERVER"
dest="${dest%/*}"
dest="${dest%%:*}"
echo "Contacting '$dest' host, to add key in authorized key:"
ssh -o "StrictHostKeyChecking=no" "root@${dest}" -- compose-add-rsync-key -R "\"$DOMAIN\"" "\"$(cat /root/.ssh/rsync_rsa.pub)\""


#+end_src

**** Installation du backup sur une installe mailcow

Le script suivant va s'occuper de tout, il doit être lancé
depuis l'hôte faisant tourner l'installation =mailcow=.

#+begin_src sh
mailcow-backup-install
#+end_src

**** Installation du backup sur un host debian

Cela fonctionnera sur tout host ayant une base debian.

#+begin_src sh
export DOMAIN=mail.myceliandre.fr
export BACKUP_SERVER=core-06.0k.io:10023

/srv/charm-store/rsync-backup/hooks/install.d/60-install.sh

#+end_src

Note, il est possible de spécifier des exclusions pour chaque
répértoire mirroré de telle façon:

#+begin_src sh
cat <<EOF > /etc/mirror-dir/config.yml
/home:
    exclude:
        - /*/.cache/
        - /*/.gvfs/
        - /*/.local/share/Trash/files/
        - /*/.Trash/
        - /*/.mozilla/firefox/*/Cache/
        - /*/.mozilla/firefox/*/storage/default/*/cache/
/media/data:
    exclude:
        - /binary/games/_steam
        - /incoming
        - /.Trash*
        - /lost+found
        - /backup/device
EOF
#+end_src


* Interventions avancées

Description des process avancés d'intervention sur une installation existante.

** Modification du compose

Y a un exemple en commentaire dans le =/opt/apps/myc-deploy/compose.yml=

Petit exemple:

#+BEGIN_SRC yaml
odoo:
  ...

  docker-compose:
    ## Important to keep as a list: otherwise it'll overwrite charm's arguments.
    command:
      - "--log-level=debug"
    environment:
      TOTO: TUTU
    image: masuperimage

#+END_SRC

** Troubleshooting

S'il semble qu'il y ait un soucis, tu peux visualiser le =docker-compose.yml= qui est
généré à la fin via l'ajout de =--debug= AVANT la commande:

#+BEGIN_EXAMPLE
compose --debug up odoo frontend
#+END_EXAMPLE


* Comment ça marche

La surcouche =compose= est là pour créer un =docker-compose.yml= et le
lancer tout a fait normalement.  Le long du chemin, il peut aussi
préparer des trucs utiles si c'est nécessaire.

Il part du =compose.yml= et accède aux définitions en yaml des charms à déployer
et qui sont dans /srv/charms ... (qui en fait sont dans =/opt/apps/0k-charms=).

Chaque charm possède une définition générale (le =metadata.yml=) qui peut aussi
injecter des trucs dans le =docker-compose.yml= final.

Et puis il y a des =hooks=, qui sont juste des scripts bash qui sont
lancés avec des infos dans des variables d'environment, qui vont généralement
créer des trucs à l'init ou lors de liaison avec d'autres charms.