> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.goodflag.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.goodflag.com/_mcp/server.

# Déploiement

> Déployer une instance en production

# Déploiement

## Lancer l'application

Cette application est une application **Spring Boot** entièrement exécutable.
Sur la plupart des systèmes d'exploitation, elle peut être lancée avec la commande suivante, en supposant que Java est correctement installé :

```bash
java -jar webapp.jar
```

Sur un système d'exploitation basé sur Unix/Linux, vous pouvez simplement exécuter :

```bash
./webapp.jar
```

> Utilisez `java -Xmx1024m -jar webapp.jar` pour modifier l'utilisation maximale de mémoire de la JVM.

## Propriétés de configuration

Les propriétés de configuration peuvent être transmises à l'application sous forme d'arguments de ligne de commande commençant par `--`.
Par exemple, le port d'écoute du serveur peut être spécifié comme suit :

```bash
java -jar webapp.jar --server.port=8080
```

Ou directement :

```bash
./webapp.jar --server.port=8080
```

> Consultez la configuration de l'application pour la liste des propriétés de configuration disponibles.

## Service systemd

La plupart des distributions Linux modernes utilisent *systemd* pour créer des services en arrière-plan, les démarrer automatiquement au démarrage du serveur et les redémarrer en cas d'arrêt inattendu.

Pour créer un service systemd, nous créons d'abord l'utilisateur `sunnystamp` en exécutant les commandes suivantes :

```bash
groupadd -r sunnystamp
useradd -r -g sunnystamp -d /home/sunnystamp -s /bin/bash sunnystamp
mkdir -p /home/sunnystamp
chown sunnystamp:sunnystamp /home/sunnystamp
```

Nous créons ensuite un fichier unité systemd nommé `webapp.service` que nous plaçons dans `/etc/systemd/system` :

```bash
[Unit]
Description=Goodflag web application
After=syslog.target

[Service]
User=sunnystamp
Environment="LC_ALL=C"
ExecStart=/usr/bin/java -XX:MaxRAMPercentage=40.0 -XX:+ExitOnOutOfMemoryError -jar /path/to/webapp.jar --server.port=8080
SuccessExitStatus=143
Restart=on-failure

[Install]
WantedBy=multi-user.target
```

> Vous pouvez spécifier un chemin et des paramètres différents pour le champ `ExecStart`.

Nous pouvons maintenant démarrer le service avec les commandes suivantes :

```bash
# Charger le service
systemctl daemon-reload
# Démarrer le service maintenant
systemctl start webapp.service
# Démarrer le service automatiquement au démarrage
systemctl enable webapp.service
```

## Service Windows

Sur un système d'exploitation Windows, vous pouvez encapsuler l'application en tant que service Windows en suivant ces étapes :

1. Téléchargez [winsw](https://github.com/kohsuke/winsw/releases). Assurez-vous de choisir la version correcte en fonction de votre version de .NET.
2. Renommez l'exécutable *winsw* en `webapp.exe`.
3. Créez un fichier XML nommé `webapp.xml` avec le contenu suivant :

```xml
<?xml version="1.0" encoding="UTF-8"?>
<service>
    <id>webapp</id>
    <name>webapp</name>
    <description>Goodflag web application</description>
    <executable>java</executable>
    <arguments>-jar "webapp.jar"</arguments>
    <logmode>rotate</logmode>
</service>
```

4. Créez un dossier contenant `webapp.exe`, `webapp.jar` et `webapp.xml`.
5. Installez le service Windows en exécutant la commande suivante dans le dossier.

```bash
webapp.exe install
```

Le service devrait maintenant apparaître dans le Gestionnaire des services Windows.

## Conteneur Docker

Pour créer une image *docker* de l'application, exécutez la commande suivante dans le dossier où se trouvent le `Dockerfile` et le `webapp.jar` :

```bash
docker build -t sunnystamp/webapp .
```

Pour exécuter l'application au premier plan et exposer le port d'écoute sur l'hôte :

```bash
docker run -p 8080:8080 -it sunnystamp/webapp --server.port=8080
```

Notez que vous devrez créer des volumes pour les différents dossiers de la configuration de l'application.
Par exemple, voici comment monter votre dossier client dans le conteneur :

```bash
docker run -p 8080:8080 -v /path/to/clients:/clients -it sunnystamp/webapp \
    --server.port=8080 \
    --clientFolderPath=/clients
```

## Clustering

Pour des raisons de résilience, vous pouvez répliquer l'application dans un environnement en cluster en déployant simplement l'exécutable sur différentes machines, placées derrière un répartiteur de charge. Pour ce type de déploiement, les exigences suivantes doivent être respectées :

* Les horloges des différentes machines doivent être synchronisées périodiquement. Cela peut être réalisé à l'aide d'un serveur NTP.

* Certains dossiers utilisés dans la configuration de l'application doivent être partagés entre les nœuds. Cela peut être réalisé à l'aide d'un serveur NFS ou CIFS.

> **Remarque :** la mise en cache des attributs de fichiers doit être désactivée pour que les lectures/écritures fonctionnent correctement. Dans le cas d'un serveur NFS, l'option de montage `noac` doit être spécifiée. Pour un serveur CIFS, l'option de montage `actimeo=0` doit être spécifiée.

À titre de suggestion, le dossier client peut être partagé entre les nœuds, en accès lecture seule. Cela vous permettra de gérer la configuration client de façon centralisée.

## Ports requis

Le Workflow Manager nécessite que le port TCP 8885 soit accessible par le reverse proxy. Ce numéro de port peut être modifié via la propriété `server.port` dans la configuration de l'application.

Le Workflow Manager a également besoin d'accéder à :

* Le serveur Elasticsearch, sur le port exposé par Elasticsearch (le port par défaut est TCP 9200).
* Le démon ClamAV, sur le port exposé par ClamAV (le port par défaut est TCP 3310).

De plus, l'application nécessite un accès **HTTP** (TCP, port 80) et **HTTPS** (TCP, port 443) à Internet pour que les fonctionnalités suivantes fonctionnent correctement :

* Accéder au serveur d'horodatage afin de produire des signatures horodatées.
* Télécharger les CRL et accéder aux répondeurs OCSP afin de vérifier le statut de révocation des certificats de signataires et d'autorités de certification.

Par ailleurs, afin de personnaliser les pages de consentement pour vos clients, l'application établira des connexions **HTTPS** (TCP, port 443) vers l'URL de l'Evidence Manager.

## Configuration du proxy

Si vous souhaitez que l'application se connecte au monde extérieur via un proxy, vous pouvez spécifier l'hôte et le port du proxy sous forme d'arguments de ligne de commande, ainsi que le nom d'utilisateur et le mot de passe si votre proxy nécessite une authentification :

```bash
java -jar webapp.jar \
    --proxyHost=my-proxy.local \
    --proxyPort=3128 \
    --proxyUser=my_proxy_user \
    --proxyPassword=my_proxy_password
```

Notez que l'application créera un tunnel TCP à travers le proxy pour toute connexion HTTP ou HTTPS sortante. Vous devez donc vous assurer que la méthode HTTP CONNECT est autorisée. Typiquement, sur un proxy Squid, la règle suivante doit être supprimée ou remplacée :

```
# Refuser CONNECT vers des ports autres que les ports SSL sécurisés
http_access deny CONNECT !SSL_ports
```

## Configuration HTTPS

Vous devez déployer l'application derrière un reverse proxy afin qu'elle ne soit pas exposée directement sur Internet. Si nécessaire, vous pouvez également activer HTTPS directement dans l'application à l'aide de la configuration de l'application :

```bash
java -jar webapp.jar --server.port=443 --server.ssl.enabled=true --server.ssl.key-store=keystore.p12 --server.ssl.key-store-password=change_me --server.ssl.keyStoreType=PKCS12 --server.ssl.key-alias=mykey
```

> Utilisez `java -jar webapp.jar -Djavax.net.debug=ssl:handshake:verbose` pour déboguer les problèmes de négociation TLS.

## Pare-feu applicatif web (WAF)

Si vous souhaitez utiliser un pare-feu applicatif web (WAF) devant l'application pour des raisons de sécurité, vous devez vous assurer que votre WAF ne bloque pas les requêtes HTTP à destination de l'application pour les méthodes suivantes :

* `GET`
* `POST`
* `PUT`
* `DELETE`
* `PATCH`
* `OPTIONS`

Par ailleurs, l'application utilisant CORS, votre WAF ne doit pas supprimer ni modifier les en-têtes suivants dans les requêtes HTTP à destination de l'application :

* `Origin`
* `Access-Control-Request-Method`
* `Access-Control-Request-Headers`

Ainsi que les en-têtes suivants dans les réponses HTTP provenant de l'application :

* `Access-Control-Allow-Origin`
* `Access-Control-Allow-Credentials`
* `Access-Control-Allow-Methods`
* `Access-Control-Allow-Headers`
* `Access-Control-Max-Age`