Installation Docker

Afin de faciliter l’installation du serveur SAINet, un container est mis à disposition sur Docker Hub (dès la version 4.9). En utilisant cette image, combinée aux autres services nécessaires, aucune installation particulière (en dehors de Docker) n’est nécessaire sur la machine hôte.

Architecture générale

Le schéma ci-dessous montre l’architecture générale ainsi que les différents composants d’une installation docker.

Architecture générale

  • sainet_traefik est utilisé pour traiter les requêtes externes et les transmettre au serveur SAINet.
  • Si les requêtes sont reçues directement depuis un réseau externe en HTTPS, le certificat SSL devra être servi par Traefik. Sinon il devra être servi au niveau du firewall/proxy en amont.
  • sainet_app est le composant applicatif central de la solution qui gère tous les traitements métiers.
  • sainet_db stocke toutes les données persistentes de l’application. Ce composant peut être externalisé sur une autre machine (voir ici).
  • sainet_redis est un cache utilisé notamment pour la partie web.

Les différents fichiers (GED, base de données) sont stockés sur le disque via des volumes.

Info:

Si les communications HTTPS sont gérées par le firewally/proxy et transmises en HTTP sur le réseau interne, le composant sainet_traefik peut-être omis.

Paramètres

Afin de pouvoir configurer SAINet, les paramètres ci-dessous doivent être connus au préalable.

Paramètre Variable Description
user SAINET_UPDATE_USERNAME Identifiant pour accéder aux paquets d’installation et de mises à jour.
password SAINET_UPDATE_PASSWORD Mot de passe pour accéder aux paquets d’installation et de mises à jour.
customer id SAINET_CUSTOMER_FILE Identifiant du client au sein de SAINet.
environment id SAINET_ENV_NAME Identifiant de l’environnement d’installation. Cette valeur est en lien avec le serveur sur lequel l’application va être installée.
Base de données SAINET_DATABASE_* Paramètres de connexion à la base de données.

Prépration du système

Sous Debian, 2 paquets doivent être installés:

apt-get install docker docker-compose
systemctl start docker

L’utilisateur courant (<user>) doit ensuite faire partie du groupe docker afin de pouvoir gérer le service. Avec l’utilisateur root, exécuter la commande suivante:

gpasswd -a <user> docker

L’utilisateur devra ensuite se reconnecter afin d’avoir ses accès à jour.

Note:

Pour éviter de se reconnecter, il est possible d’utiliser la commande newgrp docker.

Configuration minimale

Voici une configuration minimale (contenu du fichier docker-compose.yml) permettant de démarrer SAINet (docker-compose up -d):

version: "3.0"

services:
  sainet_app:
    restart: always
    image: saierp/sainet:4.11
    volumes:
      - "./sainet:/sainet"
      
    ports:
      - "80:9090"

    environment:
      # java options
      - JAVA_OPTIONS=-Xmx4096m
      
      # database configuration
      - SAINET_DATABASE_HOST=<to_define>
      - SAINET_DATABASE_SCHEMA=<to_define>
      - SAINET_DATABASE_USER=<to_define>
      - SAINET_DATABASE_PASSWORD=<to_define>
      
      # global configuration
      - SAINET_CUSTOMER_FILE=<to_define>
      - SAINET_ENV_NAME=<to_define>
      #- SAINET_EXTERNAL_URL=<to_define>
      
      # update configuration
      - SAINET_UPDATE_USERNAME=<to_define>
      - SAINET_UPDATE_PASSWORD=<to_define>
      - SAINET_UPDATE_MODE=release

Dans la configuration ci-dessus, SAINet est connecté sur le port 80 (HTTP). Lorsque le serveur se trouve derrière un proxy, ce dernier s’occupe de traiter les requêtes HTTPS et transfère ensuite la requête au serveur SAINet sur le port HTTP. Il est possible d’utiliser un autre port en utilisant la syntaxe "<port>:9090". Le port SAINet interne (9090) peut également être changé grâce à la variable SAINET_PORT_HTTP.

Note:

Le dossier /sainet doit être utilisé en tant que volume car celui-ci contient tous les fichiers qui doivent être persistants.

Les variables d’environnement principales sont les suivantes:

Variable Description
JAVA_OPTIONS Options spécifiques à Java. Il est recommandé de spécifier au moins la propriété -Xmx avec une valeur minimale de 2048m.
SAINET_PORT_HTTP Port HTTP de l’application. Par défaut, 9090. La valeur zéro désactive le port.
SAINET_PORT_HTTPS Port HTTPS de l’application. Par défaut, 0 (désactivé).
SAINET_DATABASE_* Configuration d’accès à la base de données.
SAINET_CUSTOMER_FILE Identifiant du client au sein de SAINet, transmis par SAI ERP.
SAINET_ENV_NAME Identifiant de l’environnement d’installation, transmis par SAI ERP. Cette valeur est en lien avec le serveur sur lequel l’application va être installée.
SAINET_EXTERNAL_URL Permet de spécifier l’URL externe complète par laquelle le serveur SAINet peut être atteint (par exemple https://sainet.mydomain.com/SNV4SRV-ws-war/EPS).
SAINET_WEBAPP_ENABLED Détermine si la partie applicative via browser doit être activée (désactivée par défaut). En 4.9, cette variable se nommait SAINET_MOBILE_ENABLED.
SAINET_REDIS_URL URL d’accès au cache Redis. Cette variable n’est pas nécessaire, mais recommandée dans le cas ou la partie mobile/webapp est activée pour des raisons de performances. Généralement il s’agit d’une URL sous la forme redis://<ip>.
SAINET_UPDATE_USERNAME / SAINET_UPDATE_PASSWORD Identifiant / mot de passe pour les mises à jour automatiques, transmis par SAI ERP. Ces valeurs sont nécessaires pour initialiser l’image.
SAINET_UPDATE_MODE Version à installer. Détermine également la fréquence des mises à jour. Les valeurs autorisées sont release, rc et snapshot. Si cette variable n’est pas définie, les mises à jours automatiques sont désactivées.
SAINET_UPDATE_RESTART Détermine si SAINet applique les mises à jour mineures (redémarrage automatique). Si cette variable n’est pas précisée, elle vaut true par défaut.
SAINET_GITLAB_TOKEN Token GitLab permettant d’accéder aux données de test (res_data). Ce token peut se créer dans les préférences.
SAINET_GITLAB_TESTID Identifiant du projet res_data à utiliser (par exemple 191 pour sw4). Ne fonctionne qu’avec une base de données H2 (sans définir les variables SAINET_DATABASE_MYSQL_*).
SAINET_SYSTEM_TEST Permet de définir si l’installation est un système de test. Essentiellement utilisé pour les serveurs internes à SAI ERP.
SAINET_SYSTEM_TEST_ENABLED_USERS Désactive tous les utilisateurs, exceptés ceux listés dans cette propriété. Il est possible de lister plusieurs valeurs séparées par des virgules et d’utiliser des wildcards.
SAINET_SYSTEM_TEST_MAILHOG Permet de définir le nom d’hôte pour le serveur de test d’envoi de mail. Essentiellement utilisé pour les serveurs internes à SAI ERP.
SAINET_START_OPTIONS Permet de définir des paramètres spéciaux au démarrage du serveur. Par défaut, seule l’option --verbose est définie.

Les variables d’environnement relatives à GitLab servent à initialiser un serveur avec des données de test et ne sont pas destinées à être utilisées dans la configuration d’un serveur de production.

Ci-dessous, un exemple de configuration minimale pour démarrer un serveur avec les données de test. A noter qu’il n’y a pas de volume, donc aucune information n’est persistée.

version: "3.0"

services:
  sainet_app:
    restart: always
    image: saierp/sainet:4.11

    environment:
      # java options
      - JAVA_OPTIONS=-Xmx4096m -Xms2048m

      # ports configuration
      - SAINET_PORT_HTTP=9090

      # global configuration
      - SAINET_CUSTOMER_FILE=<to_define>
      - SAINET_ENV_NAME=<to_define>

      # update configuration
      - SAINET_UPDATE_USERNAME=<to_define>
      - SAINET_UPDATE_PASSWORD=<to_define>

      # test data configuration
      #- SAINET_GITLAB_TOKEN=<to_define>
      #- SAINET_GITLAB_TESTID=<to_define>

    ports:
      - "80:9090"

Configuration complète

La configuration ci-dessous déclare plusieurs services utilisés par SAINet:

ID Description Volume
sainet_db Base de données sainet/mariadb
sainet_redis Cache Redis (lorsque l’application web est déployée, cf SAINET_WEBAPP_ENABLED) aucun
sainet_traefik Serveur HTTP/HTTPS pour la gestion des communications et certificats SSL sainet/certificates
sainet_app Serveur SAINet sainet/app
version: "3.0"

services:
  # SAINet configuration
  sainet_app:
    restart: always
    image: saierp/sainet:4.11
    depends_on:
      - sainet_db
      - sainet_redis
    volumes:
      - "./sainet/app:/sainet"

    environment:
      # java options
      - JAVA_OPTIONS=-Xmx4096m -Xms2048m
      
      # database configuration
      - SAINET_DATABASE_HOST=sainet_db
      - SAINET_DATABASE_PORT=3306
      - SAINET_DATABASE_SCHEMA=sainet_prod
      - SAINET_DATABASE_USER=dbuser
      - SAINET_DATABASE_PASSWORD=dbpassword
      
      # ports configuration
      #- SAINET_PORT_HTTP=9090
      #- SAINET_PORT_HTTPS=0
      
      # global configuration
      - SAINET_CUSTOMER_FILE=<to_define>
      - SAINET_ENV_NAME=<to_define>
      #- SAINET_EXTERNAL_URL=<to_define>
      
      # webapp configuration
      - SAINET_WEBAPP_ENABLED=true
      - SAINET_REDIS_URL=redis://sainet_redis

      # update configuration
      - SAINET_UPDATE_USERNAME=<to_define>
      - SAINET_UPDATE_PASSWORD=<to_define>
      - SAINET_UPDATE_MODE=release
      #- SAINET_UPDATE_RESTART=false
      
      # automatic backup configuration
      #- SAINET_BACKUP_CRON_CONFIG=0 2 * * *
      #- SAINET_BACKUP_RETENTION_DAYS=5

      # bootstrap configuration from GitLab
      #- SAINET_GITLAB_TOKEN=<to_define>
      #- SAINET_GITLAB_TESTID=<to_define>

    labels:
      # URL mapping (if the server has a DNS)
      - "traefik.http.routers.sainet_app.rule=Host(`<to_define>.sai-erp.net`)"
      # Path mapping (if the server has no DNS)
      #- "traefik.http.routers.sainet_app.rule=PathPrefix(`/`)"
      
      # Internal service communication mapping (do not change)
      - "traefik.http.routers.sainet_app.entrypoints=websecure"
      - "traefik.http.services.sainet_app.loadbalancer.server.port=9090"
      - "traefik.http.routers.sainet_app.tls.certresolver=le"

  # Database configuration
  sainet_db:
    restart: always
    image: mariadb:10.11
    volumes:
      - "./sainet/mariadb:/var/lib/mysql:Z"
    environment:
      - MARIADB_DATABASE=sainet_prod
      - MARIADB_USER=dbuser
      - MARIADB_PASSWORD=dbpassword
      - MARIADB_ROOT_PASSWORD=sairoot
      - MARIADB_AUTO_UPGRADE=true
    command:
      - --max-allowed-packet=1024M
      - --default-time-zone=Europe/Zurich
      - --innodb-log-buffer-size=32m
      - --innodb-log-file-size=256m
      - --tmp-table-size=64m
      - --max-heap-table-size=64m
      - --query-cache-size=64m
      - --query-cache-limit=64m
      - --query-cache-strip-comments=1
      - --skip-name-resolve
      #peut être augmenté jusqu'à 80% de la mémoire dédiée à MariaDB
      - --innodb-buffer-pool-size=1024m
    labels:
      - "traefik.enable=false"
  
  # Redis configuration (mobile cache)
  sainet_redis:
    restart: always
    image: redis:7-alpine
    command: redis-server --maxmemory 512m
    labels:
      - "traefik.enable=false"
  
  # Frontend configuration (http/https redirection, certificate handling)
  sainet_traefik:
    restart: always
    image: traefik:v2.9
    depends_on:
      - sainet_app
    command:
      - --providers.docker
      - --entrypoints.web.address=:80
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --entrypoints.web.http.redirections.entrypoint.scheme=https
      - --entrypoints.websecure.address=:443
      - --certificatesresolvers.le.acme.email=<to_define>
      - --certificatesresolvers.le.acme.storage=/sainet/certificates/acme.json
      - --certificatesresolvers.le.acme.caserver=https://acme-v02.api.letsencrypt.org/directory
      - --certificatesresolvers.le.acme.tlschallenge=true
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "./sainet/certificates:/sainet/certificates"
    ports:
      - "80:80"
      - "443:443"

Accès aux fichiers

Par défaut, sans préciser la propriété user dans le fichier docker-compose.yml, l’utilisateur des containers sera root. Il est donc conseillé de mettre les paramètres uid et gid de l’utilisateur courant. Cela permettra également d’accéder directement aux fichier de SAINet sans devoir passer par root.

Info:

Le uid et le gid de l’utilisateur courant peuvent être récupérés avec la commande id -u, respectivement id -g.

services:
  sainet_app:
    user: "1000:1000"
    ...

SELinux et GED

Dans certains environnements sécurisés (notamment avec les multi-instances), la GED est stockée sur un autre serveur et disponible dans la machine hôte à travers un mount (par exemple /mnt/sainet-ged). Lorsque ce dossier est utilisé en tant que volume directement dans Docker, cela peut provoquer des problèmes de droits d’accès, même en mettant l’utilisateur correct.

Dans ce cas, il est nécessaire d’utiliser un volume de type bind comme ceci:

services:
  sainet_app:
    volumes:
      - "./sainet/app:/sainet"
      - type: bind
        source: /mnt/sainet-ged
        target: /sainet/runtime/edms/ged

Service MariaDB

Ce service gère la base de données de SAINet.

  • La TimeZone (--default-time-zone) doit être mise à Europe/Zurich (nécessite un chargement manuel des TimeZone dans un container).
  • L’option --max-allowed-packet doit être mise à 1024M afin de pouvoir dumper/restaurer la base de données (certaines tables contiennent de gros fichiers).
  • Lors d’une mise à jour de la base, la commande mysql_upgrade doit être exécutée.

Il est possible de dissocier complètement le service MariaDB (typiquement pour déplacer la base de données sur un autre serveur). Dans ce cas, il n’est plus possible d’utiliser le script sainet-up.sh et la gestion du service (initialisation & mise à jour) doit être faite manuellement.

Les parties relatives au service sainet_db ci-dessus doivent être également supprimées.

Pour les détails sur les différents paramètres relatifs à MariaDB, se référer à la documentation MariaDB.

Info:

Utiliser la version recommandée ici selon la version de SAINet installée.

Initialisation manuelle

Info:

Cette étape n’est plus nécessaire. Dans les versions récentes de MariaDB (>=10.11) le chargement des TimeZone n’est plus bloquant et la base de données peut être démarrée directement avec les paramètres définitifs.

Voici un exemple de fichier docker-compose.yml à utiliser pour le service MariaDB lorsque celui-ci est complètement découplé:

version: "3.0"
services:
  mariadb:
    restart: always
    image: mariadb:10.11
    volumes:
      - "./mariadb_data:/var/lib/mysql:Z"
    ports:
      - "3306:3306"
    environment:
      - MARIADB_DATABASE=sainet_prod
      - MARIADB_USER=dbuser
      - MARIADB_PASSWORD=dbpassword
      - MARIADB_ROOT_PASSWORD=dbroot
      - MARIADB_AUTO_UPGRADE=true
      - MARIADB_INITDB_SKIP_TZINFO=true
    command:
      - --max-allowed-packet=1024M
      #- --default-time-zone=Europe/Zurich
      
      #paramètre spéciaux pour amélioration des performances
      - --innodb-buffer-pool-size=1024m
      - --innodb-log-buffer-size=32m
      - --innodb-log-file-size=256m
      - --tmp-table-size=64m
      - --max-heap-table-size=64m
      - --query-cache-size=64m
      - --query-cache-limit=64m
      - --query-cache-strip-comments=1
      - --skip-name-resolve

Les éléments principaux à noter:

  1. Les fichiers de données vont être stockés dans mariadb_data (au même niveau que le fichier docker_compose.yml).
  2. Le port 3306 est exposé afin que des applications externes puissent s’y connecter.
  3. La variable MYSQL_INITDB_SKIP_TZINFO indique à MariaDB de ne pas charger tous les TimeZone (cette opération peut prendre jusqu’à 30 minutes).
  4. L’option --default-time-zone est mise en commentaire, car sinon MariaDB ne peut pas démarrer.
  5. Les paramètres spéciaux pour les performances sont décrit plus bas.

Le service peut maintenant être démarré avec la commande suivante:

docker-compose up -d
Note:

Docker va démarrer le container, cela ne veut pas pour autant dire que le service a pu effectivement démarrer ! Il est possible d’utiliser docker logs <container_id> pour accéder aux logs.

Afin de pouvoir intialiser la base de données, utiliser la commande docker ps pour récupérer le container id et exécuter les commandes suivantes afin d’obtenir un terminal dans le container mariadb et charger le timezone Europe/Zurich:

docker exec -ti <container_id> /bin/bash
mysql_tzinfo_to_sql /usr/share/zoneinfo/Europe/Zurich Europe/Zurich | mysql -u root -p mysql

Ensuite, quitter le terminal du container avec ctrl+d et stopper le container avec la commande docker-compose down. Finalement, mettre à jour le fichier docker-compose.yml en commentant/enlevant la variable MYSQL_INITDB_SKIP_TZINFO et en activant l’option ---default-time-zone:

version: "3.0"
services:
  mariadb:
    restart: always
    image: mariadb:10.11
    volumes:
      - "./mariadb_data:/var/lib/mysql:Z"
    ports:
      - "3306:3306"
    environment:
      - MARIADB_DATABASE=sainet_prod
      - MARIADB_USER=dbuser
      - MARIADB_PASSWORD=dbpassword
      - MARIADB_ROOT_PASSWORD=dbroot
      - MARIADB_AUTO_UPGRADE=true
    command:
      - --max-allowed-packet=1024M
      - --default-time-zone=Europe/Zurich
      
      #paramètre spéciaux pour amélioration des performances
      - --innodb-buffer-pool-size=1024m
      - --innodb-log-buffer-size=32m
      - --innodb-log-file-size=256m
      - --tmp-table-size=64m
      - --max-heap-table-size=64m
      - --query-cache-size=64m
      - --query-cache-limit=64m
      - --query-cache-strip-comments=1
      - --skip-name-resolve

Et enfin, redémarrer le container avec la commande docker-compose up -d.

Mise à jour manuelle

Attention:

Il est recommandé de faire une sauvegarde de la base de données avant la mise à jour !

La dernière version de MariaDB peut être récupérée avec les commandes suivantes:

docker-compose pull
docker-compose up -d

Cela force Docker à télécharger la dernière version du service et relance le container si nécessaire.

Lorsque le container a été redémarré sur la nouvelle version, il est nécessaire de lancer la commande mysql_upgrade. Cela peut être fait de la manière suivante:

docker exec -ti <container_id> /bin/bash
mysql_upgrade -u root -p

Il n’est pas nécessaire de redémarrer le container après que les tables ont été mises à jour.

Connexion à la base de donnée

Pour obtenir un terminal dans le container de la base de données, lancer les commandes suivantes:

docker exec -ti `docker ps | grep sainet_db | awk '{print $1}'` /bin/bash
mariadb -u dbuser -p sainet_prod

Il est également possible d’obtenir un accès direct à la base de données si la commande mariadb est installée sur l’hôte. Pour ce faire, il suffit d’utiliser l’adresse IP du container de la base de donnée pour le passer à l’option -h:

container_id=`docker ps | grep sainet_db | awk '{print $1}'`
container_ip=`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $container_id`
mariadb -u dbuser -p -h $container_ip sainet_prod
Note:

l’identifiant et l’adresse IP du container changent à chaque redémarrage du serveur. Il est donc nécessaire de les récupérer dynamiquement.

Paramètres spéciaux MariaDB

Les paramètres suivants sont recommandés:

Paramètre Valeur
innodb-buffer-pool-size 1024m
innodb-log-file-size 256m
innodb-log-buffer-size 32m
skip-name-resolve
tmp-table-size 64m
max-heap-table-size 64m
query-cache-size 64m
query-cache-limit 64m
query-cache-strip-comments 1

Il est également possible de définir les paramètres optimizer-use-condition-selectivity=1 et eq-range-index-dive-limit=0 si des problèmes de performances sont constatés. Cela peut être que l’optimisateur de requête n’arrive pas à sélectionner le bon index, ce qui résulte en un temps d’exécution très long (voir cette discussion).

Le paramètre innodb-buffer-pool-size est recommandé à 1024m par défaut, mais il est possible d’augmenter cette valeur si la quantité de mémoire disponible le permet afin d’avoir des temps de réponse possiblement encore meilleurs. Se référer à la documentation MariaDB pour les détails (80% de la mémoire dédiée à MariaDB).

Service Traefik

Ce service gère toutes les communications avec les requêtes externes.

  • Les connexions HTTP sont automatiquement redirigées en HTTPS.
  • En arrière-plan, les requêtes sont redirigées sur SAINet (port 9090).
  • Le certificat SSL est créé/renouvellé automatiquement (voir ci-dessous).

Chiffrage des communications (TLSv1.2)

Par défaut, la configuration fournie comme exemple dans tls-config.yml force l’utilisation du protocol TLSv1.3 avec un set de cipher réduit.

tls:
  options:
    default:
      # https://www.djpic.net/articles/traefik-v2-secure-tls-and-header-configuration-with-docker-provider/
      minVersion: VersionTLS12
      cipherSuites:
       # Recommended ciphers for TLSv1.2
       - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
       - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
       - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
       # Recommended ciphers for TLSv1.3
       - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
       - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
       - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305

Cela peut s’avérer problématique si le serveur sur lequel l’application est déployée n’a pas de nom de domaine, ni de certificat associé. Dans ce cas, il conviendra de mettre en commentaire la ligne --providers.file.directory=/sainet/config afin de désactiver la prise en compte de ce fichier.

Certificats dynamiques

La configuration ci-dessus utilise Let’s Encrypt afin d’obtenir un certificat SSL. Celui-ci sera renouvellé automatiquement par Traefik.

Afin que le certificat SSL puisse être créé/renouvelé automatiquement, il est nécessaire que la règle de routing dans le label traefik.http.routers.sainet_app.rule permette à Traefik d’identifier l’hôte. Typiquement, voici un label qui fonctionnera:

traefik.http.routers.sainet_app.rule=Host(`sainet.mydomain.com`)

Au contraire, l’utilisation de la règle ci-dessous ne permettra pas à Traefik d’obtenir un certificat SSL valide et fournira un certificat auto-signé (qui proviquera des alertes lorsque SAINet est accédé à travers un navigateur Web):

traefik.http.routers.sainet_app.rule=PathPrefix(`/`)
Note:

Lorsque la règle Host(sainet.mydomain.com) est utilisée, il ne sera pas possible d’accéder à SAINet via une autre URL que https://sainet.mydomain.com (typiquement localhost), Traefik retournera une erreur 404. Dans ce cas, il faudra temporairement utiliser la règle PathPrefix('/').

Let’s Encrypt - IPv6

Afin de pouvoir émettre un certificat, Let’s Encrypt va effectuer une requête sur l’hôte spécifié dans Host afin de s’assurer que le DNS pointe bien sur la bonne adresse IP.

Si le DNS contient une entrée AAAA, Let’s Encrypt va effectuer en premier une requête avec IPv6, ce qui peut conduire à des erreurs.

Note:

Si IPv6 n’est pas configuré sur le serveur, ne pas mettre l’entrée AAAA dans le DNS, sinon le certificat dynamique ne pourra pas être créé.

Certificats statiques

Lorsque les certificats ne sont pas renouvelables automatiquement via Let’s Encrypt ou un autre organisme supporté par traefik, il est possible de configurer ce dernier pour utiliser des certificats statiques. Pour ce faire, appliquer la procédure suivante (dans le service sainet_traefik):

  1. Enlever toutes les options --certificatesresolvers.*.
  2. Ajouter l’option --providers.file.directory=/certificates/config juste après l’option --providers.docker.
  3. Ajouter le volume ./sainet/certificates:/certificates.
  4. Créer le dossier ./sainet/certificates/files.
  5. Placer les fichiers pem et key dans ./sainet/certificates/files.
  6. Modifier le fichier ./sainet/certificates/tls-config.yml avec le contenu suivant (ajuster <file> avec les noms de fichiers corrects):
tls:
  certificates:
    - certFile: /certificates/files/<file>.pem
      keyFile: /certificates/files/<file>.key
Note:

La clé ne doit pas être protégée par un mot de passe.

La documentation traefik concernant le fichier tls.yml se trouve ici.

Dans le service sainet_app:

  1. Enlever le label - "traefik.http.routers.sainet_app.tls.certresolver=le".
  2. Rajouter le label - "traefik.http.routers.sainet_app.tls=true".

Voici un exemple partiel de docker-compose.yml:

services:
  sainet_app:
    #...
      
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.sainet_app.rule=PathPrefix(`/`)"

      # Internal service communication mapping
      - "traefik.http.routers.sainet_app.entrypoints=websecure"
      - "traefik.http.services.sainet_app.loadbalancer.server.port=9090"
      - "traefik.http.routers.sainet_app.tls=true"

  sainet_traefik:
    #...
    
    command:
      - --providers.docker
      - --providers.file.directory=/sainet/config
      - --entrypoints.web.address=:80
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --entrypoints.web.http.redirections.entrypoint.scheme=https
      - --entrypoints.websecure.address=:443
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "./tls-config.yml:/sainet/config/tls-config.yml"
    ports:
      - "80:80"
      - "444:443"

Point d’entrée et communication interne

Lorsque SAINet se trouve derrière un point d’entrée (Gateway, LoadBalancer, Proxy, …), ce dernier gère généralement les connexions externes HTTPS et le certificat SSL, puis transfert les données sur le réseau interne vers le service dédié. Dans ce cas, le service Traefik peut être désactivé et les connexions gérées directement par SAINet:

services:
  sainet_app:
    #...
    
    ports:
      - "80:9090"
      - "443:9191"
Attention:

Si les échanges internes entre le LoadBalancer et SAINet se font en HTTP, les données ne sont pas chiffrées et passent en clair sur le réseau. Il est donc essentiel que dans ce cas le réseau interne soit sécurisé. Le port HTTP (80) de SAINet ne doit jamais être exposé publiquement.

Si la variable SAINET_EXTERNAL_URL est spécifiée, elle doit être ciblée sur le point d’entrée visible de l’extérieur.

Création des containers

Pour créer les différents containers:

docker-compose pull
docker-compose up -d

Une fois le serveur SAINet démarré, il est possible de se connecter à SAINet avec les identifiants saierp / bootStrap373746.

Info:

Pour suivre les logs de démarrage du service SAINet, utiliser la commande docker logs -f $(docker ps | grep sainet_app | awk '{print $1}')

Mise à jour majeure (manuelle)

En premier lieu, se référer au guide de migration afin de prendre connaissance des changements importants.

Attention:

Il est fortement recommandé de faire une sauvegarde de la base de données avant toute mise à jour majeure !

Afin d’appliquer une mise à jour majeure, il suffit de changer la version du container SAINet dans docker-compose.yml et de relancer la commande docker-compose up -d. La nouvelle version sera automatiquement téléchargée et appliquée.

Importation

Dans un processus de migration (typiquement pour la préparation d’une mise à jour majeure), il est nécessaire de pouvoir importer les données actuellement en production sur un serveur de test. Une fois les données remontées, il suffit de redémarrer le container sainet_app et ce dernier appliquera automatiquement les mises à jour nécessaires.

Note:

La base de données importée doit provenir d’un serveur avec une version antérieure ou égale à celui déployé dans le container, sinon ce dernier refusera de démarrer.

Concernant la GED, les fichiers peuvent simplement être copiés dans le répertoire ./sainet/app/runtime/edms/ged.

Version actuelle

Dans un container docker, il est possible d’obtenir la version actuelle de SAINet avec la commande suivante:

docker exec <container_id> java -Djdk.jar.maxSignatureFileSize=32000000 -jar /sainet/sainet-server.jar --version
Info:

Le <container_id> peut être obtenu avec docker ps --filter "name=sainet_app" --format "{{.ID}}".

Mise à jour forcée

Si la mise à jour doit vraiment être forcée, la solution la plus simple consiste à supprimer le fichier ./sainet/app/sainet-server.jar et à relancer le container. Cela provoquera le téléchargement de la dernière version mineure du type de version configuré. Pour ce genre de cas, il est donc conseillé de spécifier SAINET_UPDATE_MODE=rc (voire même SAINET_UPDATE_MODE=snapshot si nécessaire) afin que le container puisse redémarrer sur une version plus récente et évite de forcer un rollback.

Attention:

Avec cette procédure, la mise à jour sera forcée, même si la base de données est plus récente. Cela peut provoquer un rollback de certaines modifications et conduire à des incohérences.

Démarrer sur une version spéciale

Notamment pour des raisons de test, il est possible de créer un package SAINet spécifique et de démarrer un container docker avec. Le package peut se créer au moyen des commandes suivantes:

mvn clean install -T2 -P no-check
mvn clean package -P full-package,no-check -pl external/SNV4SRV-server
java -jar external/SNV4SRV-server/target/SNV4SRV-server-full-embedded.jar --create-sainet-package sainet.jar

Le fichier sainet.jar doit ensuite être copié manuellement à l’emplacement <sainet>/app/sainet-server-update.jar, le dossier <sainet>/app étant le volumen indiqué dans le fichier docker-compose.yml.

Lorsque le fichier sainet-server-update.jar existe (mais pas le fichier sainet.jar), alors le container va l’utiliser au lieu de télécharger la version officielle publiée.