Documentation · EV Supervision Lite

Déployer EV Supervision Lite sur Oracle Cloud

Ce guide vous accompagne de la création du réseau chez Oracle jusqu'à la première borne connectée. Un seul chemin, celui que nous utilisons en production : une machine virtuelle, Docker Compose, une base PostgreSQL gérée et HTTPS automatique.

Pour une personne à l'aise avec un terminal Linux. Chaque étape vous dit ce que vous devez voir avant de passer à la suivante.

Ce que vous allez installer

Cinq pièces travaillent ensemble. Vous n'avez pas besoin de les connaître en détail, mais savoir qui fait quoi aide beaucoup le jour où quelque chose coince.

  • CaddyLe mandataire inverse, c'est-à-dire la porte d'entrée de votre serveur. Il obtient et renouvelle seul les certificats HTTPS (Let's Encrypt), puis envoie chaque demande au bon service.
  • Le serveur (ev-server)Le cœur du produit, écrit en Kotlin. Il garde la connexion permanente avec chaque borne en OCPP 1.6, calcule les sessions et parle à Stripe. Il écoute sur le port 8080, jamais exposé directement.
  • Le tableau de bord (ev-dashboard)L'application web où vos équipes gèrent bornes, utilisateurs, badges et tarifs. Elle écoute sur le port 3000 et transmet les appels au serveur sur le réseau privé.
  • PostgreSQLLa base de données. Nous conseillons le service géré OCI Database with PostgreSQL, placé dans un sous-réseau privé, avec ses sauvegardes automatiques.
  • OCI VaultLe coffre d'Oracle où vous rangez les secrets : mot de passe de la base et clé de chiffrement.

Avant de commencer

  • Un compte Oracle Cloud et un compartiment dans lequel vous pouvez créer réseau, base et instance. Région conseillée : eu-paris-1 ou eu-marseille-1.
  • La CLI oci installée et configurée sur votre poste, ou la console web d'Oracle si vous préférez cliquer.
  • Un nom de domaine dont vous gérez les DNS, par exemple supervision.votre-domaine.fr.
  • Une clé SSH, par exemple ~/.ssh/id_ed25519.pub.
  • Au moins une borne compatible OCPP 1.6 JSON pour l'essai final.
  • Facultatif : un compte Stripe pour les paiements, et une adresse d'envoi sur votre domaine pour les courriels.
  • La licence d'attribution Codetics, lue et acceptée. Elle autorise l'usage commercial, à condition que l'attribution à Codetics reste visible.
01

Préparer Oracle Cloud

On commence par le terrain : un réseau où l'instance est joignable depuis Internet, et où la base reste à l'abri.

  1. 1.1Créer le réseau

    Dans votre compartiment, créez un VCN (le réseau privé virtuel d'Oracle) avec deux sous-réseaux : un public pour l'instance, un privé pour la base de données. Ainsi, la base n'a aucune adresse visible depuis Internet.

    Dans la liste de sécurité, autorisez les ports 80 et 443 depuis Internet vers l'instance, et le port 5432 du sous-réseau public vers le sous-réseau privé. Le port 80 sert à l'obtention des certificats HTTPS, le 443 au tableau de bord et aux bornes, le 5432 à PostgreSQL.

    Ce que vous devez voir Votre VCN contient un sous-réseau public et un sous-réseau privé, et la liste de sécurité montre les règles 80, 443 et 5432.

  2. 1.2Choisir la forme de l'instance

    Pour quelques centaines de bornes, le guide du produit conseille une instance VM.Standard.E5.Flex avec 1 OCPU et 8 Go de mémoire. Pour un essai, une VM.Standard.A1.Flex (processeur Arm Ampere) avec 1 OCPU et 6 Go suffit, avec la base locale décrite au chapitre suivant.

    Un OCPU correspond à deux processeurs virtuels sur x86 et à un cœur sur Ampere. Le simulateur de coûts d'Oracle vous donne le prix exact selon votre région.

    Attention Sur une instance Arm, n'utilisez pas d'images construites pour amd64 : elles s'arrêtent avec « exec format error ». En suivant ce guide, docker compose construit les images sur l'instance elle-même, donc dans la bonne architecture.

02

Base de données et secrets

La base garde tout : bornes, sessions, utilisateurs, paiements. Un service géré vous évite de penser aux sauvegardes et aux mises à jour de PostgreSQL.

  1. 2.1Créer la base PostgreSQL

    Créez une base OCI Database with PostgreSQL, version 16 ou ultérieure, forme 2 OCPU, dans le sous-réseau privé. Activez les sauvegardes quotidiennes avec une rétention de 7 jours au moins.

    Créez ensuite la base ev_supervision et un utilisateur ev_supervision qui en est propriétaire. Ce point compte : au premier démarrage, le serveur crée lui-même toutes les tables, il doit donc posséder la base. Notez le point de terminaison privé de la base, vous en aurez besoin pour la configuration.

    Pour un simple essai, vous pouvez vous passer du service géré : Docker Compose sait démarrer PostgreSQL sur l'instance, dans un volume local. C'est le profil local-db, présenté au chapitre Configurer.

    Ce que vous devez voir La console affiche la base comme active, avec une adresse privée dans votre sous-réseau privé.

  2. 2.2Générer et ranger les secrets

    Deux secrets sont indispensables : le mot de passe de la base et la clé de chiffrement APP_ENCRYPTION_KEY, qui protège des données sensibles en base. Générez chacun avec la commande suivante, exécutée deux fois.

    Rangez-les dans un coffre OCI Vault, avec une clé maître, sous les noms database-password et app-encryption-key. Si l'instance doit lire ces secrets elle-même, placez-la dans un groupe dynamique autorisé à read secret-bundles dans le compartiment.

    Terminal
    openssl rand -base64 32

    Ce que vous devez voir Une suite de 44 caractères s'affiche à chaque exécution.

    Attention Sans APP_ENCRYPTION_KEY, les données chiffrées en base deviennent illisibles. Gardez-en une copie hors ligne, séparée des sauvegardes de la base.

03

Créer l'instance et récupérer le code

Place à la machine qui fera tourner le serveur, le tableau de bord et Caddy.

  1. 3.1Lancer l'instance

    Depuis votre poste, lancez l'instance dans le sous-réseau public, avec une adresse publique et votre clé SSH. Remplacez <compartiment>, <domaine> (le domaine de disponibilité), <image Ubuntu 24.04> et <sous-réseau-public> par les OCID de votre compte. Vous pouvez faire exactement la même chose dans la console web.

    Terminal
    oci compute instance launch --compartment-id <compartiment> \
      --availability-domain <domaine> --shape VM.Standard.E5.Flex \
      --shape-config '{"ocpus":1,"memoryInGBs":8}' --image-id <image Ubuntu 24.04> \
      --subnet-id <sous-réseau-public> --assign-public-ip true \
      --display-name ev-supervision --ssh-authorized-keys-file ~/.ssh/id_ed25519.pub

    Ce que vous devez voir L'instance ev-supervision passe à l'état en cours d'exécution et affiche une adresse IP publique. Vous pouvez vous y connecter en SSH.

  2. 3.2Ouvrir le pare-feu du système

    Les images Ubuntu et Oracle Linux d'OCI filtrent les ports entrants dans le système lui-même, en plus de la liste de sécurité. Sur Ubuntu, ouvrez 80 et 443 dans /etc/iptables/rules.v4. Sur Oracle Linux, utilisez firewall-cmd.

    Attention C'est le piège le plus fréquent chez Oracle : la liste de sécurité autorise 80 et 443, mais le système les garde fermés. Les certificats HTTPS ne s'obtiennent pas et les bornes ne se connectent pas.

  3. 3.3Installer Docker et récupérer le code

    Sur l'instance, installez Docker Engine avec le greffon Compose, en suivant la documentation officielle de Docker pour Ubuntu.

    Avant de cloner, lisez la licence d'attribution Codetics dans le dépôt : cloner le dépôt vaut acceptation de cette licence. Clonez-le ensuite, puis placez-vous dans le dossier deploy, d'où vous lancerez toutes les commandes suivantes.

    Terminal
    git clone https://github.com/codetics-software/ev-server-lite ev-supervision && cd ev-supervision/deploy

    Ce que vous devez voir Le dossier deploy contient notamment docker-compose.yml, .env.example, server.env.example et le dossier caddy.

04

Configurer l'installation

Toute la configuration tient dans deux fichiers : .env, lu par Docker Compose, et server.env, transmis au serveur. Le reste (adresses internes, mandataires de confiance, port 8080) est déjà réglé dans docker-compose.yml : vous n'avez pas à y toucher.

  1. 4.1Pointer votre domaine vers l'instance

    Chez votre fournisseur DNS, créez un enregistrement qui fait pointer votre nom, par exemple supervision.votre-domaine.fr, vers l'adresse IP publique de l'instance. Faites-le avant le premier démarrage : Caddy en a besoin pour obtenir le certificat Let's Encrypt.

    Ce que vous devez voir La commande ping ou dig sur votre nom renvoie l'adresse publique de l'instance.

  2. 4.2Copier les fichiers d'exemple

    Les deux exemples servent de point de départ, avec des commentaires en français.

    Terminal
    cp .env.example .env
    cp server.env.example server.env
  3. 4.3Remplir .env

    Indiquez votre nom de domaine dans APP_HOST, et dans ACME_EMAIL l'adresse qui recevra les avis de Let's Encrypt. Videz COMPOSE_PROFILES pour utiliser la base gérée, puis renseignez DATABASE_URL avec le point de terminaison privé noté plus tôt, et DATABASE_PASSWORD avec le secret database-password.

    Pour un essai avec la base locale, laissez COMPOSE_PROFILES=local-db et ne définissez pas DATABASE_URL. La ligne OCPP_HOST ne sert qu'aux bornes en profil de sécurité 3 : laissez-la vide.

    deploy/.env
    APP_HOST=<votre-domaine>
    OCPP_HOST=
    ACME_EMAIL=<adresse-exploitation>
    COMPOSE_PROFILES=
    DATABASE_URL=jdbc:postgresql://<point de terminaison privé>:5432/ev_supervision?sslmode=require
    DATABASE_USER=ev_supervision
    DATABASE_PASSWORD=<secret database-password>
    JAVA_TOOL_OPTIONS=-XX:MaxRAMPercentage=75 -XX:+ExitOnOutOfMemoryError
  4. 4.4Remplir server.env

    Le compte administrateur initial se crée au premier démarrage, uniquement si la base ne contient encore aucun utilisateur. BOOTSTRAP_TENANT est l'identifiant de votre espace, que vous saisirez à chaque connexion : remplacez codetics par le vôtre dès maintenant. Choisissez une longue phrase de passe pour BOOTSTRAP_PASSWORD.

    Collez la clé app-encryption-key dans APP_ENCRYPTION_KEY. OCPP_PUBLIC_URL est l'adresse affichée dans la fiche de mise en service des bornes : wss:// suivi de votre domaine et de /ocpp. Les blocs Stripe et courriel restent vides pour l'instant, nous y revenons plus loin.

    deploy/server.env
    BOOTSTRAP_TENANT=<identifiant-espace>
    BOOTSTRAP_EMAIL=<adresse-administrateur>
    BOOTSTRAP_PASSWORD=<longue-phrase-de-passe>
    
    APP_ENCRYPTION_KEY=<secret app-encryption-key>
    OCPP_PUBLIC_URL=wss://<votre-domaine>/ocpp

    Attention Ne copiez pas server.env dans un dépôt Git ni dans un message : il contient vos secrets.

05

Démarrer et se connecter

Le moment que vous attendiez. Le premier démarrage construit les images sur l'instance, il prend donc un peu plus de temps que les suivants.

  1. 5.1Lancer les services

    Depuis le dossier deploy, construisez et démarrez l'ensemble, puis suivez les journaux du serveur. Au premier démarrage, le serveur crée les tables dans la base et le compte administrateur.

    Terminal
    docker compose up -d --build
    docker compose logs -f server

    Ce que vous devez voir Les journaux défilent puis se calment sans erreur. Quittez le suivi avec Ctrl+C : les services continuent de tourner.

  2. 5.2Se connecter au tableau de bord

    Ouvrez https://<votre-domaine>/auth/login dans votre navigateur. L'écran de connexion demande trois choses : l'identifiant de l'espace (votre BOOTSTRAP_TENANT), l'adresse et la phrase de passe de l'administrateur.

    Une fois connecté, ouvrez Espace client pour donner un nom à votre espace et téléverser votre logo. Il apparaîtra dans le tableau de bord et sur le portail de paiement.

    Ce que vous devez voir Le navigateur affiche un cadenas (certificat valide) et vous arrivez dans le tableau de bord de votre espace.

  3. 5.3Retirer les identifiants initiaux

    Le compte existe désormais en base. Supprimez BOOTSTRAP_PASSWORD (et BOOTSTRAP_EMAIL) de server.env, puis relancez pour que le serveur reparte sans eux.

    Terminal
    docker compose up -d --build

    Ce que vous devez voir Vous vous connectez toujours normalement avec votre compte administrateur.

06

Connecter une borne

Une borne ouvre une connexion permanente vers votre serveur et la garde ouverte. Il suffit de lui donner une adresse et un mot de passe.

  1. 6.1Déclarer la borne

    Dans le tableau de bord, ajoutez la borne avec son identifiant. Son mot de passe s'affiche une seule fois : copiez-le aussitôt. Si vous le perdez, la fiche de la borne permet d'en générer un nouveau.

  2. 6.2Configurer la borne

    Dans l'interface de configuration de la borne, choisissez OCPP 1.6 JSON, le sous-protocole ocpp1.6 et l'authentification Basic. <espace> est l'identifiant de votre espace, <identifiant-borne> celui que vous venez de déclarer. L'en-tête Authorization est en général construit par la borne à partir de l'identifiant et du mot de passe que vous saisissez.

    Configuration de la borne
    wss://<votre-domaine>/ocpp/<espace>/<identifiant-borne>
    Authorization: Basic <base64(identifiant-borne:mot-de-passe)>

    Ce que vous devez voir La borne apparaît en ligne dans le tableau de bord. Si elle reste hors ligne, ouvrez son historique : un événement CONNECTION_REJECTED signale un refus, souvent un mot de passe ou une adresse erronés.

07

Paiements avec Stripe

Facultatif. Stripe permet le paiement par QR code sans compte, la facturation des conducteurs et la vente de cartes. Chaque espace connecte son propre compte Stripe, et l'argent arrive directement dessus.

  1. 7.1Ajouter les clés

    Commencez avec les clés de test de Stripe, puis passez aux clés de production une fois tout vérifié. Dans Stripe, créez une destination de notifications pour les comptes connectés, vers l'adresse suivante, avec les sept événements listés. Stripe vous donne alors le secret de signature à placer dans STRIPE_WEBHOOK_SECRET.

    Adresse de notification
    https://<votre-domaine>/api/backend/api/v1/stripe/webhook
    Événements
    checkout.session.completed
    checkout.session.async_payment_succeeded
    checkout.session.async_payment_failed
    checkout.session.expired
    invoice.paid
    invoice.payment_failed
    invoice.finalized
    deploy/server.env
    STRIPE_SECRET_KEY=<clé secrète Stripe>
    STRIPE_WEBHOOK_SECRET=<secret de signature>
    STRIPE_PUBLISHABLE_KEY=<clé publiable Stripe>
  2. 7.2Relancer et activer le paiement public

    Relancez avec docker compose up -d --build. Dans le tableau de bord, créez un tarif en euros dans Tarifs, connectez le compte Stripe de l'espace dans Paiements et terminez la vérification chez Stripe, puis activez les paiements publics.

    Dans Points de charge publics, associez une borne, un connecteur et un tarif, publiez le portail et téléchargez son QR code. Le conducteur le scanne, choisit un crédit entre 5 € et 100 € et paie, sans créer de compte.

    Ce que vous devez voir Dans Stripe, l'onglet des livraisons de la destination montre une notification de test reçue avec succès.

08

Courriels

Facultatif, mais utile : réinitialisation des mots de passe, alertes et notifications passent par courriel.

  1. 8.1Passer par OCI Email Delivery

    Chez Oracle, le port 25 sortant est bloqué par défaut. Utilisez OCI Email Delivery en SMTP sur le port 587 avec STARTTLS. Déclarez SPF, DKIM et DMARC pour l'adresse d'envoi, sinon vos courriels risquent de finir en indésirables.

    Renseignez le bloc courriel de server.env avec le serveur et les identifiants SMTP fournis par Email Delivery, puis relancez avec docker compose up -d --build.

    deploy/server.env
    MAIL_ENABLED=true
    MAIL_FROM=<adresse-envoi>
    SMTP_HOST=<serveur SMTP Email Delivery>
    SMTP_PORT=587
    SMTP_USER=<utilisateur SMTP>
    SMTP_PASSWORD=<mot de passe SMTP>
    SMTP_AUTH=true
    SMTP_STARTTLS=true

    Ce que vous devez voir Demandez une réinitialisation de mot de passe depuis l'écran de connexion : le courriel arrive.

    Attention Le port 25 sortant est bloqué par défaut chez Oracle. N'essayez pas d'envoyer directement, passez par le port 587.

09

Vérifier, sauvegarder, mettre à jour

Votre supervision tourne. Quelques vérifications avant d'y raccorder tout le parc, puis les deux gestes qui la gardent en bonne santé.

  1. 9.1Vérifier depuis Internet

    Lancez ces trois commandes depuis votre poste. Remplacez <votre-domaine> et <espace>. BORNE-INCONNUE peut rester tel quel.

    Terminal
    curl -sSI https://<votre-domaine>/auth/login
    curl -sS -o /dev/null -w '%{http_code}\n' https://<votre-domaine>/actuator/health
    curl --http1.1 -sS -o /dev/null -w '%{http_code}\n' \
      -H 'Connection: Upgrade' -H 'Upgrade: websocket' -H 'Sec-WebSocket-Version: 13' \
      -H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' -H 'Sec-WebSocket-Protocol: ocpp1.6' \
      https://<votre-domaine>/ocpp/<espace>/BORNE-INCONNUE

    Ce que vous devez voir La page de connexion répond 200, /actuator/health répond 404 (il ne doit pas être visible depuis Internet) et la connexion de borne sans identifiants répond 401. Ensuite, une borne de test doit rester connectée plus d'une heure sans reconnexion dans son historique.

  2. 9.2Sauvegarder

    Avec la base gérée, les sauvegardes quotidiennes sont déjà actives. Ajoutez une copie exportée hors de votre compte Oracle, et essayez une restauration au moins une fois par trimestre sur un environnement séparé. Gardez APP_ENCRYPTION_KEY dans le coffre et en copie hors ligne.

    Avec la base locale, la commande suivante produit une copie complète de la base. Conservez-la hors de l'instance.

    Terminal
    docker compose exec postgres pg_dump -U ev_supervision ev_supervision
  3. 9.3Mettre à jour

    Une nouvelle version s'installe en deux temps : récupérer le code, reconstruire. Les migrations de la base s'appliquent au démarrage, alors sauvegardez la base avant chaque mise à jour et choisissez un moment calme.

    Pendant le redémarrage, les bornes se déconnectent puis se reconnectent d'elles-mêmes. Les messages qu'elles ont gardés en attente sont rejoués, sans doublon.

    Terminal
    git pull && docker compose up -d --build

    Ce que vous devez voir Les bornes repassent en ligne dans le tableau de bord après le redémarrage.

10

Les variables que vous réglez

Seulement celles de ce guide. Les fichiers d'exemple en contiennent d'autres (applications mobiles, itinérance, profils de sécurité avancés) que vous pouvez laisser telles quelles.

VariableRôleStatut
APP_HOSTVotre nom de domaine (.env). Sert au tableau de bord, à l'API, aux notifications Stripe et aux bornes.supervision.exemple.frObligatoire
ACME_EMAILAdresse de contact pour les certificats Let's Encrypt (.env).exploitation@exemple.frObligatoire
COMPOSE_PROFILESVide avec la base gérée. local-db démarre PostgreSQL sur l'instance, pour un essai (.env).Obligatoire
DATABASE_URLAdresse de la base gérée (.env). Inutile avec la base locale.jdbc:postgresql://10.0.0.5:5432/ev_supervision?sslmode=requireObligatoire
DATABASE_USERUtilisateur propriétaire de la base (.env).ev_supervisionObligatoire
DATABASE_PASSWORDMot de passe de la base, rangé dans OCI Vault (.env).Obligatoire
BOOTSTRAP_TENANTIdentifiant de l'espace initial, saisi à la connexion. À choisir avant le premier démarrage (server.env).codeticsObligatoire
BOOTSTRAP_EMAILAdresse du premier administrateur (server.env). À retirer après la première connexion.administrateur@exemple.frObligatoire
BOOTSTRAP_PASSWORDPhrase de passe du premier administrateur (server.env). À retirer après la première connexion.Obligatoire
APP_ENCRYPTION_KEYClé de 32 octets aléatoires en Base64 qui chiffre des secrets en base (server.env). Indispensable pour Stripe. Sa perte rend ces données illisibles.Obligatoire
OCPP_PUBLIC_URLAdresse des bornes affichée dans leur fiche de mise en service (server.env).wss://supervision.exemple.fr/ocppFacultative
STRIPE_SECRET_KEYClé secrète Stripe, de test puis de production (server.env).Facultative
STRIPE_WEBHOOK_SECRETSecret de signature de la destination de notifications Stripe (server.env).Facultative
STRIPE_PUBLISHABLE_KEYClé publiable Stripe, nécessaire à l'enregistrement des moyens de paiement des conducteurs (server.env).Facultative
MAIL_ENABLEDActive l'envoi des courriels (server.env).trueFacultative
MAIL_FROMAdresse d'envoi, sur votre domaine (server.env).supervision@exemple.frFacultative
SMTP_HOSTServeur SMTP fourni par OCI Email Delivery (server.env).Facultative
SMTP_PORTPort SMTP. Le port 25 est bloqué chez Oracle (server.env).587Facultative
SMTP_USERUtilisateur SMTP fourni par Email Delivery (server.env).Facultative
SMTP_PASSWORDMot de passe SMTP fourni par Email Delivery (server.env).Facultative
Autres hébergeurs

Un autre hébergeur ? On vous aide

Ce guide couvre Oracle Cloud, avec une seule machine. Vous préférez un autre hébergeur, un cluster Kubernetes, un équilibreur de charge devant l'instance, ou des bornes en profil de sécurité 3 avec certificats clients (mTLS) ? Parlez-nous de votre situation.

Nous pouvons déployer la supervision pour vous, ou vous accompagner pendant que vous l'installez. Dans les deux cas, vous restez propriétaire de votre plateforme.

  • AWS
  • Google Cloud
  • Microsoft Azure
  • OVHcloud
  • Scaleway
  • Hostinger
  • Cloudflare
  • Vercel
  • Votre propre serveur