[{"data":1,"prerenderedAt":1256},["ShallowReactive",2],{"blog-post-otobo-docker-sicherheit-performance-compose":3},{"id":4,"title":5,"body":6,"date":1246,"description":1247,"draft":1248,"extension":1249,"meta":1250,"navigation":977,"path":1252,"seo":1253,"stem":1254,"__hash__":1255},"blog\u002Fblog\u002Fotobo-docker-sicherheit-performance-compose.md","OTOBO Docker: Sicherer und performanter mit gehärtetem Docker Compose",{"type":7,"value":8,"toc":1214},"minimark",[9,13,30,37,40,45,157,169,171,175,184,195,246,252,256,267,277,282,377,384,386,390,394,437,444,447,450,476,480,483,527,531,551,553,557,561,590,594,609,613,633,637,644,646,650,748,754,756,760,766,792,799,819,828,833,839,846,905,909,920,922,926,1054,1065,1067,1071,1078,1122,1124,1128,1135,1149,1159,1161,1165,1198,1210],[10,11,5],"h1",{"id":12},"otobo-docker-sicherer-und-performanter-mit-gehärtetem-docker-compose",[14,15,16,17,24,25,29],"p",{},"Der offizielle ",[18,19,23],"a",{"href":20,"rel":21},"https:\u002F\u002Fgithub.com\u002FRotherOSS\u002Fotobo-docker",[22],"nofollow","RotherOSS\u002Fotobo-docker","-Stack bringt OTOBO schnell ans Laufen — Web, MariaDB, Elasticsearch, Redis und optional Nginx in wenigen Minuten. Für ",[26,27,28],"strong",{},"Produktionsbetrieb"," reicht „läuft“ oft nicht: Volume-Berechtigungen, fehlende Netzwerk-Trennung, Root-Container und ungepinnte Images sind typische Schwachstellen, die Admins erst unter Last oder im Security-Audit entdecken.",[14,31,32,33,36],{},"Dieser Artikel fasst zusammen, wie sich OTOBO Docker ",[26,34,35],{},"absichern und tunen"," lässt — ohne am offiziellen Image-Release-Zyklus vorbeizubauen.",[38,39],"hr",{},[41,42,44],"h2",{"id":43},"ausgangslage-was-der-standard-stack-gut-macht-und-wo-es-hakt","Ausgangslage: Was der Standard-Stack gut macht — und wo es hakt",[46,47,48,64],"table",{},[49,50,51],"thead",{},[52,53,54,58,61],"tr",{},[55,56,57],"th",{},"Aspekt",[55,59,60],{},"Offizieller Stack",[55,62,63],{},"Typische Produktionslücke",[65,66,67,90,103,116,129,142],"tbody",{},[52,68,69,75,83],{},[70,71,72],"td",{},[26,73,74],{},"Installation",[70,76,77,78,82],{},"Bewährte Compose-Snippets, ",[79,80,81],"code",{},".env","-Samples",[70,84,85,86,89],{},"Mehrere Override-Dateien in ",[79,87,88],{},"COMPOSE_FILE"," — schwer zu überblicken",[52,91,92,97,100],{},[70,93,94],{},[26,95,96],{},"TLS",[70,98,99],{},"Integrierter nginx-Override",[70,101,102],{},"Security-Header, Rate-Limits und Asset-Caching oft minimal",[52,104,105,110,113],{},[70,106,107],{},[26,108,109],{},"Netzwerk",[70,111,112],{},"Ein gemeinsames Docker-Netz",[70,114,115],{},"DB, Redis und Elasticsearch theoretisch vom Proxy erreichbar",[52,117,118,123,126],{},[70,119,120],{},[26,121,122],{},"Container-Härtung",[70,124,125],{},"Funktional ausgelegt",[70,127,128],{},"Root-UIDs, offene Volume-Modi (777), breite Capabilities",[52,130,131,136,139],{},[70,132,133],{},[26,134,135],{},"Performance",[70,137,138],{},"Defaults",[70,140,141],{},"MariaDB\u002FRedis\u002FES nicht auf Ticket-Workload getunt",[52,143,144,149,154],{},[70,145,146],{},[26,147,148],{},"Betrieb",[70,150,151],{},[79,152,153],{},"scripts\u002Fupdate.sh",[70,155,156],{},"Kein Least-Privilege-Modell für technische Admins",[14,158,159,160,164,165,168],{},"Ab OTOBO 11.1 haben ",[18,161,163],{"href":20,"rel":162},[22],"OTOBO Core und OTOBO Docker unabhängige Release-Zyklen"," — ein guter Zeitpunkt, die ",[26,166,167],{},"Infrastruktur-Schicht"," bewusst zu ownen, statt nur Images zu pullen.",[38,170],{},[41,172,174],{"id":173},"zwei-sinnvolle-ansätze","Zwei sinnvolle Ansätze",[176,177,179,180,183],"h3",{"id":178},"_1-hardening-overlay-für-bestehende-otobo-docker-installationen","1. Hardening-Overlay (für bestehende ",[79,181,182],{},"otobo-docker","-Installationen)",[14,185,186,187,190,191,194],{},"Wer bereits den offiziellen Stack nutzt, kann ein ",[26,188,189],{},"Compose-Override"," plus ",[26,192,193],{},"Host-Skript"," nachrüsten — ohne den Upstream-Workflow zu verlieren:",[196,197,198,205,215,229],"ul",{},[199,200,201,204],"li",{},[26,202,203],{},"Non-Root-UIDs"," für Web, Daemon, DB, Redis und Elasticsearch",[199,206,207,210,211,214],{},[26,208,209],{},"Config-Bind-Mount"," nach ",[79,212,213],{},"\u002Fopt\u002Fotobo-config\u002F"," (read-only im Container)",[199,216,217,220,221,224,225,228],{},[26,218,219],{},"Volume-Berechtigungen"," von 777 auf service-spezifische Owner (z. B. ",[79,222,223],{},"1000:1000",", ",[79,226,227],{},"999:999",")",[199,230,231,234,235,238,239,224,242,245],{},[26,232,233],{},"Least-Privilege-Sudo"," für die Gruppe ",[79,236,237],{},"otobo-admin"," (nur ",[79,240,241],{},"docker ps\u002Flogs",[79,243,244],{},"sudoedit"," auf Config, kein Root-Shell)",[14,247,248,249,251],{},"Das Overlay wird in ",[79,250,88],{}," angehängt und per Skript idempotent angewendet — inklusive Backup der Docker-Volumes vor dem Neustart.",[176,253,255],{"id":254},"_2-project-owned-compose-stack-greenfield-kontrollierte-upgrades","2. Project-owned Compose-Stack (Greenfield \u002F kontrollierte Upgrades)",[14,257,258,259,262,263,266],{},"Für neue Deployments lohnt sich ein ",[26,260,261],{},"eigener, schlanker Compose-Stack"," unter ",[79,264,265],{},"docker\u002F",":",[268,269,274],"pre",{"className":270,"code":272,"language":273},[271],"language-text","docker-compose.yml          # Basis-Topologie (db, redis, elastic, web, daemon)\ndocker-compose.dev.yml      # HTTP auf :8080, DB nur localhost\ndocker-compose.prod.yml     # nginx TLS-Proxy, keine direkten Host-Ports\nconfig\u002Fmariadb\u002Fotobo.cnf    # InnoDB-Tuning (utf8mb4, buffer pool)\nconfig\u002Fredis\u002Fredis.conf     # maxmemory + LRU-Eviction\nconfig\u002Fnginx\u002F               # TLS, Security-Header, Static-Cache, Rate-Limits\n","text",[79,275,272],{"__ignoreMap":276},"",[14,278,279],{},[26,280,281],{},"Designprinzipien:",[46,283,284,294],{},[49,285,286],{},[52,287,288,291],{},[55,289,290],{},"Prinzip",[55,292,293],{},"Umsetzung",[65,295,296,310,324,339,358,369],{},[52,297,298,301],{},[70,299,300],{},"Reproduzierbarkeit",[70,302,303,304,306,307],{},"Image-Tags in ",[79,305,81],{}," gepinnt; Upgrade = Tag bump + ",[79,308,309],{},"scripts\u002Fupgrade.sh",[52,311,312,315],{},[70,313,314],{},"Defense in Depth",[70,316,317,224,320,323],{},[79,318,319],{},"cap_drop: ALL",[79,321,322],{},"no-new-privileges",", Non-Root wo möglich",[52,325,326,329],{},[70,327,328],{},"Netzwerk-Segmentierung",[70,330,331,334,335,338],{},[79,332,333],{},"frontend"," (nginx ↔ web) und ",[79,336,337],{},"backend"," (Datenstores) — DB\u002FRedis\u002FES nie am Proxy",[52,340,341,343],{},[70,342,135],{},[70,344,345,346,349,350,353,354,357],{},"MariaDB ",[79,347,348],{},"innodb_buffer_pool_size",", Redis ",[79,351,352],{},"maxmemory",", ES ",[79,355,356],{},"ES_JAVA_OPTS"," abgestimmt",[52,359,360,363],{},[70,361,362],{},"Observability",[70,364,365,366],{},"Healthchecks mit ",[79,367,368],{},"depends_on: condition: service_healthy",[52,370,371,374],{},[70,372,373],{},"Ressourcen-Governance",[70,375,376],{},"CPU\u002FMemory-Limits pro Service",[14,378,379,380,383],{},"In Produktion terminiert ",[26,381,382],{},"nur nginx"," TLS; der OTOBO-Web-Container bleibt intern auf Port 5000.",[38,385],{},[41,387,389],{"id":388},"sicherheit-im-detail","Sicherheit im Detail",[176,391,393],{"id":392},"netzwerk-frontend-vs-backend","Netzwerk: Frontend vs. Backend",[268,395,399],{"className":396,"code":397,"language":398,"meta":276,"style":276},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","networks:\n  frontend:   # nginx ↔ web\n  backend:    # web\u002Fdaemon ↔ db\u002Fredis\u002Felastic\n","yaml",[79,400,401,414,426],{"__ignoreMap":276},[402,403,406,410],"span",{"class":404,"line":405},"line",1,[402,407,409],{"class":408},"swJcz","networks",[402,411,413],{"class":412},"sMK4o",":\n",[402,415,417,420,422],{"class":404,"line":416},2,[402,418,419],{"class":408},"  frontend",[402,421,266],{"class":412},[402,423,425],{"class":424},"sHwdD","   # nginx ↔ web\n",[402,427,429,432,434],{"class":404,"line":428},3,[402,430,431],{"class":408},"  backend",[402,433,266],{"class":412},[402,435,436],{"class":424},"    # web\u002Fdaemon ↔ db\u002Fredis\u002Felastic\n",[14,438,439,440,443],{},"Datenbank und Cache sind ",[26,441,442],{},"nicht"," im gleichen Netz wie der Reverse Proxy. Selbst bei einem kompromittierten nginx-Container bleibt ein direkter Zugriff auf MariaDB ausgeschlossen.",[176,445,122],{"id":446},"container-härtung",[14,448,449],{},"Jeder Service startet mit:",[196,451,452,461,466],{},[199,453,454,457,458],{},[79,455,456],{},"cap_drop: [ALL]"," plus minimal nötige ",[79,459,460],{},"cap_add",[199,462,463],{},[79,464,465],{},"security_opt: [no-new-privileges:true]",[199,467,468,469,224,472,475],{},"dedizierte Linux-User (",[79,470,471],{},"mysql:mysql",[79,473,474],{},"redis:redis",", UID-Mapping für OTOBO)",[176,477,479],{"id":478},"nginx-als-einziger-einstiegspunkt","nginx als einziger Einstiegspunkt",[14,481,482],{},"Der Produktions-Override setzt:",[196,484,485,491,497,511,517],{},[199,486,487,490],{},[26,488,489],{},"HTTP → HTTPS"," Redirect",[199,492,493,496],{},[26,494,495],{},"TLS 1.2\u002F1.3"," (Mozilla Intermediate Profile)",[199,498,499,224,502,224,505,224,508],{},[26,500,501],{},"HSTS",[79,503,504],{},"X-Frame-Options",[79,506,507],{},"X-Content-Type-Options",[79,509,510],{},"Referrer-Policy",[199,512,513,516],{},[26,514,515],{},"Rate-Limiting"," und Connection-Limits auf dynamische Requests",[199,518,519,522,523,526],{},[26,520,521],{},"Proxy-Cache"," für ",[79,524,525],{},"\u002Fotobo-web\u002F","-Assets (Skins, JS, CSS) — entlastet Perl\u002FPSGI",[176,528,530],{"id":529},"config-außerhalb-des-containers","Config außerhalb des Containers",[14,532,533,536,537,540,541,543,544,546,547,550],{},[79,534,535],{},"Config.pm"," und ",[79,538,539],{},"Kernel\u002FConfig\u002FFiles\u002F"," liegen auf dem Host unter ",[79,542,213],{}," und werden read-only gemountet. Änderungen laufen über ",[79,545,244],{}," — nicht über ",[79,548,549],{},"docker exec"," als Root im laufenden Container.",[38,552],{},[41,554,556],{"id":555},"performance-im-detail","Performance im Detail",[176,558,560],{"id":559},"mariadb","MariaDB",[196,562,563,568,574,580],{},[199,564,565,567],{},[79,566,348],{}," ≈ 70–80 % des DB-Container-Limits",[199,569,570,573],{},[79,571,572],{},"innodb_log_file_size"," 512M (weniger Checkpoint-Churn als 256M-Minimum)",[199,575,576,579],{},[79,577,578],{},"max_allowed_packet"," 128M für große Ticket-Anhänge",[199,581,582,585,586,589],{},[79,583,584],{},"utf8mb4"," + ",[79,587,588],{},"dynamic"," Row Format (OTOBO-Pflicht)",[176,591,593],{"id":592},"redis","Redis",[196,595,596,606],{},[199,597,598,599,602,603],{},"Reiner Cache: ",[79,600,601],{},"maxmemory 512mb"," mit ",[79,604,605],{},"allkeys-lru",[199,607,608],{},"Kein Host-Port — nur internes Backend-Netz",[176,610,612],{"id":611},"elasticsearch","Elasticsearch",[196,614,615,624,627],{},[199,616,617,620,621],{},[79,618,619],{},"bootstrap.memory_lock: true"," + passende ",[79,622,623],{},"ulimits",[199,625,626],{},"JVM-Heap ≤ 50 % des Container-Memory-Limits",[199,628,629,630],{},"Host-Kernel: ",[79,631,632],{},"vm.max_map_count=262144",[176,634,636],{"id":635},"nginx-static-cache","nginx Static Cache",[14,638,639,640,643],{},"Statische Assets werden sieben Tage am Proxy gecacht (",[79,641,642],{},"X-Cache-Status","-Header zur Diagnose). Dynamische Ticket-Requests bleiben ungecacht, aber rate-limited.",[38,645],{},[41,647,649],{"id":648},"ressourcen-budget-richtwerte","Ressourcen-Budget (Richtwerte)",[46,651,652,668],{},[49,653,654],{},[52,655,656,659,662,665],{},[55,657,658],{},"Service",[55,660,661],{},"CPU",[55,663,664],{},"RAM",[55,666,667],{},"Hinweis",[65,669,670,683,694,709,723,735],{},[52,671,672,674,677,680],{},[70,673,560],{},[70,675,676],{},"2",[70,678,679],{},"2 GB",[70,681,682],{},"Buffer Pool synchron halten",[52,684,685,687,689,691],{},[70,686,612],{},[70,688,676],{},[70,690,679],{},[70,692,693],{},"Heap ≤ 1 GB",[52,695,696,699,701,703],{},[70,697,698],{},"Web (PSGI)",[70,700,676],{},[70,702,679],{},[70,704,705,708],{},[79,706,707],{},"OTOBO_WEB_OPTION=deployment"," in Prod",[52,710,711,714,717,720],{},[70,712,713],{},"Daemon",[70,715,716],{},"1",[70,718,719],{},"1 GB",[70,721,722],{},"GenericAgent, Eskalationen",[52,724,725,727,729,732],{},[70,726,593],{},[70,728,716],{},[70,730,731],{},"768 MB",[70,733,734],{},"maxmemory \u003C Limit",[52,736,737,740,742,745],{},[70,738,739],{},"nginx",[70,741,716],{},[70,743,744],{},"256 MB",[70,746,747],{},"nur Prod",[14,749,750,753],{},[26,751,752],{},"Minimum-Host:"," 8 GB RAM, 2 vCPU, 50 GB SSD. Für produktive Teams eher 16 GB.",[38,755],{},[41,757,759],{"id":758},"github-repo-ja-und-wo","GitHub-Repo: Ja — und wo?",[14,761,762,765],{},[26,763,764],{},"Ja, ein öffentliches Repo macht Sinn"," — aus drei Gründen:",[767,768,769,775,781],"ol",{},[199,770,771,774],{},[26,772,773],{},"Wiederverwendbarkeit:"," Andere OTOBO-Admins suchen genau diese Patterns (Hardening, nginx, Tuning).",[199,776,777,780],{},[26,778,779],{},"Transparenz:"," Security-relevante Infra gehört in versionierte, reviewbare Dateien — nicht nur in Kundenprojekte.",[199,782,783,786,787,791],{},[26,784,785],{},"SEO & Community:"," Verlinkung aus ",[18,788,790],{"href":789},"\u002Fsystems\u002Fotobo","Open ITSM Hub",", softoft.de und otobo-docs stärkt das OTOBO-Ökosystem.",[176,793,795,796],{"id":794},"empfohlene-heimat-softoft-orga","Empfohlene Heimat: ",[79,797,798],{},"Softoft-Orga",[14,800,801,802,807,808,536,811,814,815,818],{},"Unter ",[18,803,806],{"href":804,"rel":805},"https:\u002F\u002Fgithub.com\u002FSoftoft-Orga",[22],"github.com\u002FSoftoft-Orga"," passt es neben ",[79,809,810],{},"open-ticket-ai",[79,812,813],{},"otobo-znuny-python-client"," — als ",[26,816,817],{},"Community-Infrastruktur",", nicht als Fork von RotherOSS.",[14,820,821,824,825],{},[26,822,823],{},"Vorgeschlagener Repo-Name:"," ",[79,826,827],{},"otobo-docker-production",[14,829,830],{},[26,831,832],{},"Struktur:",[268,834,837],{"className":835,"code":836,"language":273,"meta":276},[271],"otobo-docker-production\u002F\n├── overlay\u002F                 # Für Nutzer des offiziellen RotherOSS-Stacks\n│   ├── otobo-override-hardening.yml\n│   ├── harden-docker.sh\n│   └── otobo-admin.sudoers\n├── compose\u002F                 # Vollständiger project-owned Stack\n│   ├── docker-compose.yml\n│   ├── docker-compose.dev.yml\n│   ├── docker-compose.prod.yml\n│   ├── config\u002F\n│   └── scripts\u002F\n└── README.md                # Entscheidungshilfe: Overlay vs. Compose\n",[79,838,836],{"__ignoreMap":276},[176,840,842,843,845],{"id":841},"was-nicht-ins-repo-gehört","Was ",[26,844,442],{}," ins Repo gehört",[46,847,848,858],{},[49,849,850],{},[52,851,852,855],{},[55,853,854],{},"Nicht upstream forken",[55,856,857],{},"Stattdessen",[65,859,860,869,880,894],{},[52,861,862,866],{},[70,863,864],{},[79,865,23],{},[70,867,868],{},"Override-Dateien referenzieren, README verlinkt Upstream",[52,870,871,877],{},[70,872,873,876],{},[79,874,875],{},"RotherOSS\u002Fotobo"," Images",[70,878,879],{},"Tags pinnen, Images pullen",[52,881,882,888],{},[70,883,884,885,887],{},"Kundenspezifische ",[79,886,81],{},"-Secrets",[70,889,890,893],{},[79,891,892],{},".env.example"," mit Platzhaltern",[52,895,896,899],{},[70,897,898],{},"TLS-Private-Keys",[70,900,901,904],{},[79,902,903],{},".gitignore"," + Cert-Generation-Skript",[176,906,908],{"id":907},"upstream-beiträge","Upstream-Beiträge",[14,910,911,912,915,916,919],{},"Generische Verbesserungen (z. B. Default-Volume-Permissions, dokumentierte Non-Root-UIDs) können als ",[26,913,914],{},"Issues oder PRs"," an ",[18,917,23],{"href":20,"rel":918},[22]," — der Overlay-Ansatz bleibt unabhängig vom Merge-Tempo.",[38,921],{},[41,923,925],{"id":924},"quick-start-compose-stack","Quick Start (Compose-Stack)",[268,927,931],{"className":928,"code":929,"language":930,"meta":276,"style":276},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","git clone https:\u002F\u002Fgithub.com\u002FSoftoft-Orga\u002Fotobo-docker-production.git\ncd otobo-docker-production\u002Fcompose\ncp .env.example .env\n# OTOBO_DB_ROOT_PASSWORD setzen\n\n# Entwicklung (HTTP)\ndocker compose -f docker-compose.yml -f docker-compose.dev.yml up -d\n\n# Produktion (TLS)\n.\u002Fscripts\u002Fgen-selfsigned-cert.sh helpdesk.example.com   # oder echtes Zertifikat\ndocker compose -f docker-compose.yml -f docker-compose.prod.yml up -d\n","bash",[79,932,933,946,955,966,972,979,985,1011,1016,1022,1034],{"__ignoreMap":276},[402,934,935,939,943],{"class":404,"line":405},[402,936,938],{"class":937},"sBMFI","git",[402,940,942],{"class":941},"sfazB"," clone",[402,944,945],{"class":941}," https:\u002F\u002Fgithub.com\u002FSoftoft-Orga\u002Fotobo-docker-production.git\n",[402,947,948,952],{"class":404,"line":416},[402,949,951],{"class":950},"s2Zo4","cd",[402,953,954],{"class":941}," otobo-docker-production\u002Fcompose\n",[402,956,957,960,963],{"class":404,"line":428},[402,958,959],{"class":937},"cp",[402,961,962],{"class":941}," .env.example",[402,964,965],{"class":941}," .env\n",[402,967,969],{"class":404,"line":968},4,[402,970,971],{"class":424},"# OTOBO_DB_ROOT_PASSWORD setzen\n",[402,973,975],{"class":404,"line":974},5,[402,976,978],{"emptyLinePlaceholder":977},true,"\n",[402,980,982],{"class":404,"line":981},6,[402,983,984],{"class":424},"# Entwicklung (HTTP)\n",[402,986,988,991,994,997,1000,1002,1005,1008],{"class":404,"line":987},7,[402,989,990],{"class":937},"docker",[402,992,993],{"class":941}," compose",[402,995,996],{"class":941}," -f",[402,998,999],{"class":941}," docker-compose.yml",[402,1001,996],{"class":941},[402,1003,1004],{"class":941}," docker-compose.dev.yml",[402,1006,1007],{"class":941}," up",[402,1009,1010],{"class":941}," -d\n",[402,1012,1014],{"class":404,"line":1013},8,[402,1015,978],{"emptyLinePlaceholder":977},[402,1017,1019],{"class":404,"line":1018},9,[402,1020,1021],{"class":424},"# Produktion (TLS)\n",[402,1023,1025,1028,1031],{"class":404,"line":1024},10,[402,1026,1027],{"class":937},".\u002Fscripts\u002Fgen-selfsigned-cert.sh",[402,1029,1030],{"class":941}," helpdesk.example.com",[402,1032,1033],{"class":424},"   # oder echtes Zertifikat\n",[402,1035,1037,1039,1041,1043,1045,1047,1050,1052],{"class":404,"line":1036},11,[402,1038,990],{"class":937},[402,1040,993],{"class":941},[402,1042,996],{"class":941},[402,1044,999],{"class":941},[402,1046,996],{"class":941},[402,1048,1049],{"class":941}," docker-compose.prod.yml",[402,1051,1007],{"class":941},[402,1053,1010],{"class":941},[14,1055,1056,1057,1060,1061,1064],{},"Web-Installer: ",[79,1058,1059],{},"https:\u002F\u002F\u003Cfqdn>\u002Fotobo\u002Finstaller.pl"," — DB-Host = ",[79,1062,1063],{},"db",".",[38,1066],{},[41,1068,1070],{"id":1069},"quick-start-hardening-overlay","Quick Start (Hardening-Overlay)",[14,1072,1073,1074,1077],{},"Für bestehende ",[79,1075,1076],{},"\u002Fopt\u002Fotobo-docker","-Installationen:",[268,1079,1081],{"className":928,"code":1080,"language":930,"meta":276,"style":276},"# Nach dem Klonen des overlay\u002F-Ordners\nbash harden-docker.sh              # Volume-Fix, Override, Sudoers, Neustart\nbash harden-docker.sh --dry-run    # Nur anzeigen\nbash harden-docker.sh --add-admin max.mustermann\n",[79,1082,1083,1088,1098,1110],{"__ignoreMap":276},[402,1084,1085],{"class":404,"line":405},[402,1086,1087],{"class":424},"# Nach dem Klonen des overlay\u002F-Ordners\n",[402,1089,1090,1092,1095],{"class":404,"line":416},[402,1091,930],{"class":937},[402,1093,1094],{"class":941}," harden-docker.sh",[402,1096,1097],{"class":424},"              # Volume-Fix, Override, Sudoers, Neustart\n",[402,1099,1100,1102,1104,1107],{"class":404,"line":428},[402,1101,930],{"class":937},[402,1103,1094],{"class":941},[402,1105,1106],{"class":941}," --dry-run",[402,1108,1109],{"class":424},"    # Nur anzeigen\n",[402,1111,1112,1114,1116,1119],{"class":404,"line":968},[402,1113,930],{"class":937},[402,1115,1094],{"class":941},[402,1117,1118],{"class":941}," --add-admin",[402,1120,1121],{"class":941}," max.mustermann\n",[38,1123],{},[41,1125,1127],{"id":1126},"fazit","Fazit",[14,1129,1130,1131,1134],{},"Der offizielle OTOBO-Docker-Stack ist der richtige Einstieg. Für ",[26,1132,1133],{},"Produktion"," lohnt sich eine bewusste Schicht darüber:",[196,1136,1137,1143],{},[199,1138,1139,1142],{},[26,1140,1141],{},"Overlay"," — schnell, upstream-kompatibel, für Bestandsinstallationen",[199,1144,1145,1148],{},[26,1146,1147],{},"Eigener Compose-Stack"," — maximale Kontrolle, klare Dev\u002FProd-Trennung, reproduzierbare Upgrades",[14,1150,1151,1152,1154,1155,1158],{},"Beides ist Open Source wert — und gehört in ein dediziertes GitHub-Repo unter ",[26,1153,798],{},", nicht in ",[79,1156,1157],{},"open-itsm-hub"," (Verzeichnis\u002FContent) und nicht als Fork von RotherOSS.",[38,1160],{},[41,1162,1164],{"id":1163},"weiterführende-links","Weiterführende Links",[196,1166,1167,1172,1178,1185,1191],{},[199,1168,1169],{},[18,1170,1171],{"href":789},"OTOBO im Open ITSM Hub",[199,1173,1174],{},[18,1175,1177],{"href":20,"rel":1176},[22],"Offizieller otobo-docker Stack",[199,1179,1180],{},[18,1181,1184],{"href":1182,"rel":1183},"https:\u002F\u002Fotobo-docs.softoft.de\u002Fde\u002Fquick-start\u002Finstallation\u002Fdocker-compose\u002F",[22],"OTOBO Docker Installationsguide (softoft Community Docs)",[199,1186,1187],{},[18,1188,1190],{"href":1189},"\u002Fblog\u002Fotobo-11-1-ki-kurzuberblick","OTOBO 11.1 Kurzüberblick",[199,1192,1193],{},[18,1194,1197],{"href":1195,"rel":1196},"https:\u002F\u002Fwww.openticketai.com\u002F",[22],"Open Ticket AI — Automation für OTOBO & Co.",[14,1199,1200],{},[1201,1202,1203,1204,1209],"em",{},"Geplanter Code-Stand: ",[18,1205,1208],{"href":1206,"rel":1207},"https:\u002F\u002Fgithub.com\u002FSoftoft-Orga\u002Fotobo-docker-production",[22],"github.com\u002FSoftoft-Orga\u002Fotobo-docker-production"," — Repo wird aus dem IT-Unlimited-Projekt extrahiert.",[1211,1212,1213],"style",{},"html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}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);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}",{"title":276,"searchDepth":416,"depth":416,"links":1215},[1216,1217,1222,1228,1234,1235,1242,1243,1244,1245],{"id":43,"depth":416,"text":44},{"id":173,"depth":416,"text":174,"children":1218},[1219,1221],{"id":178,"depth":428,"text":1220},"1. Hardening-Overlay (für bestehende otobo-docker-Installationen)",{"id":254,"depth":428,"text":255},{"id":388,"depth":416,"text":389,"children":1223},[1224,1225,1226,1227],{"id":392,"depth":428,"text":393},{"id":446,"depth":428,"text":122},{"id":478,"depth":428,"text":479},{"id":529,"depth":428,"text":530},{"id":555,"depth":416,"text":556,"children":1229},[1230,1231,1232,1233],{"id":559,"depth":428,"text":560},{"id":592,"depth":428,"text":593},{"id":611,"depth":428,"text":612},{"id":635,"depth":428,"text":636},{"id":648,"depth":416,"text":649},{"id":758,"depth":416,"text":759,"children":1236},[1237,1239,1241],{"id":794,"depth":428,"text":1238},"Empfohlene Heimat: Softoft-Orga",{"id":841,"depth":428,"text":1240},"Was nicht ins Repo gehört",{"id":907,"depth":428,"text":908},{"id":924,"depth":416,"text":925},{"id":1069,"depth":416,"text":1070},{"id":1126,"depth":416,"text":1127},{"id":1163,"depth":416,"text":1164},"2026-07-11","Praxisleitfaden zu gehärtetem OTOBO-Docker-Compose — Netzwerk-Segmentierung, Non-Root-Container, nginx-TLS-Proxy, Ressourcenlimits und ein Hardening-Overlay für den offiziellen RotherOSS-Stack.",false,"md",{"language":1251},"de","\u002Fblog\u002Fotobo-docker-sicherheit-performance-compose",{"title":5,"description":1247},"blog\u002Fotobo-docker-sicherheit-performance-compose","LHy_Y8nWPW7l0ivhaB_xxXYIyqsjT2JVcXsC0QOrMno",1785427360557]