Guide13 mars 2026

Installation Odoo 19 prête pour
la production

INTRODUCTION

Votre installation Odoo n'est pas « terminée » quand la page de connexion s'affiche

Chaque déploiement Odoo commence par une installation. Et chaque incident de production que nous avons investigué chez Octura commence par une installation qui était « suffisante pour le moment ». La page de connexion s'affichait, les données de démonstration se chargeaient, et quelqu'un déclarait que c'était terminé. Six mois plus tard : la base de données ne supporte pas 50 utilisateurs simultanés, les sauvegardes n'ont jamais été testées, et le serveur tourne en root avec le mot de passe maître par défaut.

Odoo 19 a relevé la barre. Le runtime exige désormais PostgreSQL 15+, embarque une gestion de sessions werkzeug plus stricte, et le pipeline d'assets attend rtlcss et wkhtmltopdf 0.12.7 à des chemins spécifiques. Installez-le mal et vous obtiendrez des erreurs 500 cryptiques sur les rapports PDF, des expirations de session sous charge, et un système qui se dégrade silencieusement quand vous en avez le plus besoin.

Ce guide couvre trois méthodes d'installation — Docker, installation depuis les sources, et Odoo.sh — avec les étapes de durcissement production qui distinguent un jouet de staging d'un système sur lequel vous pouvez parier vos opérations.

01

Docker vs Source vs Odoo.sh : quelle méthode d'installation Odoo 19 convient à votre équipe

Il n'existe pas de méthode « universelle » pour installer Odoo. Le bon choix dépend de la maturité opérationnelle de votre équipe, de vos exigences de conformité, et du nombre de modules personnalisés que vous exploitez. Voici la comparaison honnête :

AspectDockerInstallation sourceOdoo.sh
Temps de mise en place15 minutes45 à 90 minutes5 minutes
Modules personnalisésVolume monté ou image customAccès complet au système de fichiersSous-modules Git uniquement
Contrôle PostgreSQLConteneur séparé, configurableContrôle total, toute versionGéré (paramétrage limité)
ScalabilitéHorizontale via orchestrationConfiguration multi-workers manuelleIntégrée (avec limites du plan)
SSL / ProxyReverse proxy requisNginx / Caddy requisInclus
SauvegardesÀ votre charge (pg_dump + filestore)À votre charge (pg_dump + filestore)Automatique quotidienne
CoûtVotre infrastructure uniquementVotre infrastructure uniquementÀ partir de 32 $/mois + licence Odoo
Idéal pourÉquipes avec capacité DevOpsPersonnalisation poussée, industries réglementéesPME souhaitant des opérations managées
Notre recommandation

Pour la plupart des entreprises de taille intermédiaire, Docker avec un service PostgreSQL managé (AWS RDS, Google Cloud SQL, ou DigitalOcean Managed DB) offre le meilleur compromis. Vous obtenez des déploiements reproductibles sans gérer vous-même les sauvegardes, la réplication et le basculement de la base de données. L'installation depuis les sources est réservée aux clients dans des secteurs réglementés qui nécessitent une auditabilité au niveau du noyau.

02

Docker Compose de niveau production pour Odoo 19 : la stack complète

L'image Docker officielle d'Odoo vous amène à un écran de connexion. Elle ne vous amène pas en production. Voici le docker-compose.yml que nous utilisons comme point de départ pour les déploiements clients — avec le tuning PostgreSQL, des volumes persistants, des limites de ressources appropriées et un durcissement sécurité.

YAML — docker-compose.yml
version: "3.8"

services:
  odoo:
    image: odoo:19.0
    container_name: odoo19
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "127.0.0.1:8069:8069"
      - "127.0.0.1:8072:8072"  # longpolling / websocket
    volumes:
      - odoo-data:/var/lib/odoo
      - ./custom-addons:/mnt/extra-addons:ro
      - ./config/odoo.conf:/etc/odoo/odoo.conf:ro
    environment:
      - HOST=db
      - USER=odoo
      - PASSWORD_FILE=/run/secrets/db_password
    secrets:
      - db_password
    deploy:
      resources:
        limits:
          memory: 4G
          cpus: "2.0"

  db:
    image: postgres:16-alpine
    container_name: odoo19-db
    restart: unless-stopped
    environment:
      - POSTGRES_USER=odoo
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
      - POSTGRES_DB=postgres
    volumes:
      - pg-data:/var/lib/postgresql/data
      - ./config/postgresql.conf:/etc/postgresql/postgresql.conf:ro
    command: postgres -c config_file=/etc/postgresql/postgresql.conf
    secrets:
      - db_password
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U odoo"]
      interval: 10s
      timeout: 5s
      retries: 5
    deploy:
      resources:
        limits:
          memory: 2G

secrets:
  db_password:
    file: ./secrets/db_password.txt

volumes:
  odoo-data:
  pg-data:

Détails clés que la plupart des tutoriels omettent :

  • Ports liés à 127.0.0.1 — n'exposez jamais Odoo directement à internet. Nginx ou Caddy se place devant.
  • Docker secrets pour le mot de passe de la base — pas des variables d'environnement qui fuient dans la sortie de docker inspect.
  • Health check sur PostgreSQL — Odoo n'entrera pas en boucle de crash en attendant un démarrage lent de la base.
  • Addons personnalisés montés en lecture seule — empêche les écritures accidentelles par le processus Odoo.
  • Limites mémoire — sans elles, une génération de rapport incontrôlée provoquera un OOM-kill de tout l'hôte.
INI — config/odoo.conf
[options]
; ── Security ──────────────────────────────────
admin_passwd = False
list_db = False
proxy_mode = True

; ── Performance ───────────────────────────────
workers = 4
max_cron_threads = 2
limit_memory_hard = 2684354560
limit_memory_soft = 2147483648
limit_time_cpu = 600
limit_time_real = 1200
limit_time_real_cron = 1800

; ── Database ──────────────────────────────────
db_host = db
db_port = 5432
db_user = odoo
db_name = production
dbfilter = ^production$

; ── Paths ─────────────────────────────────────
addons_path = /mnt/extra-addons,/usr/lib/python3/dist-packages/odoo/addons
data_dir = /var/lib/odoo
Pourquoi admin_passwd = False

Définir admin_passwd = False désactive entièrement le gestionnaire de base de données. C'est non négociable en production. Le gestionnaire de base de données permet à quiconque de créer, dupliquer, supprimer ou restaurer des bases — avec un seul mot de passe protégeant l'ensemble de l'opération. Combiné avec list_db = False et dbfilter, cela verrouille l'instance sur une seule base de données sans surface de gestion web.

03

Installer Odoo 19 depuis les sources sur Ubuntu 24.04 : étape par étape avec durcissement sécurité

L'installation depuis les sources vous donne un contrôle total. C'est aussi la plus facile à mal configurer. Voici la séquence que nous suivons pour les déploiements bare-metal et VM.

Dépendances système

Bash — Paquets système
# System user — never run Odoo as root
sudo adduser --system --home=/opt/odoo --group odoo

# PostgreSQL 16
sudo apt install -y postgresql-16 postgresql-client-16

# Create DB role (no superuser, no createdb in production)
sudo -u postgres createuser --createdb --no-superuser \
  --no-createrole odoo

# Python build deps + Odoo runtime deps
sudo apt install -y \
  python3-dev python3-pip python3-venv \
  libxml2-dev libxslt1-dev libldap2-dev libsasl2-dev \
  libpq-dev libjpeg-dev zlib1g-dev \
  node-less npm git

# wkhtmltopdf 0.12.7 (Odoo 19 requirement)
wget https://github.com/wkhtmltopdf/packaging/releases/\
download/0.12.7-1/wkhtmltox_0.12.7-1.jammy_amd64.deb
sudo dpkg -i wkhtmltox_0.12.7-1.jammy_amd64.deb
sudo apt install -f -y

# rtlcss for RTL language support
sudo npm install -g rtlcss

Cloner et configurer

Bash — Installation source Odoo
# Clone Odoo 19 (shallow clone saves ~2GB)
sudo -u odoo git clone --depth 1 --branch 19.0 \
  https://github.com/odoo/odoo.git /opt/odoo/odoo

# Virtual environment (isolated from system Python)
sudo -u odoo python3 -m venv /opt/odoo/venv
sudo -u odoo /opt/odoo/venv/bin/pip install --upgrade pip wheel
sudo -u odoo /opt/odoo/venv/bin/pip install \
  -r /opt/odoo/odoo/requirements.txt

# Enterprise (if licensed)
sudo -u odoo git clone --depth 1 --branch 19.0 \
  https://github.com/odoo/enterprise.git /opt/odoo/enterprise

# Custom addons
sudo mkdir -p /opt/odoo/custom-addons
sudo chown odoo:odoo /opt/odoo/custom-addons

Service Systemd

INI — /etc/systemd/system/odoo.service
[Unit]
Description=Odoo 19
After=postgresql.service
Requires=postgresql.service

[Service]
Type=simple
User=odoo
Group=odoo
ExecStart=/opt/odoo/venv/bin/python /opt/odoo/odoo/odoo-bin \
  -c /etc/odoo/odoo.conf
StandardOutput=journal
StandardError=journal

# Security hardening
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/odoo/.local /var/log/odoo
NoNewPrivileges=true
PrivateTmp=true

# Restart policy
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
Sécurité Systemd

Les directives ProtectSystem=strict et NoNewPrivileges=true rendent l'intégralité du système de fichiers en lecture seule pour le processus Odoo, sauf les chemins explicitement autorisés. C'est de la défense en profondeur : même si un attaquant obtient l'exécution de code via une vulnérabilité dans un module personnalisé, il ne peut ni modifier les binaires système ni escalader ses privilèges.

Reverse Proxy Nginx

Nginx — /etc/nginx/sites-available/odoo
upstream odoo_backend {
    server 127.0.0.1:8069;
}
upstream odoo_longpoll {
    server 127.0.0.1:8072;
}

server {
    listen 443 ssl http2;
    server_name erp.yourcompany.com;

    ssl_certificate     /etc/letsencrypt/live/erp.yourcompany.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/erp.yourcompany.com/privkey.pem;

    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;

    # Odoo request size (large imports, attachments)
    client_max_body_size 256m;

    # Timeouts for long operations (reports, exports)
    proxy_read_timeout 720s;
    proxy_connect_timeout 720s;
    proxy_send_timeout 720s;

    location / {
        proxy_pass http://odoo_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_redirect off;
    }

    location /websocket {
        proxy_pass http://odoo_longpoll;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # Block database manager from outside
    location ~* ^/web/database {
        deny all;
        return 404;
    }

    # Static file caching
    location ~* /web/static/ {
        proxy_pass http://odoo_backend;
        expires 365d;
        add_header Cache-Control "public, immutable";
    }
}
04

3 erreurs d'installation qui paralysent Odoo 19 en production

1

Tourner avec workers = 0 (mode mono-thread)

Le odoo.conf par défaut est livré avec workers = 0, ce qui exécute Odoo en mode mono-thread. Cela signifie qu'une seule génération de rapport lente bloque tous les autres utilisateurs. Un export PDF qui prend 30 secondes verrouille l'application entière pour les 50 utilisateurs. Nous avons vu des entreprises fonctionner ainsi pendant des mois, accusant « Odoo est lent » alors que le vrai coupable était un paramètre par défaut prévu pour le développement.

Notre correctif

Définissez workers = (nb coeurs CPU * 2) + 1 comme base. Pour un serveur 4 coeurs, cela donne 9 workers. Puis configurez max_cron_threads = 2 séparément pour que les actions planifiées ne volent pas de slots aux workers HTTP. Surveillez avec htop aux heures de pointe et ajustez jusqu'à ce que le CPU reste sous 70 %.

2

PostgreSQL avec les paramètres par défaut

Une installation fraîche de PostgreSQL 16 alloue 128 Mo de shared buffers — suffisant pour un blog personnel, pas pour un ERP gérant 10 000 écritures comptables. Nous trouvons régulièrement des serveurs Odoo où la base de données est le goulot d'étranglement, mais personne n'a vérifié pg_stat_user_tables parce que « la base a été configurée par l'hébergeur ».

Notre correctif

Tuning minimum pour une base Odoo de production sur un serveur 16 Go de RAM : shared_buffers = 4GB, effective_cache_size = 12GB, work_mem = 64MB, maintenance_work_mem = 1GB. Utilisez PGTune comme point de départ, puis profilez avec pg_stat_statements pour trouver les vraies requêtes lentes.

3

Aucune stratégie de sauvegarde automatisée

« On mettra en place les sauvegardes après la mise en production » est la phrase la plus coûteuse du déploiement ERP. Le filestore Odoo (pièces jointes, images, rapports) vit sur le disque en dehors de PostgreSQL. Un pg_dump seul restaure une base avec des liens de pièces jointes cassés. Nous avons été appelés pour des situations de récupération où une entreprise avait perdu 6 mois de bons de commande uploadés parce que personne n'avait sauvegardé /var/lib/odoo/filestore.

Notre correctif

Nous déployons un cron qui exécute pg_dump et rsync du répertoire filestore vers un stockage distant (S3, Backblaze B2, ou un serveur séparé). Les sauvegardes sont chiffrées avec gpg, la rétention est de 30 quotidiennes + 12 mensuelles, et nous lançons un test de restauration mensuel sur un serveur de staging pour prouver que la sauvegarde fonctionne réellement. Une sauvegarde non testée n'est pas une sauvegarde.

ROI BUSINESS

Ce qu'une installation correcte fait économiser à votre entreprise

L'installation n'est pas un coût ponctuel — c'est la fondation qui détermine votre coût total de possession. Voici ce que nous observons sur le terrain :

60 %De tickets « Odoo est lent » en moins

Une configuration correcte des workers et le tuning PostgreSQL éliminent la plainte n°1 des déploiements Odoo.

0 $De coût de récupération de données

Des sauvegardes automatisées et testées signifient que vous ne payez jamais de récupération d'urgence — qui coûte en moyenne entre 5 000 et 25 000 $.

4 hTemps moyen de déploiement

Avec des templates Docker Compose, les nouveaux environnements sont opérationnels en heures au lieu du processus manuel de 2 à 3 jours.

Le vrai ROI ne réside pas dans l'installation elle-même — il est dans les incidents qui ne se produisent jamais. Chaque décision de configuration ci-dessus — de NoNewPrivileges dans systemd à admin_passwd = False dans odoo.conf — supprime un mode de défaillance qui vous coûterait autrement des heures d'indisponibilité, des tickets de support, ou pire : une faille de sécurité qui érode la confiance de vos clients.

NOTES SEO

Métadonnées d'optimisation

Meta Desc

Installation Odoo 19 prête pour la production via Docker et source. Couvre le tuning PostgreSQL, le durcissement sécurité, la configuration Nginx et la stratégie de sauvegarde.

Mots-clés H2

1. « Docker vs Source vs Odoo.sh : quelle méthode d'installation Odoo 19 convient à votre équipe »
2. « Docker Compose de niveau production pour Odoo 19 : la stack complète »
3. « 3 erreurs d'installation qui paralysent Odoo 19 en production »

Ne laissez pas l'infrastructure devenir votre goulot d'étranglement

Une installation Odoo qui « fonctionne » et une installation Odoo prête pour la production sont deux choses différentes. La première vous donne une page de connexion. La seconde vous donne une plateforme qui absorbe la croissance, survit aux pannes, et ne réveille personne à 3 h du matin.

Si vous déployez Odoo 19 en production — ou si vous soupçonnez que votre installation actuelle tient grâce aux paramètres par défaut et à la chance — parlons-en. Nous réalisons des audits d'infrastructure couvrant la configuration serveur, les performances PostgreSQL, l'intégrité des sauvegardes et la posture de sécurité. L'audit prend une journée. La tranquillité d'esprit dure des années.

Réserver un audit infrastructure gratuit