[{"data":1,"prerenderedAt":1648},["ShallowReactive",2],{"search-de":3,"content-de-developer\u002Fself-hosting-maintenance":4,"surround-de-\u002Fdeveloper\u002Fself-hosting-maintenance":1641},[],{"id":5,"title":6,"body":7,"description":1634,"extension":1635,"meta":1636,"navigation":187,"path":1637,"seo":1638,"stem":1639,"__hash__":1640},"content_de\u002F3.developer\u002F34.self-hosting-maintenance.md","Wartung & Updates",{"type":8,"value":9,"toc":1602},"minimark",[10,20,25,41,46,57,78,81,88,95,138,141,145,148,264,272,276,291,295,383,387,393,398,419,424,503,510,514,571,575,582,610,616,620,629,649,677,681,684,752,760,764,771,790,796,847,853,857,864,867,887,890,914,925,929,932,960,987,991,995,1005,1025,1031,1035,1103,1107,1113,1139,1143,1147,1162,1165,1194,1198,1213,1215,1289,1293,1299,1306,1310,1321,1327,1342,1346,1370,1372,1399,1403,1406,1598],[11,12,13,14,19],"p",{},"Diese Anleitung behandelt die tägliche Wartung Ihrer selbst gehosteten Owlat-Instanz. Für die Ersteinrichtung siehe ",[15,16,18],"a",{"href":17},"\u002Fdeveloper\u002Fself-hosting","Self-Hosting",".",[21,22,24],"h2",{"id":23},"aktualisieren","Aktualisieren",[11,26,27,28,32,33,36,37,40],{},"Owlat unterstützt drei Wege zum Aktualisieren: ",[29,30,31],"strong",{},"in der App",", per ",[29,34,35],{},"CLI"," oder ",[29,38,39],{},"manuell",". Alle drei tun unter der Haube dasselbe — das gepinnte Compose-Template eines getaggten Release ziehen, es anwenden und die Convex-Functions erneut deployen.",[42,43,45],"h3",{"id":44},"option-a-update-in-der-app-empfohlen","Option A: Update in der App (empfohlen)",[11,47,48,49,52,53,56],{},"Plattform-Admins sehen unter ",[29,50,51],{},"Einstellungen → System & Updates"," eine Benachrichtigung „Update verfügbar“, sobald eine neue Version veröffentlicht wurde. Klicken Sie auf ",[29,54,55],{},"Jetzt aktualisieren",", bestätigen Sie, und die Web-App wird:",[58,59,60,69,72,75],"ol",{},[61,62,63,64,68],"li",{},"Die gepinnte ",[65,66,67],"code",{},"docker-compose-\u003Cversion>.yml"," von den GitHub Releases herunterladen",[61,70,71],{},"Sie an den Updater-Sidecar übergeben",[61,73,74],{},"Neue Images ziehen, Container neu erstellen, Convex-Functions erneut deployen",[61,76,77],{},"Überprüfen, dass die neue Version aktiv ist",[11,79,80],{},"Die Seite fragt die Container-Gesundheit ab und lädt sich nach Abschluss des Updates automatisch neu. Gesamtdauer: typischerweise 2–5 Minuten.",[42,82,84,85],{"id":83},"option-b-cli-owlat-upgrade","Option B: CLI ",[65,86,87],{},"owlat upgrade",[11,89,90,91,94],{},"Wird vom Installer nach ",[65,92,93],{},"\u002Fusr\u002Flocal\u002Fbin\u002Fowlat"," installiert:",[96,97,102],"pre",{"className":98,"code":99,"language":100,"meta":101,"style":101},"language-bash shiki shiki-themes github-light github-dark-dimmed","owlat upgrade                     # to latest\nowlat upgrade --version 1.2.3     # to a specific version (useful for rollback)\n","bash","",[65,103,104,121],{"__ignoreMap":101},[105,106,109,113,117],"span",{"class":107,"line":108},"line",1,[105,110,112],{"class":111},"sOLd2","owlat",[105,114,116],{"class":115},"s-HuK"," upgrade",[105,118,120],{"class":119},"sDN9O","                     # to latest\n",[105,122,124,126,128,132,135],{"class":107,"line":123},2,[105,125,112],{"class":111},[105,127,116],{"class":115},[105,129,131],{"class":130},"sviXB"," --version",[105,133,134],{"class":130}," 1.2.3",[105,136,137],{"class":119},"     # to a specific version (useful for rollback)\n",[11,139,140],{},"Das CLI steuert denselben Updater-Sidecar, den auch der Ablauf in der App nutzt.",[42,142,144],{"id":143},"option-c-manuell","Option C: Manuell",[11,146,147],{},"Für Air-Gapped-Umgebungen oder wenn Sie Updates lieber selbst steuern:",[96,149,151],{"className":98,"code":150,"language":100,"meta":101,"style":101},"# 1. Pull the pinned compose template for the target version\ncurl -fsSL https:\u002F\u002Fgithub.com\u002Fwolvesdotink\u002Fowlat\u002Freleases\u002Fdownload\u002Fv1.2.3\u002Fdocker-compose-1.2.3.yml \\\n  -o docker-compose.yml\n\n# 2. Pull the new images\ndocker compose pull\n\n# 3. Recreate containers\ndocker compose up -d\n\n# 4. Re-deploy Convex tenant functions\ndocker compose --profile deploy run --rm convex-deploy\n",[65,152,153,158,173,182,189,195,207,212,218,231,236,242],{"__ignoreMap":101},[105,154,155],{"class":107,"line":108},[105,156,157],{"class":119},"# 1. Pull the pinned compose template for the target version\n",[105,159,160,163,166,169],{"class":107,"line":123},[105,161,162],{"class":111},"curl",[105,164,165],{"class":130}," -fsSL",[105,167,168],{"class":115}," https:\u002F\u002Fgithub.com\u002Fwolvesdotink\u002Fowlat\u002Freleases\u002Fdownload\u002Fv1.2.3\u002Fdocker-compose-1.2.3.yml",[105,170,172],{"class":171},"s74oq"," \\\n",[105,174,176,179],{"class":107,"line":175},3,[105,177,178],{"class":130},"  -o",[105,180,181],{"class":115}," docker-compose.yml\n",[105,183,185],{"class":107,"line":184},4,[105,186,188],{"emptyLinePlaceholder":187},true,"\n",[105,190,192],{"class":107,"line":191},5,[105,193,194],{"class":119},"# 2. Pull the new images\n",[105,196,198,201,204],{"class":107,"line":197},6,[105,199,200],{"class":111},"docker",[105,202,203],{"class":115}," compose",[105,205,206],{"class":115}," pull\n",[105,208,210],{"class":107,"line":209},7,[105,211,188],{"emptyLinePlaceholder":187},[105,213,215],{"class":107,"line":214},8,[105,216,217],{"class":119},"# 3. Recreate containers\n",[105,219,221,223,225,228],{"class":107,"line":220},9,[105,222,200],{"class":111},[105,224,203],{"class":115},[105,226,227],{"class":115}," up",[105,229,230],{"class":130}," -d\n",[105,232,234],{"class":107,"line":233},10,[105,235,188],{"emptyLinePlaceholder":187},[105,237,239],{"class":107,"line":238},11,[105,240,241],{"class":119},"# 4. Re-deploy Convex tenant functions\n",[105,243,245,247,249,252,255,258,261],{"class":107,"line":244},12,[105,246,200],{"class":111},[105,248,203],{"class":115},[105,250,251],{"class":130}," --profile",[105,253,254],{"class":115}," deploy",[105,256,257],{"class":115}," run",[105,259,260],{"class":130}," --rm",[105,262,263],{"class":115}," convex-deploy\n",[265,266,269],"callout",{"title":267,"type":268},"Functions immer erneut deployen","warning",[11,270,271],{},"Das Ziehen neuer Docker-Images aktualisiert die Container, die Convex-Serverless-Functions werden jedoch separat deployt. Der Weg in der App und über das CLI erledigen das für Sie; der manuelle Weg erfordert Schritt 4 oben.",[21,273,275],{"id":274},"wiederherstellung-nach-einem-fehlgeschlagenen-update","Wiederherstellung nach einem fehlgeschlagenen Update",[11,277,278,279,282,283,286,287,290],{},"Schlägt ein Update mittendrin fehl, kann Ihr Stack in einem gemischten Zustand sein — einige Container auf der neuen Version, andere auf der alten. Der Updater fasst die Daten-Volumes nie an, und seit dem Stage-then-Promote-Ablauf ersetzt er ",[65,280,281],{},"docker-compose.yml"," erst, nachdem Images gezogen und Convex-Functions erfolgreich deployt wurden. Dennoch gilt: ",[29,284,285],{},"Erstellen Sie vor dem Update ein Backup"," (",[65,288,289],{},"owlat backup",") — ein Release mit einer brechenden Schemaänderung kann Daten zurücksetzen oder migrieren, und maßgeblich dafür sind die Release Notes.",[42,292,294],{"id":293},"zuerst-diagnostizieren","Zuerst diagnostizieren",[96,296,298],{"className":98,"code":297,"language":100,"meta":101,"style":101},"# What's running?\nowlat status                       # or: docker compose ps\n\n# What did each container log?\nowlat logs web                     # follows the stream (Ctrl-C to exit); for a one-shot snapshot use: docker compose logs --tail=200 web\nowlat logs mta\nowlat logs convex\nowlat logs updater\n\n# Environment health check\nowlat doctor                       # checks .env, required env vars, compose override, running services\n",[65,299,300,305,315,319,324,337,346,355,364,368,373],{"__ignoreMap":101},[105,301,302],{"class":107,"line":108},[105,303,304],{"class":119},"# What's running?\n",[105,306,307,309,312],{"class":107,"line":123},[105,308,112],{"class":111},[105,310,311],{"class":115}," status",[105,313,314],{"class":119},"                       # or: docker compose ps\n",[105,316,317],{"class":107,"line":175},[105,318,188],{"emptyLinePlaceholder":187},[105,320,321],{"class":107,"line":184},[105,322,323],{"class":119},"# What did each container log?\n",[105,325,326,328,331,334],{"class":107,"line":191},[105,327,112],{"class":111},[105,329,330],{"class":115}," logs",[105,332,333],{"class":115}," web",[105,335,336],{"class":119},"                     # follows the stream (Ctrl-C to exit); for a one-shot snapshot use: docker compose logs --tail=200 web\n",[105,338,339,341,343],{"class":107,"line":197},[105,340,112],{"class":111},[105,342,330],{"class":115},[105,344,345],{"class":115}," mta\n",[105,347,348,350,352],{"class":107,"line":209},[105,349,112],{"class":111},[105,351,330],{"class":115},[105,353,354],{"class":115}," convex\n",[105,356,357,359,361],{"class":107,"line":214},[105,358,112],{"class":111},[105,360,330],{"class":115},[105,362,363],{"class":115}," updater\n",[105,365,366],{"class":107,"line":220},[105,367,188],{"emptyLinePlaceholder":187},[105,369,370],{"class":107,"line":233},[105,371,372],{"class":119},"# Environment health check\n",[105,374,375,377,380],{"class":107,"line":238},[105,376,112],{"class":111},[105,378,379],{"class":115}," doctor",[105,381,382],{"class":119},"                       # checks .env, required env vars, compose override, running services\n",[42,384,386],{"id":385},"rollback-auf-die-vorherige-version","Rollback auf die vorherige Version",[11,388,389,390,392],{},"Jedes getaggte Release hängt seine ",[65,391,67],{}," an die GitHub-Release-Seite an. So machen Sie ein Rollback:",[11,394,395],{},[29,396,397],{},"Per CLI:",[96,399,401],{"className":98,"code":400,"language":100,"meta":101,"style":101},"# Replace with the last-known-good version\nowlat upgrade --version 1.2.2\n",[65,402,403,408],{"__ignoreMap":101},[105,404,405],{"class":107,"line":108},[105,406,407],{"class":119},"# Replace with the last-known-good version\n",[105,409,410,412,414,416],{"class":107,"line":123},[105,411,112],{"class":111},[105,413,116],{"class":115},[105,415,131],{"class":130},[105,417,418],{"class":130}," 1.2.2\n",[11,420,421],{},[29,422,423],{},"Manuell:",[96,425,427],{"className":98,"code":426,"language":100,"meta":101,"style":101},"# Download the previous release's compose file\ncurl -fsSL https:\u002F\u002Fgithub.com\u002Fwolvesdotink\u002Fowlat\u002Freleases\u002Fdownload\u002Fv1.2.2\u002Fdocker-compose-1.2.2.yml \\\n  -o docker-compose.yml\n\n# Pull the pinned images and recreate\ndocker compose pull\ndocker compose up -d\n\n# Re-deploy functions at the old version\ndocker compose --profile deploy run --rm convex-deploy\n",[65,428,429,434,445,451,455,460,468,478,482,487],{"__ignoreMap":101},[105,430,431],{"class":107,"line":108},[105,432,433],{"class":119},"# Download the previous release's compose file\n",[105,435,436,438,440,443],{"class":107,"line":123},[105,437,162],{"class":111},[105,439,165],{"class":130},[105,441,442],{"class":115}," https:\u002F\u002Fgithub.com\u002Fwolvesdotink\u002Fowlat\u002Freleases\u002Fdownload\u002Fv1.2.2\u002Fdocker-compose-1.2.2.yml",[105,444,172],{"class":171},[105,446,447,449],{"class":107,"line":175},[105,448,178],{"class":130},[105,450,181],{"class":115},[105,452,453],{"class":107,"line":184},[105,454,188],{"emptyLinePlaceholder":187},[105,456,457],{"class":107,"line":191},[105,458,459],{"class":119},"# Pull the pinned images and recreate\n",[105,461,462,464,466],{"class":107,"line":197},[105,463,200],{"class":111},[105,465,203],{"class":115},[105,467,206],{"class":115},[105,469,470,472,474,476],{"class":107,"line":209},[105,471,200],{"class":111},[105,473,203],{"class":115},[105,475,227],{"class":115},[105,477,230],{"class":130},[105,479,480],{"class":107,"line":214},[105,481,188],{"emptyLinePlaceholder":187},[105,483,484],{"class":107,"line":220},[105,485,486],{"class":119},"# Re-deploy functions at the old version\n",[105,488,489,491,493,495,497,499,501],{"class":107,"line":233},[105,490,200],{"class":111},[105,492,203],{"class":115},[105,494,251],{"class":130},[105,496,254],{"class":115},[105,498,257],{"class":115},[105,500,260],{"class":130},[105,502,263],{"class":115},[11,504,505,506,509],{},"Docker zieht die Images zu den gepinnten Tags (z. B. ",[65,507,508],{},"ghcr.io\u002Fwolvesdotink\u002Fweb:1.2.2",") und tauscht die Container an Ort und Stelle aus.",[42,511,513],{"id":512},"wenn-der-web-container-nicht-startet","Wenn der Web-Container nicht startet",[96,515,517],{"className":98,"code":516,"language":100,"meta":101,"style":101},"# See why\ndocker compose logs web\n\n# Rule out a stale image\ndocker compose pull web\ndocker compose up -d --force-recreate web\n",[65,518,519,524,535,539,544,555],{"__ignoreMap":101},[105,520,521],{"class":107,"line":108},[105,522,523],{"class":119},"# See why\n",[105,525,526,528,530,532],{"class":107,"line":123},[105,527,200],{"class":111},[105,529,203],{"class":115},[105,531,330],{"class":115},[105,533,534],{"class":115}," web\n",[105,536,537],{"class":107,"line":175},[105,538,188],{"emptyLinePlaceholder":187},[105,540,541],{"class":107,"line":184},[105,542,543],{"class":119},"# Rule out a stale image\n",[105,545,546,548,550,553],{"class":107,"line":191},[105,547,200],{"class":111},[105,549,203],{"class":115},[105,551,552],{"class":115}," pull",[105,554,534],{"class":115},[105,556,557,559,561,563,566,569],{"class":107,"line":197},[105,558,200],{"class":111},[105,560,203],{"class":115},[105,562,227],{"class":115},[105,564,565],{"class":130}," -d",[105,567,568],{"class":130}," --force-recreate",[105,570,534],{"class":115},[42,572,574],{"id":573},"wenn-convex-nicht-startet","Wenn Convex nicht startet",[11,576,577,578,581],{},"Convex hält die primäre Datenbank; Redis und ClamAV persistieren ebenfalls Daten, dazu kommen optionale Services (code-worker, ollama, IMAP-\u002FACME-Zertifikate), sofern deren Feature-Profile aktiviert sind. Wenn der Start scheitert, prüfen Sie zuerst den Speicherplatz auf dem Volume ",[65,579,580],{},"convex-data",":",[96,583,585],{"className":98,"code":584,"language":100,"meta":101,"style":101},"docker system df -v | grep convex-data\n",[65,586,587],{"__ignoreMap":101},[105,588,589,591,594,597,600,604,607],{"class":107,"line":108},[105,590,200],{"class":111},[105,592,593],{"class":115}," system",[105,595,596],{"class":115}," df",[105,598,599],{"class":130}," -v",[105,601,603],{"class":602},"s7YZ4"," |",[105,605,606],{"class":111}," grep",[105,608,609],{"class":115}," convex-data\n",[11,611,612,613,615],{},"Ist die Festplatte voll, schaffen Sie Platz oder vergrößern Sie das zugrunde liegende Volume. Löschen Sie das Volume ",[65,614,580],{}," niemals — das ist Ihre Datenbank.",[42,617,619],{"id":618},"letztes-mittel-aus-dem-backup-wiederherstellen","Letztes Mittel: aus dem Backup wiederherstellen",[11,621,622,623,625,626,581],{},"Ist der Stack in einem nicht mehr reparablen Zustand, stellen Sie das jüngste Backup-Archiv wieder her. Das ",[65,624,112],{},"-CLI kapselt ",[65,627,628],{},"scripts\u002Frestore.sh",[96,630,632],{"className":98,"code":631,"language":100,"meta":101,"style":101},"owlat restore backups\u002Fowlat-YYYYMMDD-HHMMSS.tar.gz\n# equivalently: bash scripts\u002Frestore.sh backups\u002Fowlat-YYYYMMDD-HHMMSS.tar.gz\n",[65,633,634,644],{"__ignoreMap":101},[105,635,636,638,641],{"class":107,"line":108},[105,637,112],{"class":111},[105,639,640],{"class":115}," restore",[105,642,643],{"class":115}," backups\u002Fowlat-YYYYMMDD-HHMMSS.tar.gz\n",[105,645,646],{"class":107,"line":123},[105,647,648],{"class":119},"# equivalently: bash scripts\u002Frestore.sh backups\u002Fowlat-YYYYMMDD-HHMMSS.tar.gz\n",[11,650,651,652,655,656,659,660,664,665,668,669,672,673,676],{},"Das stoppt den Stack, löscht die Volumes, befüllt sie aus dem Archiv neu (Convex, Redis und optional ClamAV) und fährt alles wieder hoch. Die aktuelle ",[65,653,654],{},".env"," wird zuvor unter ",[65,657,658],{},".env.before-restore-\u003Ctimestamp>"," gesichert. Wie Sie solche Archive erzeugen und automatische Backups einrichten, steht unter ",[15,661,663],{"href":662},"\u002Fdeveloper\u002Fself-hosting-production#backups","Backups",". Um wiederkehrende Backups einzurichten, ohne selbst Cron-Einträge zu basteln, führen Sie ",[65,666,667],{},"owlat backup-schedule enable"," aus — das installiert einen täglichen systemd-Timer (mit Cron als Fallback), der ",[65,670,671],{},"scripts\u002Fbackup.sh"," ausführt; ",[65,674,675],{},"owlat backup-schedule disable"," entfernt ihn wieder.",[42,678,680],{"id":679},"einen-update-fehler-melden","Einen Update-Fehler melden",[11,682,683],{},"Schlägt ein Update auf eine Weise fehl, die Sie für einen Bug in Owlat selbst halten (und nicht für ein Problem Ihrer Umgebung), erfassen Sie Folgendes und hängen es an ein GitHub-Issue an:",[96,685,687],{"className":98,"code":686,"language":100,"meta":101,"style":101},"owlat doctor                                   > \u002Ftmp\u002Fowlat-doctor.txt 2>&1\ndocker compose ps                              > \u002Ftmp\u002Fowlat-ps.txt\ndocker compose logs --tail=500                 > \u002Ftmp\u002Fowlat-logs.txt 2>&1\ncat \u002Fopt\u002Fowlat\u002Fdocker-compose.yml              > \u002Ftmp\u002Fowlat-compose.yml\n",[65,688,689,704,719,738],{"__ignoreMap":101},[105,690,691,693,695,698,701],{"class":107,"line":108},[105,692,112],{"class":111},[105,694,379],{"class":115},[105,696,697],{"class":602},"                                   >",[105,699,700],{"class":115}," \u002Ftmp\u002Fowlat-doctor.txt",[105,702,703],{"class":602}," 2>&1\n",[105,705,706,708,710,713,716],{"class":107,"line":123},[105,707,200],{"class":111},[105,709,203],{"class":115},[105,711,712],{"class":115}," ps",[105,714,715],{"class":602},"                              >",[105,717,718],{"class":115}," \u002Ftmp\u002Fowlat-ps.txt\n",[105,720,721,723,725,727,730,733,736],{"class":107,"line":175},[105,722,200],{"class":111},[105,724,203],{"class":115},[105,726,330],{"class":115},[105,728,729],{"class":130}," --tail=500",[105,731,732],{"class":602},"                 >",[105,734,735],{"class":115}," \u002Ftmp\u002Fowlat-logs.txt",[105,737,703],{"class":602},[105,739,740,743,746,749],{"class":107,"line":184},[105,741,742],{"class":111},"cat",[105,744,745],{"class":115}," \u002Fopt\u002Fowlat\u002Fdocker-compose.yml",[105,747,748],{"class":602},"              >",[105,750,751],{"class":115}," \u002Ftmp\u002Fowlat-compose.yml\n",[11,753,754,755],{},"Einreichen unter: ",[15,756,757],{"href":757,"rel":758},"https:\u002F\u002Fgithub.com\u002Fwolvesdotink\u002Fowlat\u002Fissues\u002Fnew",[759],"nofollow",[42,761,763],{"id":762},"updates-automatisieren","Updates automatisieren",[11,765,766,767,770],{},"Es gibt bewusst ",[29,768,769],{},"keinen Cron-Job für unbeaufsichtigte Updates ab Werk",". Zwei Gründe:",[58,772,773,787],{},[61,774,775,776,779,780,782,783,786],{},"Die Reihenfolge zählt: Functions müssen deployt werden, ",[29,777,778],{},"bevor"," die App-Container\nneu starten (der Updater in der App und ",[65,781,87],{}," erledigen das für Sie). Ein naiver\n",[65,784,785],{},"pull && up && deploy","-Cron — wie ihn frühere Fassungen dieser Seite\nvorschlugen — startet die Container zuerst gegen ein altes Schema neu.",[61,788,789],{},"Vor 1.0 kann ein Release eine brechende Schemaänderung enthalten. Lesen Sie die\nRelease Notes, bevor Sie ein Update anwenden; lassen Sie sie nicht blind per Cron einspielen.",[11,791,792,793,795],{},"Wenn Sie diese Kompromisse akzeptieren, automatisieren Sie ",[65,794,87],{}," (das die\nsichere Reihenfolge kapselt) und kombinieren es mit einem Backup vor dem Update:",[96,797,799],{"className":98,"code":798,"language":100,"meta":101,"style":101},"# \u002Fetc\u002Fcron.d\u002Fowlat-update — automated upgrades, at your own risk\n0 4 * * 0 root cd \u002Fopt\u002Fowlat && bash scripts\u002Fbackup.sh && owlat upgrade\n",[65,800,801,806],{"__ignoreMap":101},[105,802,803],{"class":107,"line":108},[105,804,805],{"class":119},"# \u002Fetc\u002Fcron.d\u002Fowlat-update — automated upgrades, at your own risk\n",[105,807,808,811,814,817,819,822,825,828,831,835,837,840,842,844],{"class":107,"line":123},[105,809,810],{"class":111},"0",[105,812,813],{"class":130}," 4",[105,815,816],{"class":130}," *",[105,818,816],{"class":130},[105,820,821],{"class":130}," 0",[105,823,824],{"class":115}," root",[105,826,827],{"class":115}," cd",[105,829,830],{"class":115}," \u002Fopt\u002Fowlat",[105,832,834],{"class":833},"sYgZi"," && ",[105,836,100],{"class":111},[105,838,839],{"class":115}," scripts\u002Fbackup.sh",[105,841,834],{"class":833},[105,843,112],{"class":111},[105,845,846],{"class":115}," upgrade\n",[265,848,850],{"title":849,"type":268},"Update-Sicherheit",[11,851,852],{},"Halten Sie vor einem Update stets ein frisches Backup bereit. Owlat ist vor 1.0: Ein\nRelease kann brechende Schemaänderungen enthalten, die bestimmte Tabellen\nzurücksetzen — die Release Notes weisen darauf hin, wenn das der Fall ist.",[21,854,856],{"id":855},"clamav-signaturen","ClamAV-Signaturen",[11,858,859,860,863],{},"Der ClamAV-Container führt automatisch ",[65,861,862],{},"freshclamd"," aus, was täglich aktualisierte Virendefinitionen herunterlädt. Ein manueller Eingriff ist nicht nötig.",[11,865,866],{},"Um eine sofortige Signaturaktualisierung zu erzwingen:",[96,868,870],{"className":98,"code":869,"language":100,"meta":101,"style":101},"docker compose exec clamav freshclam\n",[65,871,872],{"__ignoreMap":101},[105,873,874,876,878,881,884],{"class":107,"line":108},[105,875,200],{"class":111},[105,877,203],{"class":115},[105,879,880],{"class":115}," exec",[105,882,883],{"class":115}," clamav",[105,885,886],{"class":115}," freshclam\n",[11,888,889],{},"Um die installierte Version der Signaturdatenbank direkt zu prüfen:",[96,891,893],{"className":98,"code":892,"language":100,"meta":101,"style":101},"docker compose exec clamav sigtool --info \u002Fvar\u002Flib\u002Fclamav\u002Fdaily.cld\n",[65,894,895],{"__ignoreMap":101},[105,896,897,899,901,903,905,908,911],{"class":107,"line":108},[105,898,200],{"class":111},[105,900,203],{"class":115},[105,902,880],{"class":115},[105,904,883],{"class":115},[105,906,907],{"class":115}," sigtool",[105,909,910],{"class":130}," --info",[105,912,913],{"class":115}," \u002Fvar\u002Flib\u002Fclamav\u002Fdaily.cld\n",[11,915,916,917,920,921,924],{},"(",[65,918,919],{},"clamscan --version"," meldet die Version der ClamAV-",[29,922,923],{},"Engine",", nicht die der Signaturdatenbank.)",[21,926,928],{"id":927},"redis-wartung","Redis-Wartung",[11,930,931],{},"Redis ist standardmäßig mit AOF-Persistenz (Append Only File) konfiguriert. Das stellt sicher, dass die MTA-Job-Queue Container-Neustarts übersteht.",[933,934,935,941,950],"ul",{},[61,936,937,940],{},[29,938,939],{},"Kompaktierung"," — Redis schreibt die AOF-Datei automatisch neu, um sie kompakt zu halten.",[61,942,943,946,947,19],{},[29,944,945],{},"Arbeitsspeicher"," — überwachen Sie den Speicherverbrauch von Redis mit ",[65,948,949],{},"docker compose exec redis redis-cli info memory",[61,951,952,955,956,959],{},[29,953,954],{},"Leeren"," — wenn Sie die Queue leeren müssen (z. B. nach einer Fehlkonfiguration): ",[65,957,958],{},"docker compose exec redis redis-cli FLUSHALL",". Das verwirft alle laufenden E-Mail-Jobs.",[265,961,964],{"title":962,"type":963},"Passwortgeschütztes Redis","info",[11,965,966,967,970,971,975,976,979,980,983,984,19],{},"Wenn Sie Redis mit einem ",[65,968,969],{},"REDIS_PASSWORD"," abgesichert haben (siehe ",[15,972,974],{"href":973},"\u002Fdeveloper\u002Fself-hosting-production#redis-authentication","Redis-Authentifizierung","), stellen Sie jedem ",[65,977,978],{},"redis-cli","-Befehl ",[65,981,982],{},"-a \"$REDIS_PASSWORD\" --no-auth-warning"," voran, z. B. ",[65,985,986],{},"docker compose exec redis redis-cli -a \"$REDIS_PASSWORD\" --no-auth-warning info memory",[21,988,990],{"id":989},"skalierung","Skalierung",[42,992,994],{"id":993},"mta-durchsatz","MTA-Durchsatz",[11,996,997,998,1001,1002,1004],{},"Erhöhen Sie ",[65,999,1000],{},"WORKER_CONCURRENCY"," in Ihrer ",[65,1003,654],{},", um mehr E-Mail-Gruppen parallel zu verarbeiten:",[96,1006,1008],{"className":98,"code":1007,"language":100,"meta":101,"style":101},"# Default: 50 workers\nWORKER_CONCURRENCY=100\n",[65,1009,1010,1015],{"__ignoreMap":101},[105,1011,1012],{"class":107,"line":108},[105,1013,1014],{"class":119},"# Default: 50 workers\n",[105,1016,1017,1019,1022],{"class":107,"line":123},[105,1018,1000],{"class":833},[105,1020,1021],{"class":602},"=",[105,1023,1024],{"class":115},"100\n",[11,1026,1027,1028],{},"Zum Anwenden den MTA neu starten: ",[65,1029,1030],{},"docker compose restart mta",[42,1032,1034],{"id":1033},"server-dimensionierung","Server-Dimensionierung",[1036,1037,1038,1057],"table",{},[1039,1040,1041],"thead",{},[1042,1043,1044,1048,1051,1054],"tr",{},[1045,1046,1047],"th",{},"Last",[1045,1049,1050],{},"vCPU",[1045,1052,1053],{},"RAM",[1045,1055,1056],{},"Festplatte",[1058,1059,1060,1075,1089],"tbody",{},[1042,1061,1062,1066,1069,1072],{},[1063,1064,1065],"td",{},"Bis zu 10.000 Kontakte",[1063,1067,1068],{},"2",[1063,1070,1071],{},"4 GB",[1063,1073,1074],{},"40 GB",[1042,1076,1077,1080,1083,1086],{},[1063,1078,1079],{},"Bis zu 100.000 Kontakte",[1063,1081,1082],{},"4",[1063,1084,1085],{},"8 GB",[1063,1087,1088],{},"80 GB",[1042,1090,1091,1094,1097,1100],{},[1063,1092,1093],{},"100.000+ Kontakte",[1063,1095,1096],{},"8",[1063,1098,1099],{},"16 GB",[1063,1101,1102],{},"160 GB",[42,1104,1106],{"id":1105},"convex-backend","Convex-Backend",[11,1108,1109,1110,1112],{},"Convex ist ein Single-Node-Service, der vertikal skaliert. Überwachen Sie die Festplattennutzung des Volumes ",[65,1111,580],{}," — dort werden alle Datenbankeinträge, hochgeladenen Dateien und Vektorindizes gespeichert.",[96,1114,1116],{"className":98,"code":1115,"language":100,"meta":101,"style":101},"# Check volume disk usage\ndocker system df -v | grep convex-data\n",[65,1117,1118,1123],{"__ignoreMap":101},[105,1119,1120],{"class":107,"line":108},[105,1121,1122],{"class":119},"# Check volume disk usage\n",[105,1124,1125,1127,1129,1131,1133,1135,1137],{"class":107,"line":123},[105,1126,200],{"class":111},[105,1128,593],{"class":115},[105,1130,596],{"class":115},[105,1132,599],{"class":130},[105,1134,603],{"class":602},[105,1136,606],{"class":111},[105,1138,609],{"class":115},[21,1140,1142],{"id":1141},"fehlerbehebung","Fehlerbehebung",[42,1144,1146],{"id":1145},"convex-startet-nicht","Convex startet nicht",[96,1148,1150],{"className":98,"code":1149,"language":100,"meta":101,"style":101},"docker compose logs convex\n",[65,1151,1152],{"__ignoreMap":101},[105,1153,1154,1156,1158,1160],{"class":107,"line":108},[105,1155,200],{"class":111},[105,1157,203],{"class":115},[105,1159,330],{"class":115},[105,1161,354],{"class":115},[11,1163,1164],{},"Häufige Ursachen:",[933,1166,1167,1179,1188],{},[61,1168,1169,1175,1176,1178],{},[29,1170,1171,1174],{},[65,1172,1173],{},"INSTANCE_SECRET"," ist nicht gesetzt"," — prüfen Sie, ob Ihre ",[65,1177,654],{},"-Datei eine gültige Hex-Zeichenkette enthält",[61,1180,1181,1184,1185,1187],{},[29,1182,1183],{},"Festplatte voll"," — das Volume ",[65,1186,580],{}," benötigt freien Speicher für die Datenbank",[61,1189,1190,1193],{},[29,1191,1192],{},"Port-Konflikt"," — ein anderer Service belegt Port 3210 oder 3211",[42,1195,1197],{"id":1196},"der-mta-kann-keine-e-mails-versenden","Der MTA kann keine E-Mails versenden",[96,1199,1201],{"className":98,"code":1200,"language":100,"meta":101,"style":101},"docker compose logs mta\n",[65,1202,1203],{"__ignoreMap":101},[105,1204,1205,1207,1209,1211],{"class":107,"line":108},[105,1206,200],{"class":111},[105,1208,203],{"class":115},[105,1210,330],{"class":115},[105,1212,345],{"class":115},[11,1214,1164],{},[933,1216,1217,1256,1265,1274,1280],{},[61,1218,1219,1225,1226,1228,1229,1232,1233,1235,1236,1239,1240,1243,1244,1247,1248,1251,1252,1255],{},[29,1220,1221,1224],{},[65,1222,1223],{},"MTA_API_URL"," ist in der Convex-Laufzeit nicht gesetzt"," — die häufigste Ursache nach einer manuellen Installation. ",[65,1227,1223],{}," (und ",[65,1230,1231],{},"MTA_API_KEY",") müssen in das Convex-Deployment übertragen werden, nicht nur in die Compose-",[65,1234,654],{},"; ohne sie löst der Versand einen harten Fehler ",[65,1237,1238],{},"No system email transport configured"," aus (",[65,1241,1242],{},"apps\u002Fapi\u002Fconvex\u002FsystemMail.ts","), bevor der MTA überhaupt erreicht wird. Prüfen Sie das mit ",[65,1245,1246],{},"npx convex env list"," (oder über das Dashboard) und setzen Sie den Wert auf ",[65,1249,1250],{},"http:\u002F\u002Fmta:3100",". Der Assistent ",[65,1253,1254],{},"owlat quickstart"," erledigt das für Sie.",[61,1257,1258,1261,1262],{},[29,1259,1260],{},"Der EHLO-Hostname passt nicht zum PTR-Record"," — empfangende Server weisen die Verbindung ab. Prüfen Sie mit ",[65,1263,1264],{},"dig -x YOUR_IP +short",[61,1266,1267,1270,1271],{},[29,1268,1269],{},"Das JSON in DKIM_KEYS ist ungültig"," — validieren Sie das JSON: ",[65,1272,1273],{},"echo $DKIM_KEYS | jq .",[61,1275,1276,1279],{},[29,1277,1278],{},"Port 25 blockiert"," — viele Cloud-Anbieter (AWS, GCP, Azure) blockieren ausgehendes SMTP standardmäßig. Beantragen Sie die Freigabe von Port 25 oder nutzen Sie ein E-Mail-Relay",[61,1281,1282,1285,1286,1288],{},[29,1283,1284],{},"MTA_API_KEY stimmt nicht überein"," — der Key in der Docker-",[65,1287,654],{}," muss dem in den Convex-Umgebungsvariablen gesetzten entsprechen",[42,1290,1292],{"id":1291},"clamav-startet-langsam","ClamAV startet langsam",[11,1294,1295,1296,19],{},"Das ist normal. ClamAV lädt beim Start die Virendefinitionen in den Arbeitsspeicher und beim allerersten Start zusätzlich die vollständige Signaturdatenbank (~300 MB) herunter — auf einem kleinen VPS kann das mehrere Minuten dauern. Der Docker-Healthcheck hat dafür ein ",[65,1297,1298],{},"start_period: 600s",[11,1300,1301,1302,1305],{},"Der MTA wartet, bis ClamAV healthy ist, bevor er startet (konfiguriert über ",[65,1303,1304],{},"depends_on"," in Docker Compose).",[42,1307,1309],{"id":1308},"die-web-oberfläche-zeigt-einen-verbindungsfehler","Die Web-Oberfläche zeigt einen Verbindungsfehler",[11,1311,1312,1313,1316,1317,1320],{},"Der Browser muss das Convex-Backend direkt erreichen. Wenn ",[65,1314,1315],{},"NUXT_PUBLIC_CONVEX_URL"," einen Docker-internen Hostnamen verwendet (etwa ",[65,1318,1319],{},"http:\u002F\u002Fconvex:3210","), kann der Browser keine Verbindung aufbauen.",[11,1322,1323,1324,1326],{},"Abhilfe: Setzen Sie ",[65,1325,1315],{}," auf eine aus dem Browser erreichbare URL:",[933,1328,1329,1335],{},[61,1330,1331,1332],{},"Lokale Entwicklung: ",[65,1333,1334],{},"http:\u002F\u002Flocalhost:3210",[61,1336,1337,1338,1341],{},"Produktion: ",[65,1339,1340],{},"https:\u002F\u002Fapi.example.com"," (über den Reverse Proxy)",[42,1343,1345],{"id":1344},"das-deployment-der-functions-schlägt-fehl","Das Deployment der Functions schlägt fehl",[96,1347,1349],{"className":98,"code":1348,"language":100,"meta":101,"style":101},"docker compose --profile deploy run --rm convex-deploy 2>&1\n",[65,1350,1351],{"__ignoreMap":101},[105,1352,1353,1355,1357,1359,1361,1363,1365,1368],{"class":107,"line":108},[105,1354,200],{"class":111},[105,1356,203],{"class":115},[105,1358,251],{"class":130},[105,1360,254],{"class":115},[105,1362,257],{"class":115},[105,1364,260],{"class":130},[105,1366,1367],{"class":115}," convex-deploy",[105,1369,703],{"class":602},[11,1371,1164],{},[933,1373,1374,1383,1393],{},[61,1375,1376,1379,1380],{},[29,1377,1378],{},"CONVEX_ADMIN_KEY ist falsch oder fehlt"," — neu erzeugen: ",[65,1381,1382],{},"docker compose exec convex .\u002Fgenerate_admin_key.sh",[61,1384,1385,1388,1389,1392],{},[29,1386,1387],{},"Der Convex-Container ist nicht healthy"," — mit ",[65,1390,1391],{},"docker compose ps"," prüfen",[61,1394,1395,1398],{},[29,1396,1397],{},"Schemakonflikt"," — wenn Sie Convex-Schemadateien geändert haben, suchen Sie in der Deploy-Ausgabe nach Validierungsfehlern",[21,1400,1402],{"id":1401},"umzug-in-die-produktion","Umzug in die Produktion",[11,1404,1405],{},"So wechseln Sie von einem lokalen Entwicklungs-Setup zu einem Produktions-Deployment:",[58,1407,1408,1450,1460,1470,1482,1578,1587],{},[61,1409,1410,1413,1414,581,1416],{},[29,1411,1412],{},"URLs aktualisieren"," in ",[65,1415,654],{},[96,1417,1419],{"className":98,"code":1418,"language":100,"meta":101,"style":101},"NUXT_PUBLIC_CONVEX_URL=https:\u002F\u002Fapi.example.com\nNUXT_PUBLIC_CONVEX_SITE_URL=https:\u002F\u002Frest.api.example.com\nNUXT_PUBLIC_SITE_URL=https:\u002F\u002Fowlat.example.com\n",[65,1420,1421,1430,1440],{"__ignoreMap":101},[105,1422,1423,1425,1427],{"class":107,"line":108},[105,1424,1315],{"class":833},[105,1426,1021],{"class":602},[105,1428,1429],{"class":115},"https:\u002F\u002Fapi.example.com\n",[105,1431,1432,1435,1437],{"class":107,"line":123},[105,1433,1434],{"class":833},"NUXT_PUBLIC_CONVEX_SITE_URL",[105,1436,1021],{"class":602},[105,1438,1439],{"class":115},"https:\u002F\u002Frest.api.example.com\n",[105,1441,1442,1445,1447],{"class":107,"line":175},[105,1443,1444],{"class":833},"NUXT_PUBLIC_SITE_URL",[105,1446,1021],{"class":602},[105,1448,1449],{"class":115},"https:\u002F\u002Fowlat.example.com\n",[61,1451,1452,1455,1456,19],{},[29,1453,1454],{},"DNS einrichten"," — A-Records, PTR, SPF, DKIM und DMARC konfigurieren. Siehe ",[15,1457,1459],{"href":1458},"\u002Fdeveloper\u002Fself-hosting-dns-email","DNS- & E-Mail-Setup",[61,1461,1462,1465,1466,19],{},[29,1463,1464],{},"Reverse Proxy ergänzen"," — Caddy oder Nginx mit TLS. Siehe ",[15,1467,1469],{"href":1468},"\u002Fdeveloper\u002Fself-hosting-production","Produktions-Deployment",[61,1471,1472,1475,1476,1478,1479,1481],{},[29,1473,1474],{},"Redis absichern"," — ",[65,1477,969],{}," ergänzen, wie unter ",[15,1480,1469],{"href":973}," beschrieben.",[61,1483,1484,1487,1488],{},[29,1485,1486],{},"Convex-Umgebungsvariablen aktualisieren",", damit sie zu den neuen URLs passen:",[96,1489,1491],{"className":98,"code":1490,"language":100,"meta":101,"style":101},"npx convex env set SITE_URL \"https:\u002F\u002Fowlat.example.com\" --url http:\u002F\u002Flocalhost:3210 --admin-key \u003Ckey>\n# CONVEX_SITE_URL is a Convex BUILT-IN — do not set it via `convex env set`\n# (the CLI rejects it). It derives from CONVEX_SITE_ORIGIN on the convex\n# container, which docker-compose interpolates from NUXT_PUBLIC_CONVEX_SITE_URL.\nnpx convex env set ALLOWED_ORIGINS \"https:\u002F\u002Fowlat.example.com\" --url http:\u002F\u002Flocalhost:3210 --admin-key \u003Ckey>\n",[65,1492,1493,1534,1539,1544,1549],{"__ignoreMap":101},[105,1494,1495,1498,1501,1504,1507,1510,1513,1516,1519,1522,1525,1528,1531],{"class":107,"line":108},[105,1496,1497],{"class":111},"npx",[105,1499,1500],{"class":115}," convex",[105,1502,1503],{"class":115}," env",[105,1505,1506],{"class":115}," set",[105,1508,1509],{"class":115}," SITE_URL",[105,1511,1512],{"class":115}," \"https:\u002F\u002Fowlat.example.com\"",[105,1514,1515],{"class":130}," --url",[105,1517,1518],{"class":115}," http:\u002F\u002Flocalhost:3210",[105,1520,1521],{"class":130}," --admin-key",[105,1523,1524],{"class":602}," \u003C",[105,1526,1527],{"class":115},"ke",[105,1529,1530],{"class":833},"y",[105,1532,1533],{"class":602},">\n",[105,1535,1536],{"class":107,"line":123},[105,1537,1538],{"class":119},"# CONVEX_SITE_URL is a Convex BUILT-IN — do not set it via `convex env set`\n",[105,1540,1541],{"class":107,"line":175},[105,1542,1543],{"class":119},"# (the CLI rejects it). It derives from CONVEX_SITE_ORIGIN on the convex\n",[105,1545,1546],{"class":107,"line":184},[105,1547,1548],{"class":119},"# container, which docker-compose interpolates from NUXT_PUBLIC_CONVEX_SITE_URL.\n",[105,1550,1551,1553,1555,1557,1559,1562,1564,1566,1568,1570,1572,1574,1576],{"class":107,"line":191},[105,1552,1497],{"class":111},[105,1554,1500],{"class":115},[105,1556,1503],{"class":115},[105,1558,1506],{"class":115},[105,1560,1561],{"class":115}," ALLOWED_ORIGINS",[105,1563,1512],{"class":115},[105,1565,1515],{"class":130},[105,1567,1518],{"class":115},[105,1569,1521],{"class":130},[105,1571,1524],{"class":602},[105,1573,1527],{"class":115},[105,1575,1530],{"class":833},[105,1577,1533],{"class":602},[61,1579,1580,1583,1584],{},[29,1581,1582],{},"Stack neu starten",": ",[65,1585,1586],{},"docker compose up -d",[61,1588,1589,1592,1593,19],{},[29,1590,1591],{},"Überprüfen"," — senden Sie eine Test-E-Mail und prüfen Sie die Zustellung mit ",[15,1594,1597],{"href":1595,"rel":1596},"https:\u002F\u002Fwww.mail-tester.com",[759],"mail-tester.com",[1599,1600,1601],"style",{},"html pre.shiki code .sOLd2, html code.shiki .sOLd2{--shiki-default:#6F42C1;--shiki-dark:#F69D50}html pre.shiki code .s-HuK, html code.shiki .s-HuK{--shiki-default:#032F62;--shiki-dark:#96D0FF}html pre.shiki code .sDN9O, html code.shiki .sDN9O{--shiki-default:#6A737D;--shiki-dark:#768390}html pre.shiki code .sviXB, html code.shiki .sviXB{--shiki-default:#005CC5;--shiki-dark:#6CB6FF}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);}html pre.shiki code .s74oq, html code.shiki .s74oq{--shiki-default:#005CC5;--shiki-dark:#F47067}html pre.shiki code .s7YZ4, html code.shiki .s7YZ4{--shiki-default:#D73A49;--shiki-dark:#F47067}html pre.shiki code .sYgZi, html code.shiki .sYgZi{--shiki-default:#24292E;--shiki-dark:#ADBAC7}",{"title":101,"searchDepth":123,"depth":123,"links":1603},[1604,1610,1619,1620,1621,1626,1633],{"id":23,"depth":123,"text":24,"children":1605},[1606,1607,1609],{"id":44,"depth":175,"text":45},{"id":83,"depth":175,"text":1608},"Option B: CLI owlat upgrade",{"id":143,"depth":175,"text":144},{"id":274,"depth":123,"text":275,"children":1611},[1612,1613,1614,1615,1616,1617,1618],{"id":293,"depth":175,"text":294},{"id":385,"depth":175,"text":386},{"id":512,"depth":175,"text":513},{"id":573,"depth":175,"text":574},{"id":618,"depth":175,"text":619},{"id":679,"depth":175,"text":680},{"id":762,"depth":175,"text":763},{"id":855,"depth":123,"text":856},{"id":927,"depth":123,"text":928},{"id":989,"depth":123,"text":990,"children":1622},[1623,1624,1625],{"id":993,"depth":175,"text":994},{"id":1033,"depth":175,"text":1034},{"id":1105,"depth":175,"text":1106},{"id":1141,"depth":123,"text":1142,"children":1627},[1628,1629,1630,1631,1632],{"id":1145,"depth":175,"text":1146},{"id":1196,"depth":175,"text":1197},{"id":1291,"depth":175,"text":1292},{"id":1308,"depth":175,"text":1309},{"id":1344,"depth":175,"text":1345},{"id":1401,"depth":123,"text":1402},"Ihre selbst gehostete Owlat-Instanz aktuell halten, Backups verwalten, Performance skalieren und häufige Probleme beheben.","md",{},"\u002Fdeveloper\u002Fself-hosting-maintenance",{"title":6,"description":1634},"3.developer\u002F34.self-hosting-maintenance","zV8PUIhtqZYiKNHTYSdmswX2C-Zj8h2e1PTS4BU7x8w",[1642,1644],{"title":1469,"path":1468,"stem":1643,"children":-1},"3.developer\u002F33.self-hosting-production",{"title":1645,"path":1646,"stem":1647,"children":-1},"Desktop-Installer","\u002Fdeveloper\u002Fself-hosting-desktop","3.developer\u002F35.self-hosting-desktop",1786915110109]