[{"data":1,"prerenderedAt":696},["ShallowReactive",2],{"\u002Fv5\u002Fadministrer\u002Fexploitation\u002Fprocessus-unique":3,"section:\u002Fv5\u002Fadministrer\u002Fexploitation\u002Fprocessus-unique":695},{"id":4,"title":5,"body":6,"description":678,"extension":679,"meta":680,"navigation":687,"path":691,"seo":692,"stem":693,"__hash__":694},"docs\u002F1.v5\u002F5.administrer\u002F03.exploitation\u002F17.processus-unique.md","Lancer le web, le temps réel et les tâches dans un seul processus",{"type":7,"value":8,"toc":668},"minimark",[9,13,20,23,36,48,53,88,95,99,106,149,160,174,206,213,217,428,431,435,506,516,520,523,572,578,581,585,588,591,595,608,614,618,664],[10,11,5],"h1",{"id":12},"lancer-le-web-le-temps-réel-et-les-tâches-dans-un-seul-processus",[14,15,16],"blockquote",{},[17,18,19],"p",{},"S'applique à : auto-hébergé, Dokos v5.",[17,21,22],{},"Le mode « processus unique » démarre un seul processus qui sert :",[24,25,26,30,33],"ul",{},[27,28,29],"li",{},"l'application web ;",[27,31,32],{},"le temps réel (notifications en direct, Socket.IO) ;",[27,34,35],{},"les tâches de fond et le planificateur.",[17,37,38,39,43,44,47],{},"Il n'y a ni Gunicorn, ni processus Node.js, ni worker séparé à superviser. Ce mode convient à un petit site ou à un site d'essai. Le code ne l'interdit pas en production, mais l'outil ",[40,41,42],"code",{},"bench"," ne génère pas de configuration Supervisor ni Nginx pour ce mode (",[40,45,46],{},"bench setup production"," configure toujours Gunicorn, le serveur Node.js et des workers séparés) : en production, vous écrivez et maintenez vous-même le service qui lance ce processus. Il est facultatif : un bench existant n'est pas modifié tant que vous ne lancez pas cette commande.",[49,50,52],"h2",{"id":51},"prérequis","Prérequis",[24,54,55,62,73],{},[27,56,57,58,61],{},"Un bench installé avec un site fonctionnel, et les services Redis du bench démarrés (le temps réel et les tâches de fond s'appuient sur ",[40,59,60],{},"redis_queue",").",[27,63,64,65,68,69,72],{},"Le serveur web est démarré par ",[40,66,67],{},"uvicorn",", avec la dépendance ",[40,70,71],{},"a2wsgi",", toutes deux installées avec Dodock.",[27,74,75,76,79,80,83,84,87],{},"Pour l'option ",[40,77,78],{},"--dev"," : le paquet ",[40,81,82],{},"watchdog",", installé avec ",[40,85,86],{},"pip install 'frappe[dev]'",".",[17,89,90,91,94],{},"N'exécutez pas en même temps ",[40,92,93],{},"bench start",", Gunicorn ou des workers sur le même bench : ils feraient double emploi avec ce processus.",[49,96,98],{"id":97},"démarrer-le-processus","Démarrer le processus",[17,100,101,102,105],{},"Depuis le dossier ",[40,103,104],{},"sites"," du bench :",[107,108,113],"pre",{"className":109,"code":110,"language":111,"meta":112,"style":112},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","cd sites\n..\u002Fenv\u002Fbin\u002Fpython -m frappe.runner --port 8000\n","bash","",[40,114,115,128],{"__ignoreMap":112},[116,117,120,124],"span",{"class":118,"line":119},"line",1,[116,121,123],{"class":122},"s2Zo4","cd",[116,125,127],{"class":126},"sfazB"," sites\n",[116,129,131,133,136,139,142,145],{"class":118,"line":130},2,[116,132,87],{"class":122},[116,134,135],{"class":126},".\u002Fenv\u002Fbin\u002Fpython",[116,137,138],{"class":126}," -m",[116,140,141],{"class":126}," frappe.runner",[116,143,144],{"class":126}," --port",[116,146,148],{"class":147},"sbssI"," 8000\n",[17,150,151,152,155,156,159],{},"Le processus écoute par défaut sur ",[40,153,154],{},"127.0.0.1:8000",". Pour le rendre accessible depuis un reverse proxy sur une autre machine, ajoutez ",[40,157,158],{},"--host 0.0.0.0"," et protégez le port.",[17,161,162,166,167,170,171,87],{},[163,164,165],"strong",{},"Exemple fictif"," : un site d'essai doit tourner sur un petit serveur, avec deux tâches de fond en parallèle et un reverse proxy local qui sert déjà ",[40,168,169],{},"\u002Fassets"," et ",[40,172,173],{},"\u002Ffiles",[107,175,177],{"className":109,"code":176,"language":111,"meta":112,"style":112},"cd sites\n..\u002Fenv\u002Fbin\u002Fpython -m frappe.runner --port 8000 --job-threads 2\n",[40,178,179,185],{"__ignoreMap":112},[116,180,181,183],{"class":118,"line":119},[116,182,123],{"class":122},[116,184,127],{"class":126},[116,186,187,189,191,193,195,197,200,203],{"class":118,"line":130},[116,188,87],{"class":122},[116,190,135],{"class":126},[116,192,138],{"class":126},[116,194,141],{"class":126},[116,196,144],{"class":126},[116,198,199],{"class":147}," 8000",[116,201,202],{"class":126}," --job-threads",[116,204,205],{"class":147}," 2\n",[17,207,208,209,212],{},"Le site répond sur le port 8000, les notifications en direct passent par le même port (chemin ",[40,210,211],{},"\u002Fsocket.io",") et deux tâches de fond peuvent s'exécuter en même temps.",[49,214,216],{"id":215},"options","Options",[218,219,220,236],"table",{},[221,222,223],"thead",{},[224,225,226,230,233],"tr",{},[227,228,229],"th",{},"Option",[227,231,232],{},"Valeur par défaut",[227,234,235],{},"Effet",[237,238,239,255,270,283,298,318,334,346,364,381,398,413],"tbody",{},[224,240,241,247,252],{},[242,243,244],"td",{},[40,245,246],{},"--host",[242,248,249],{},[40,250,251],{},"127.0.0.1",[242,253,254],{},"Adresse d'écoute",[224,256,257,262,267],{},[242,258,259],{},[40,260,261],{},"--port",[242,263,264],{},[40,265,266],{},"8000",[242,268,269],{},"Port d'écoute",[224,271,272,277,280],{},[242,273,274],{},[40,275,276],{},"--queue",[242,278,279],{},"toutes les files",[242,281,282],{},"Files d'attente à traiter, séparées par des virgules",[224,284,285,290,295],{},[242,286,287],{},[40,288,289],{},"--job-threads",[242,291,292],{},[40,293,294],{},"1",[242,296,297],{},"Nombre de tâches de fond exécutées en même temps",[224,299,300,305,315],{},[242,301,302],{},[40,303,304],{},"--web-threads",[242,306,307,310,311,314],{},[40,308,309],{},"0"," (valeur de ",[40,312,313],{},"FRAPPE_WEB_THREADS",", soit 8 sans variable)",[242,316,317],{},"Nombre de requêtes web simultanées",[224,319,320,324,327],{},[242,321,322],{},[40,323,78],{},[242,325,326],{},"désactivé",[242,328,329,330,170,332],{},"Recharge le processus quand un fichier Python d'une application change, et sert aussi ",[40,331,169],{},[40,333,173],{},[224,335,336,341,343],{},[242,337,338],{},[40,339,340],{},"--verbose",[242,342,326],{},[242,344,345],{},"Journalise chaque tâche et chaque paquet temps réel",[224,347,348,353,358],{},[242,349,350],{},[40,351,352],{},"--restart-after-requests",[242,354,355],{},[40,356,357],{},"5000",[242,359,360,361,363],{},"Redémarrage après ce nombre de requêtes web réussies (",[40,362,309],{}," : jamais)",[224,365,366,371,376],{},[242,367,368],{},[40,369,370],{},"--restart-after-jobs",[242,372,373],{},[40,374,375],{},"500",[242,377,378,379,363],{},"Redémarrage après ce nombre de tâches (",[40,380,309],{},[224,382,383,388,393],{},[242,384,385],{},[40,386,387],{},"--restart-idle-seconds",[242,389,390],{},[40,391,392],{},"300",[242,394,395,396,363],{},"Redémarrage après ce délai sans requête web, une fois du travail effectué (",[40,397,309],{},[224,399,400,405,410],{},[242,401,402],{},[40,403,404],{},"--request-drain-seconds",[242,406,407],{},[40,408,409],{},"60",[242,411,412],{},"Temps d'attente des requêtes en cours à l'arrêt",[224,414,415,420,425],{},[242,416,417],{},[40,418,419],{},"--job-drain-seconds",[242,421,422],{},[40,423,424],{},"600",[242,426,427],{},"Temps d'attente d'une tâche en cours à l'arrêt",[17,429,430],{},"Un processus qui n'a encore rien traité ne redémarre pas pour cause d'inactivité. Le redémarrage n'a lieu que lorsqu'aucune requête ni tâche n'est en cours.",[49,432,434],{"id":433},"variables-denvironnement","Variables d'environnement",[218,436,437,446],{},[221,438,439],{},[224,440,441,444],{},[227,442,443],{},"Variable",[227,445,235],{},[237,447,448,460,489],{},[224,449,450,454],{},[242,451,452],{},[40,453,313],{},[242,455,456,457,459],{},"Nombre de requêtes web simultanées (8 par défaut). L'option ",[40,458,304],{}," la remplace.",[224,461,462,467],{},[242,463,464],{},[40,465,466],{},"FRAPPE_SERVE_ASSETS",[242,468,469,470,170,472,474,475,477,478,480,481,484,485,488],{},"Si elle est vraie, le processus sert aussi ",[40,471,169],{},[40,473,173],{},", comme lorsqu'aucun reverse proxy ne s'en charge. L'option ",[40,476,78],{}," l'active. La route ",[40,479,173],{}," ne sert que les fichiers publics du site (",[40,482,483],{},"sites\u002F\u003Csite>\u002Fpublic\u002Ffiles","). Les fichiers privés restent servis par l'application sous ",[40,486,487],{},"\u002Fprivate\u002Ffiles",", avec contrôle des droits.",[224,490,491,496],{},[242,492,493],{},[40,494,495],{},"FRAPPE_PRELOAD_MODULES",[242,497,498,499,501,502,505],{},"À ",[40,500,309],{}," ou ",[40,503,504],{},"false",", désactive l'import anticipé des modules courants au démarrage, pour économiser de la mémoire. Cette variable s'applique aussi au serveur web Gunicorn habituel.",[17,507,508,509,511,512,170,514,87],{},"Sans reverse proxy et sans ",[40,510,466],{},", les feuilles de style, scripts et fichiers ne sont pas servis. Pour un usage derrière Nginx, laissez Nginx servir ",[40,513,169],{},[40,515,173],{},[49,517,519],{"id":518},"arrêter-redémarrer-recharger","Arrêter, redémarrer, recharger",[17,521,522],{},"Le processus réagit à trois signaux :",[218,524,525,534],{},[221,526,527],{},[224,528,529,532],{},[227,530,531],{},"Signal",[227,533,235],{},[237,535,536,554,564],{},[224,537,538,546],{},[242,539,540,501,543],{},[40,541,542],{},"SIGTERM",[40,544,545],{},"SIGINT",[242,547,548,549,170,551,553],{},"Arrêt propre : les nouvelles requêtes sont refusées, les requêtes et les tâches en cours vont à leur terme (dans la limite des délais ",[40,550,404],{},[40,552,419],{},"), puis le processus s'arrête",[224,555,556,561],{},[242,557,558],{},[40,559,560],{},"SIGHUP",[242,562,563],{},"Redémarrage propre : même arrêt, puis le processus se relance avec la même commande et le même numéro de processus (PID)",[224,565,566,569],{},[242,567,568],{},"Second signal d'arrêt",[242,570,571],{},"Arrêt immédiat",[17,573,574,575,577],{},"Les clients du temps réel sont déconnectés à l'arrêt, puis se reconnectent automatiquement quand le processus est reparti. Un ",[40,576,560],{}," reçu pendant un arrêt ne relance pas le processus.",[17,579,580],{},"Avec systemd, le processus peut reprendre le port d'écoute que systemd lui transmet (activation par socket, un seul descripteur) : les connexions attendent dans la file du socket pendant un redémarrage.",[49,582,584],{"id":583},"planificateur-et-tâches","Planificateur et tâches",[17,586,587],{},"Le planificateur tourne dans un fil du processus. Il utilise le même verrou que le planificateur habituel du bench : si un autre planificateur est déjà actif sur le bench, celui du processus s'arrête aussitôt. Ne cumulez donc pas ce mode avec un planificateur lancé ailleurs sur le même bench.",[17,589,590],{},"Les tâches de fond s'exécutent dans des fils du processus et non dans des processus séparés. Une tâche en cours n'est pas interrompue de force par une demande d'arrêt.",[49,592,594],{"id":593},"mode-développement","Mode développement",[17,596,597,598,600,601,604,605,607],{},"Avec ",[40,599,78],{},", le processus surveille les fichiers ",[40,602,603],{},".py"," des applications installées et se recharge environ une seconde après le dernier enregistrement. Les fichiers JavaScript ne déclenchent pas de rechargement. Sans ",[40,606,82],{},", la commande s'arrête avec un message d'erreur.",[17,609,610,611,613],{},"N'utilisez pas ",[40,612,78],{}," en production.",[49,615,617],{"id":616},"à-savoir","À savoir",[24,619,620,627,649,657],{},[27,621,622,623,626],{},"La configuration du temps réel vient de ",[40,624,625],{},"common_site_config.json",", comme pour le serveur temps réel séparé. Dans ce mode, les vérifications d'autorisation du temps réel appellent l'application web directement, sans passer par une requête HTTP vers le port.",[27,628,629,630,633,634,501,637,640,641,644,645,648],{},"La clé ",[40,631,632],{},"socketio_backend"," de la configuration (",[40,635,636],{},"node",[40,638,639],{},"python",") indique seulement quel serveur temps réel séparé le bench utilise. Dodock la copie dans ",[40,642,643],{},"frappe.boot"," au démarrage de la session, mais aucun code de Dodock v5 ne la lit côté navigateur. Elle n'active pas ce mode processus unique : seule la commande ",[40,646,647],{},"frappe.runner"," le fait.",[27,650,651,652,87],{},"Un seul processus partage la mémoire et le processeur entre le web, le temps réel et les tâches : une tâche longue peut ralentir les requêtes. Pour un site à fort trafic, utilisez l'architecture habituelle décrite dans ",[653,654,656],"a",{"href":655},"\u002Fv5\u002Fdodock\u002Fdeveloppeurs\u002Farchitecture\u002Farchitecture-technique","Architecture technique",[27,658,659,660,87],{},"Pour surveiller le planificateur et les files de tâches, voir ",[653,661,663],{"href":662},"\u002Fv5\u002Fadministrer\u002Fexploitation\u002Fdiagnostic","Diagnostiquer un site auto-hébergé",[665,666,667],"style",{},"html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":112,"searchDepth":119,"depth":130,"links":669},[670,671,672,673,674,675,676,677],{"id":51,"depth":130,"text":52},{"id":97,"depth":130,"text":98},{"id":215,"depth":130,"text":216},{"id":433,"depth":130,"text":434},{"id":518,"depth":130,"text":519},{"id":583,"depth":130,"text":584},{"id":593,"depth":130,"text":594},{"id":616,"depth":130,"text":617},"Démarrez un site avec la commande python -m frappe.runner, qui exécute le serveur web, le temps réel (Socket.IO), les tâches de fond et le planificateur dans un seul processus. Utile pour un petit site ou un site d'essai.","md",{"sources":681,"generated":687,"generated_at":688,"source_mrs":689,"reviewed":687},[682,683,684,685,686],"dodock@v5:frappe\u002Frunner.py","dodock@v5:frappe\u002Fasgi.py","dodock@v5:frappe\u002F_optimizations.py","dodock@v5:frappe\u002Fboot.py","dodock@v5:frappe\u002Frealtime\u002Fconfig.py",true,"2026-11-13",[690],"https:\u002F\u002Fgitlab.com\u002Fdokos\u002Fdodock\u002F-\u002Fmerge_requests\u002F12057","\u002Fv5\u002Fadministrer\u002Fexploitation\u002Fprocessus-unique",{"title":5,"description":678},"1.v5\u002F5.administrer\u002F03.exploitation\u002F17.processus-unique","5eYQmNyvQT48_Z3317enRBTeroDrC5W4Hd6TdFZPZ-s",{},1794606054288]