FrameworksAgents.com Logo

Déployer un agent IA en production

Tutorielcalendar_todayPublié le 20 avril 2026schedule13 min de lecturedéploiement agent iaagent ia prod

Apprenez à déployer un agent IA en production : Docker, VPS, monitoring et sécurité. Tutoriel complet pour un agent stable et autonome.

Introduction

Un agent IA qui tourne sur votre machine locale, c'est une preuve de concept. Un agent qui tourne en production, c'est un outil qui crée de la valeur. La différence entre les deux n'est pas seulement technique — elle impose de penser containerisation, supervision, sécurité et disponibilité.

Dans ce tutoriel, vous apprendrez à prendre un agent Python fonctionnel et à le transformer en service robuste qui tourne 24h/24 sur un VPS. Nous couvrons Docker, la configuration systemd, la gestion des secrets, le monitoring et les bonnes pratiques de sécurité. Pour aller plus loin sur ce dernier point, consultez notre guide dédié pour sécuriser un agent IA en production.

À la fin, vous aurez un agent prêt pour la production — pas une coquille fragile.

Résumé rapide

ÉtapeActionOutil
1Rendre l'agent configurable via variables d'environnementPython os.environ
2Containeriser avec un Dockerfile slimDocker
3Choisir un VPS adapté (2 Go RAM minimum)Hetzner / OVH / Scaleway
4Déployer avec systemd ou Docker restart policysystemd / docker-compose
5Configurer le pare-feu et les secretsUFW, .env
6Mettre en place le monitoring et les alertesHealthcheck, logs

Choisir une option d'hébergement

Avant d'écrire la moindre ligne de configuration, il faut décider l'agent va tourner. Trois grandes familles d'hébergement existent, chacune avec ses compromis.

OptionPour quiAvantagesLimites
VPS (Hetzner, OVH, Scaleway)Agent persistant, tâches longues, coût maîtriséContrôle total, prix fixe, idéal pour un process 24h/24Maintenance OS à votre charge
Serverless (AWS Lambda, Cloud Run, Vercel Functions)Agent déclenché à la demande (webhook, cron)Scaling automatique, facturation à l'usage, zéro maintenance serveurCold start, timeout (souvent 15 min max), mal adapté aux process longs
Conteneurs managés (Cloud Run, ECS Fargate, Railway, Fly.io)Entre les deux : conteneur Docker sans gérer de VMScaling horizontal, déploiement par image, pas de serveur à patcherPlus cher qu'un VPS au repos

Comment trancher ?

  • Un agent qui doit rester éveillé en permanence (surveillance, boucle d'écoute, file de tâches) → VPS ou conteneur managé toujours actif.
  • Un agent déclenché ponctuellement (réponse à un email, traitement d'un fichier uploadé, cron quotidien) → serverless, beaucoup moins cher car vous ne payez que le temps d'exécution.
  • Un agent que vous voulez pouvoir déplacer et scaler facilement sans toucher à un OS → conteneur managé.

Ce tutoriel détaille le scénario le plus courant — un agent persistant sur VPS conteneurisé — mais les principes (configuration externalisée, secrets, monitoring) s'appliquent à toutes les options.

Préparer l'agent pour la production

Externaliser la configuration

La première étape consiste à retirer toutes les valeurs codées en dur. Un agent en production doit être configurable sans modifier le code.

import os

# Clés API — NE JAMAIS hardcoder
api_key = os.environ.get("OPENAI_API_KEY")
model = os.environ.get("MODEL_NAME", "gpt-4o")
max_tokens = int(os.environ.get("MAX_TOKENS", "2000"))

# Configuration du comportement
temperature = float(os.environ.get("TEMPERATURE", "0.7"))
max_steps = int(os.environ.get("MAX_AGENT_STEPS", "10"))

Placez ces variables dans un fichier .env et chargez-le au démarrage :

from dotenv import load_dotenv
load_dotenv()

Règle absolue : le fichier .env doit être dans .gitignore. Ne commitez jamais de clé API.

Prévoir le rechargement sans interruption

Votre agent doit pouvoir être reconfiguré sans redémarrage brutal. Un pattern courant : un fichier de configuration JSON rechargé périodiquement ou sur signal SIGUSR1.

import signal, json

def reload_config(signum, frame):
    with open("agent_config.json") as f:
        config = json.load(f)
    print(f"Configuration rechargée : {config}")

signal.signal(signal.SIGUSR1, reload_config)

Containeriser avec Docker

Le Dockerfile

Choisissez une image Python slim pour minimiser la taille et la surface d'attaque :

FROM python:3.12-slim

WORKDIR /app

# Dépendances système minimales
RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    && rm -rf /var/lib/apt/lists/*

# Dépendances Python
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Code de l'agent
COPY agent.py .

# Utilisateur non-root (sécurité)
RUN useradd -m -u 1000 agent && chown -R agent:agent /app
USER agent

CMD ["python", "agent.py"]

docker-compose pour orchestrer

version: "3.9"
services:
  agent:
    build: .
    restart: unless-stopped
    env_file:
      - .env
    volumes:
      - ./data:/app/data
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - agent_network

networks:
  agent_network:
    driver: bridge

L'option restart: unless-stopped garantit que l'agent redémarre automatiquement après un crash ou un reboot du serveur.

Choisir et configurer le VPS

Ressources minimales

Pour un agent Python léger (pas de modèle local) :

ProviderInstanceRAMvCPUPrix/mois
HetznerCX214 Go2~4 €
OVHStarter2 Go1~3 €
ScalewayDEV1-S2 Go2~3 €

Pour un agent avec modèle local (Llama, Mistral), prévoyez un minimum de 16 Go RAM et un CPU correct — Hetzner AX42 (≈ 20 €/mois) ou équivalent.

Installation de Docker sur le VPS

# Connexion SSH
ssh root@adresse_ip

# Installation Docker
curl -fsSL https://get.docker.com | sh

# Activer Docker au démarrage
systemctl enable docker

# Ajouter l'utilisateur (votre login) au groupe docker
usermod -aG docker $USER

Transférez vos fichiers sur le VPS :

# Depuis votre machine
rsync -avz --exclude='.env' --exclude='.git' ./agent/ user@vps:/home/user/agent/

Déployer et maintenir le service actif

Option 1 : systemd (recommandé pour un seul agent)

Créez un service systemd :

# /etc/systemd/system/agent-ia.service
[Unit]
Description=Agent IA de production
After=network.target

[Service]
Type=simple
User=agent
WorkingDirectory=/home/agent/agent
EnvironmentFile=/home/agent/agent/.env
ExecStart=/usr/bin/python3 /home/agent/agent/agent.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Activez et lancez :

systemctl enable agent-ia
systemctl start agent-ia
journalctl -u agent-ia -f  # suivre les logs en temps réel

Option 2 : Docker directement

Si vous préférez Docker à systemd :

docker run -d \
  --name mon_agent \
  --restart unless-stopped \
  --env-file .env \
  -v $(pwd)/data:/app/data \
  -p 8000:8000 \
  mon_agent:latest

Vérifier que l'agent est vivant

Ajoutez un endpoint healthcheck dans votre agent :

from flask import Flask
app = Flask(__name__)

@app.route("/health")
def health():
    return {"status": "ok", "agent": "production"}

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

Testez depuis l'extérieur :

curl https://votre-domaine.com/health

Sécurité de base

Pare-feu avec UFW

ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 8000/tcp  # uniquement si le healthcheck est exposé
ufw enable

Gestion des secrets

Jamais dans le code ou dans un fichier commité.

# Variables d'environnement uniquement en production
# Le fichier .env reste en LOCAL, ne contient PAS de vraie clé
# Sur le VPS, définissez les variables dans systemd :
Environment=OPENAI_API_KEY=sk-...
Environment=MODEL_NAME=gpt-4o

Pour les environnements critiques, utilisez un gestionnaire de secrets comme Doppler ou HashiCorp Vault. Sur les plateformes managées (Cloud Run, Railway, Fly.io), passez plutôt par leur coffre-fort de secrets natif, qui injecte les variables au runtime sans jamais les écrire sur disque.

Accès SSH

  • Désactivez l'authentification par mot de passe (clés SSH uniquement)
  • Changez le port SSH par défaut (2222 par exemple)
  • Installez fail2ban pour bloquer les tentatives d'attaque par force brute
apt install fail2ban
systemctl enable fail2ban

Monitoring et alertes

Logs structurés

Envoyez les logs dans un format lisible pour l'analyse :

import logging, sys

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(levelname)s %(name)s: %(message)s",
    handlers=[
        logging.FileHandler("/var/log/agent/agent.log"),
        logging.StreamHandler(sys.stdout)
    ]
)

logger = logging.getLogger("agent_ia")
logger.info("Agent démarré", extra={"model": model, "max_steps": max_steps})

Surveillance avec healthcheck

# Script de surveillance
#!/bin/bash
if curl -sf http://localhost:8000/health > /dev/null; then
    echo "OK"
    exit 0
else
    echo "FAIL"
    exit 1
fi

Placez ce script dans /usr/local/bin/agent-healthcheck et exécutez-le depuis systemd :

[Service]
ExecStartPost=/usr/local/bin/agent-healthcheck

Alerte par email en cas de panne

Utilisez un service comme Healthchecks.io ou UptimeRobot pour pinguer votre endpoint /health toutes les minutes. Configurez une alerte email/SMS si le ping échoue pendant 2 minutes.

Scaling : encaisser la montée en charge

Un agent qui répond à une requête à la fois suffit en phase de lancement. Dès que le trafic augmente, il faut prévoir la montée en charge.

Scaling vertical (le plus simple)

Augmentez les ressources de la machine : plus de RAM et de vCPU. C'est immédiat et sans refonte du code, mais limité par le plafond matériel du provider et par le coût d'une grosse instance qui tourne en permanence.

Scaling horizontal (plusieurs instances)

Lancez plusieurs conteneurs identiques derrière un répartiteur de charge (nginx, Traefik, ou le load balancer du provider). Deux conditions pour que cela fonctionne :

  1. L'agent doit être stateless. Aucun état critique en mémoire locale : la conversation, la mémoire de l'agent et la file de tâches vivent dans un service externe (Redis, PostgreSQL).
  2. Le travail doit être distribuable. Pour des tâches longues, passez par une file de messages (Redis Queue, Celery, RabbitMQ) : un producteur empile les tâches, N workers les consomment en parallèle.
# docker-compose : 3 workers consommant une file Redis
services:
  worker:
    build: .
    restart: unless-stopped
    env_file: [.env]
    deploy:
      replicas: 3
    depends_on:
      - redis
  redis:
    image: redis:7-alpine
    restart: unless-stopped

Goulot d'étranglement réel. Pour un agent appuyé sur une API LLM, la limite n'est presque jamais le CPU mais les rate limits du fournisseur (requêtes/minute, tokens/minute). Mettez en place une logique de retry avec back-off exponentiel avant de multiplier les machines.

Maîtriser les coûts LLM

En production, le poste de dépense numéro un d'un agent n'est pas le serveur — c'est la facture de tokens. Quelques leviers concrets :

  • Choisir le bon modèle par tâche. Un modèle léger (gpt-4o-mini, Claude Haiku) pour le routage et la classification ; le gros modèle uniquement pour les étapes qui le justifient. Le rapport de prix entre les deux dépasse souvent un facteur 10.
  • Plafonner les boucles. Un agent qui boucle, c'est une facture qui explose. Imposez un MAX_AGENT_STEPS et un budget de tokens par requête.
  • Mettre en cache. Cachez les réponses aux requêtes identiques ou similaires (clé = hash du prompt). Beaucoup de fournisseurs proposent aussi un prompt caching natif qui réduit fortement le coût des préfixes répétés (system prompt, contexte).
  • Compresser le contexte. N'envoyez pas tout l'historique à chaque appel : résumez les anciens tours, tronquez les documents, n'injectez que le strict nécessaire.
  • Suivre la dépense. Loguez prompt_tokens et completion_tokens à chaque appel et agrégez-les. Posez une alerte sur un seuil quotidien.
resp = client.chat.completions.create(model=model, messages=messages)
usage = resp.usage
logger.info(
    "Appel LLM",
    extra={
        "prompt_tokens": usage.prompt_tokens,
        "completion_tokens": usage.completion_tokens,
        "total_tokens": usage.total_tokens,
    },
)

CI/CD : déployer automatiquement

Plutôt que de transférer le code à la main à chaque modification, automatisez le déploiement avec un pipeline d'intégration et de déploiement continus. Exemple minimal avec GitHub Actions : à chaque push sur main, on construit l'image, on la pousse vers le registre, puis on redéploie sur le VPS via SSH.

# .github/workflows/deploy.yml
name: Deploy agent
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Lancer les tests
        run: |
          pip install -r requirements.txt
          pytest

      - name: Construire et pousser l'image
        run: |
          echo "${{ secrets.REGISTRY_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
          docker build -t ghcr.io/${{ github.repository }}:latest .
          docker push ghcr.io/${{ github.repository }}:latest

      - name: Redéployer sur le VPS
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /home/agent/agent
            docker compose pull
            docker compose up -d

Les secrets (SSH_PRIVATE_KEY, VPS_HOST, token de registre) se définissent dans Settings → Secrets and variables → Actions de votre dépôt — jamais dans le YAML. Faites systématiquement passer les tests avant le déploiement : un pipeline qui déploie du code cassé est pire que pas de pipeline du tout.

Checklist de mise en production

Avant de considérer l'agent comme « en prod », vérifiez chaque point :

  • Aucune valeur sensible codée en dur ; configuration via variables d'environnement.
  • .env dans .gitignore ; secrets injectés au runtime (systemd, coffre-fort, secrets CI).
  • Dockerfile basé sur une image slim, exécution en utilisateur non-root.
  • Politique de redémarrage automatique (restart: unless-stopped ou Restart=always).
  • Endpoint /health exposé et surveillé par un service externe (UptimeRobot, Healthchecks.io).
  • Logs structurés persistés et consultables (journalctl ou docker logs).
  • Pare-feu actif (UFW), SSH par clé uniquement, fail2ban installé.
  • Plafonds en place : MAX_AGENT_STEPS, budget de tokens, retry avec back-off.
  • Suivi des coûts LLM (tokens logués) et alerte sur seuil quotidien.
  • Procédure de mise à jour testée (rollback possible vers l'image précédente).
  • Sauvegarde des données persistantes (./data, base, mémoire de l'agent).

Tableau comparatif : systemd vs Docker restart

CritèresystemdDocker restart
SimplicitéBon pour 1 agentBon pour plusieurs services
PortabilitéLié à la machinePortable entre machines
Supervisionjournalctl natifdocker logs
NetworkingConfig réseau standardNetwork mode intégré
Mise à joursystemctl restartdocker pull && docker-compose up -d

Pour un seul agent, systemd est souvent le choix le plus simple et le plus robuste.

Questions fréquentes

Comment mettre à jour l'agent sans interruption de service ?

Avec Docker : docker pull télécharge la nouvelle image, puis docker-compose up -d --no-deps agent remplace le conteneur. Le flag --no-deps évite de redémarrer les services dépendants.

Avec systemd : modifiez le code, transférez via rsync, puis systemctl restart agent-ia.

Un agent IA peut-il tourner sur un Raspberry Pi ?

Un agent utilisant une API externe (OpenAI, Anthropic) oui, sans problème. Un agent avec modèle local (Llama 3) nécessite un GPU ou beaucoup de RAM — pas adapté au Pi. Dans ce cas, hébergez le modèle sur une machine séparée et connectez l'agent via API.

Comment éviter d'exposer mes clés API sur le serveur ?

Définissez les variables d'environnement dans la configuration du service (systemd Environment=) ou utilisez un gestionnaire de secrets. Le fichier .env reste en local et n'est jamais transféré sur le VPS.

Comment dimensionner le VPS ?

Commencez avec 2 Go RAM / 1 vCPU pour un agent avec API externe. Surveillez avec htop après déploiement. En cas de fuite mémoire ou de charge élevée, montez à 4 Go. Pour un modèle local, partez sur 16 Go minimum.

Articles liés

Déployer un agent en production n'est que la dernière étape. Avant d'en arriver là, il faut avoir construit l'agent lui-même. Le pilier de ce tutoriel est la création d'agent — maîtriser ce processus est un prérequis indispensable.

Votre agent tourne désormais en continu. L'étape suivante logique consiste à lui confier des tâches métier récurrentes : veille concurrentielle, génération de contenu, qualification de leads. L'automatisation par agents IA est le terrain de jeu naturel de ce type de déploiement.

Restez informé sur les agents IA

Nouveaux tutoriels, comparatifs et guides pratiques directement dans votre boîte mail.

homeAccueilcodeFrameworkssmart_toyAgentsmenu_bookTutorielsTwitter