web:framework:spring:deployment

Ceci est une ancienne révision du document !


Déploiement Springboot

Mise en place du déploiement automatique d'une application Springboot vers un serveur externe (VM mise à disposition) via CI/CD Gitlab.

Se connecter en root avec su :

su -l

Installer Java

Choisir une version compatible (supérieure ou égale à la verion java déclarée dans le pom.xml):

cd /tmp
wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.deb
dpkg -i jdk-17_linux-x64_bin.deb
java -version

Installer Tomcat 10

Ajouter un utilisateur tomcat :

useradd -m -d /opt/tomcat -U -s /bin/false tomcat 

Télécharger et dézipper Tomcat :

cd /tmp
wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.16/bin/apache-tomcat-10.1.16.tar.gz
sudo tar xzvf apache-tomcat-10*tar.gz -C /opt/tomcat --strip-components=1 

Définir les permissions sur les fichiers :

chown -R tomcat:tomcat /opt/tomcat/ 
chmod -R u+x /opt/tomcat/bin 

Créer le tomcat-manager pour manager les sites à distance via l'interface web :

nano /opt/tomcat/conf/tomcat-users.xml

<!-- user manager can access only manager section -->
<role rolename="manager-gui" />
<user username="manager" password="_SECRET_PASSWORD_" roles="manager-gui" />

<!-- user admin can access manager and admin section both -->
<role rolename="admin-gui" />
<user username="admin" password="_SECRET_PASSWORD_" roles="manager-gui,admin-gui" />

Créer un service Tomcat

Pour gérer tomcat plus facilement, créer un service Tomcat :

nano /etc/systemd/system/tomcat.service

[Unit]
Description=Tomcat
After=network.target

[Service]
Type=forking

User=tomcat
Group=tomcat

Environment="JAVA_HOME=/usr/lib/jvm/jdk-17-oracle-x64"
Environment="JAVA_OPTS=-Djava.security.egd=file:///dev/urandom"
Environment="CATALINA_BASE=/opt/tomcat"
Environment="CATALINA_HOME=/opt/tomcat"
Environment="CATALINA_PID=/opt/tomcat/temp/tomcat.pid"
Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC"

ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh

[Install]
WantedBy=multi-user.target

Recharger le deamon service pour prendre en compte le nouveau service :

systemctl daemon-reload

Démarrer Tomcat :

systemctl start tomcat.service

Activer Tomcat pour qu'il redémarre automatiquement à chaque reboot :

systemctl enable tomcat.service

Afficher son statut :

systemctl status tomcat.service

Accéder à l'interface Web via l'adresse DNS fournie :

  • http[s]://srv2-vm-[number].sts-sio-caen.info/
  • http[s]://srv2-vm-[number].sts-sio-caen.info/manager/

gitlab-ci user sur la VM

Sur la VM :

  • Créer un utilisateur gitlab-ci
  • Faire en sorte qu'il puisse accéder à sudo
  • Changer son password : changeMyPassword
  • Permettre qu'il puisse s'authentifier en SSH avec login/password
  • Redémarrer SSH
  • Faire en sorte qu'il n'ait pas besoin de saisir un password en utilisant sudo avec les commandes mv, cp, systemctl

adduser --quiet --shell $SHELL --disabled-password --gecos 'GitlabCI User' gitlab-ci
usermod -a -G sudo gitlab-ci
echo 'gitlab-ci:changeMyPassword' | chpasswd
printf 'Match User gitlab-ci\n\tPasswordAuthentication yes\n' >> /etc/ssh/sshd_config
systemctl restart sshd
echo 'gitlab-ci ALL=(ALL) NOPASSWD: /bin/mv, NOPASSWD: /usr/bin/systemctl, NOPASSWD: /bin/cp' | sudo EDITOR='tee -a' visudo

Variable CI/CD sur Gitlab

Créer une variable dans Gitlab pour stocker le mot de passe de l'utilisateur gitlab-ci qui se connectera en SSH :

Dans Settings-CI/CD, créer la variable CI_USER_PASS :

Configuration du projet Springboot

Modifier pom.xml pour définir le nom du fichier WAR déployé :

    <build>
        <finalName>ssh-deploy</finalName>
    </build>

Vérifiez que le déploiement sera bien fait en WAR :

    <packaging>war</packaging>

Configuration Gitlab CI/CD

Créer ou modifier le fichier .gitlab-ci.yml :

stages:
  - build
  - deploy

maven-build:
  image: maven:3.9.5-amazoncorretto-17-debian
  stage: build
  script: "mvn package -B"
  artifacts:
    paths:
      - target/ssh-deploy.war

deploy-master:
  variables:
    HOST: "149.202.94.223"
    PORT: "7839"
    USER: "gitlab-ci"
    WAR: "ssh-deploy.war"
  rules:
    - if: '$CI_COMMIT_BRANCH =~ /^main$/'
  before_script:
    - apt-get update -qq && apt-get install -y -qq sshpass sudo
    - echo "Host= $HOST"
  stage: deploy
  script:
    - sudo whoami  # Vérifiez si sudo est disponible
    - which mv
    - sshpass -V
    - export SSHPASS=$CI_USER_PASS
    - sshpass -e scp -o StrictHostKeyChecking=no -P $PORT target/$WAR $USER@$HOST:/home/$USER
    - sshpass -e ssh -tt -o StrictHostKeyChecking=no -p $PORT $USER@$HOST echo $PATH
    - sshpass -e ssh -tt -o StrictHostKeyChecking=no -p $PORT $USER@$HOST sudo mv /home/$USER/$WAR /opt/tomcat/webapps
    - sshpass -e ssh -tt -o StrictHostKeyChecking=no -p $PORT $USER@$HOST sudo systemctl restart tomcat.service

Il est conseillé de mettre les valeurs HOST, USER et PORT dans des variables Gitlab.

Vérifier que les 2 jobs sont bien lancés sur Gitlab à chaque commit sur la branche main, et que l'application est bien déployée sur le serveur :

La création de profiles permet de gérer des configurations différentes, et des fichiers de configuration spécifiques à chaque profile.

Ajouter la section profiles suivante au fichier pom.xml

    <profiles>
        <profile>
            <id>dev</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <activeProfile>dev</activeProfile>
            </properties>
        </profile>
        <profile>
            <id>prod</id>
            <properties>
                <activeProfile>prod</activeProfile>
            </properties>
        </profile>
        <profile>
            <id>test</id>
            <properties>
                <activeProfile>test</activeProfile>
            </properties>
        </profile>
    </profiles>

Il est ensuite possible de créer des fichiers de configuration spécifiques à chaque profile, en plus du fichier de configuration de base application.properties.

Configuration générale : application.properties

spring.profiles.active=@activeProfile@

# Mustache Template engine
spring.mustache.prefix=classpath:/templates/
spring.mustache.suffix=.html

# H2 Database + JPA
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.globally_quoted_identifiers=true

spring.h2.console.enabled=true
spring.h2.console.settings.web-allow-others=true
spring.h2.console.path=/h2-console

Configuration spécifique au dev

spring.datasource.url=jdbc:h2:file:./data/paris-2024;DB_CLOSE_ON_EXIT=FALSE
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

servlet.context.path=/

Configuration spécifique à la prod

  • La base de données H2 est localisée en dehors du dossier du projet (pour ne pas être modifiée par les commits)
  • Les Logs SQL sont désactivés

La base de données (le fichier db) pourra être déposée dans le dossier préalablement créé sur la VM : /data/h2/ via WinSCP.

spring.datasource.url=jdbc:h2:file:/data/h2/paris-2024/data;DB_CLOSE_ON_EXIT=FALSE
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.format_sql=false

servlet.context.path=/paris-2024

Configuration spécifique aux tests

spring.datasource.url=jdbc:h2:file:/home/runner/work/myparis/paris-2024/target/data;DB_CLOSE_ON_EXIT=FALSE
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

servlet.context.path=/

Prise en compte dans .gitlab-ci.yml

Génération du package en production

  stage: build
  script: "mvn clean package -P prod -DskipTests=true"

Génération du package pour les tests

  stage: test
  script: "mvn --batch-mode --update-snapshots verify -P test -DskipTests=false"

  • web/framework/spring/deployment.1700918388.txt.gz
  • Dernière modification : il y a 17 mois
  • de jcheron