[{"data":1,"prerenderedAt":1194},["ShallowReactive",2],{"blog-post-otobo-docker-sicherheit-performance-compose-en":3},{"id":4,"title":5,"body":6,"date":1184,"description":1185,"draft":1186,"extension":1187,"meta":1188,"navigation":945,"path":1190,"seo":1191,"stem":1192,"__hash__":1193},"blogEn\u002Fblog\u002Fotobo-docker-sicherheit-performance-compose.md","OTOBO Docker: More Secure and Performant with Hardened Docker Compose",{"type":7,"value":8,"toc":1154},"minimark",[9,13,30,37,40,45,158,170,172,176,185,196,247,253,257,268,278,283,378,385,387,391,395,439,446,449,452,478,482,485,529,533,553,555,559,563,592,596,611,615,635,639,646,648,652,750,756,758,762,768,794,808,813,819,827,886,890,900,902,906,1023,1034,1036,1040,1047,1091,1093,1097,1104,1118,1125,1127,1131,1150],[10,11,5],"h1",{"id":12},"otobo-docker-more-secure-and-performant-with-hardened-docker-compose",[14,15,16,17,24,25,29],"p",{},"The official ",[18,19,23],"a",{"href":20,"rel":21},"https:\u002F\u002Fgithub.com\u002FRotherOSS\u002Fotobo-docker",[22],"nofollow","RotherOSS\u002Fotobo-docker"," stack gets OTOBO up and running quickly — web, MariaDB, Elasticsearch, Redis, and optionally Nginx in just minutes. For ",[26,27,28],"strong",{},"production environments",", \"it runs\" is often not enough: volume permissions, missing network isolation, root containers, and unpinned images are typical vulnerabilities that admins usually only discover under load or during a security audit.",[14,31,32,33,36],{},"This article summarizes how to ",[26,34,35],{},"secure and tune"," OTOBO Docker without bypassing the official image release cycle.",[38,39],"hr",{},[41,42,44],"h2",{"id":43},"initial-situation-what-the-standard-stack-does-well-and-where-it-falls-short","Initial Situation: What the Standard Stack Does Well — and Where It Falls Short",[46,47,48,65],"table",{},[49,50,51],"thead",{},[52,53,54,59,62],"tr",{},[55,56,58],"th",{"align":57},"left","Aspect",[55,60,61],{"align":57},"Official Stack",[55,63,64],{"align":57},"Typical Production Gap",[66,67,68,91,104,117,130,143],"tbody",{},[52,69,70,76,84],{},[71,72,73],"td",{"align":57},[26,74,75],{},"Installation",[71,77,78,79,83],{"align":57},"Proven Compose snippets, ",[80,81,82],"code",{},".env"," samples",[71,85,86,87,90],{"align":57},"Multiple override files in ",[80,88,89],{},"COMPOSE_FILE"," — hard to keep track of",[52,92,93,98,101],{},[71,94,95],{"align":57},[26,96,97],{},"TLS",[71,99,100],{"align":57},"Integrated nginx override",[71,102,103],{"align":57},"Security headers, rate limits, and asset caching often minimal",[52,105,106,111,114],{},[71,107,108],{"align":57},[26,109,110],{},"Network",[71,112,113],{"align":57},"A single shared Docker network",[71,115,116],{"align":57},"DB, Redis, and Elasticsearch theoretically reachable from the proxy",[52,118,119,124,127],{},[71,120,121],{"align":57},[26,122,123],{},"Container Hardening",[71,125,126],{"align":57},"Functionally designed",[71,128,129],{"align":57},"Root UIDs, open volume modes (777), broad capabilities",[52,131,132,137,140],{},[71,133,134],{"align":57},[26,135,136],{},"Performance",[71,138,139],{"align":57},"Defaults",[71,141,142],{"align":57},"MariaDB\u002FRedis\u002FES not tuned for ticket workloads",[52,144,145,150,155],{},[71,146,147],{"align":57},[26,148,149],{},"Operations",[71,151,152],{"align":57},[80,153,154],{},"scripts\u002Fupdate.sh",[71,156,157],{"align":57},"No least-privilege model for technical admins",[14,159,160,161,165,166,169],{},"Starting with OTOBO 11.1, ",[18,162,164],{"href":20,"rel":163},[22],"OTOBO Core and OTOBO Docker have independent release cycles"," — a good time to intentionally own the ",[26,167,168],{},"infrastructure layer"," rather than just pulling images.",[38,171],{},[41,173,175],{"id":174},"two-sensible-approaches","Two Sensible Approaches",[177,178,180,181,184],"h3",{"id":179},"_1-hardening-overlay-for-existing-otobo-docker-installations","1. Hardening Overlay (for Existing ",[80,182,183],{},"otobo-docker"," Installations)",[14,186,187,188,191,192,195],{},"If you are already using the official stack, you can retrofit a ",[26,189,190],{},"Compose override"," plus a ",[26,193,194],{},"host script"," without losing the upstream workflow:",[197,198,199,206,216,230],"ul",{},[200,201,202,205],"li",{},[26,203,204],{},"Non-root UIDs"," for web, daemon, db, redis, and Elasticsearch",[200,207,208,211,212,215],{},[26,209,210],{},"Config bind mount"," to ",[80,213,214],{},"\u002Fopt\u002Fotobo-config\u002F"," (read-only in the container)",[200,217,218,221,222,225,226,229],{},[26,219,220],{},"Volume permissions"," changed from 777 to service-specific owners (e.g., ",[80,223,224],{},"1000:1000",", ",[80,227,228],{},"999:999",")",[200,231,232,235,236,239,240,225,243,246],{},[26,233,234],{},"Least-privilege sudo"," for the ",[80,237,238],{},"otobo-admin"," group (only ",[80,241,242],{},"docker ps\u002Flogs",[80,244,245],{},"sudoedit"," on config, no root shell)",[14,248,249,250,252],{},"The overlay is appended to ",[80,251,89],{}," and applied idempotently via script — including a backup of the Docker volumes before restarting.",[177,254,256],{"id":255},"_2-project-owned-compose-stack-greenfield-controlled-upgrades","2. Project-Owned Compose Stack (Greenfield \u002F Controlled Upgrades)",[14,258,259,260,263,264,267],{},"For new deployments, a ",[26,261,262],{},"dedicated, streamlined Compose stack"," under ",[80,265,266],{},"docker\u002F"," is worth setting up:",[269,270,275],"pre",{"className":271,"code":273,"language":274},[272],"language-text","docker-compose.yml          # Base topology (db, redis, elastic, web, daemon)\ndocker-compose.dev.yml      # HTTP on :8080, DB localhost only\ndocker-compose.prod.yml     # Nginx TLS proxy, no direct host ports\nconfig\u002Fmariadb\u002Fotobo.cnf    # InnoDB tuning (utf8mb4, buffer pool)\nconfig\u002Fredis\u002Fredis.conf     # maxmemory + LRU eviction\nconfig\u002Fnginx\u002F               # TLS, security headers, static cache, rate limits\n","text",[80,276,273],{"__ignoreMap":277},"",[14,279,280],{},[26,281,282],{},"Design Principles:",[46,284,285,295],{},[49,286,287],{},[52,288,289,292],{},[55,290,291],{"align":57},"Principle",[55,293,294],{"align":57},"Implementation",[66,296,297,311,325,340,359,370],{},[52,298,299,302],{},[71,300,301],{"align":57},"Reproducibility",[71,303,304,305,307,308],{"align":57},"Image tags pinned in ",[80,306,82],{},"; upgrade = tag bump + ",[80,309,310],{},"scripts\u002Fupgrade.sh",[52,312,313,316],{},[71,314,315],{"align":57},"Defense in Depth",[71,317,318,225,321,324],{"align":57},[80,319,320],{},"cap_drop: ALL",[80,322,323],{},"no-new-privileges",", non-root where possible",[52,326,327,330],{},[71,328,329],{"align":57},"Network Segmentation",[71,331,332,335,336,339],{"align":57},[80,333,334],{},"frontend"," (nginx ↔ web) and ",[80,337,338],{},"backend"," (datastores) — DB\u002FRedis\u002FES never exposed to the proxy",[52,341,342,344],{},[71,343,136],{"align":57},[71,345,346,347,350,351,354,355,358],{"align":57},"MariaDB ",[80,348,349],{},"innodb_buffer_pool_size",", Redis ",[80,352,353],{},"maxmemory",", ES ",[80,356,357],{},"ES_JAVA_OPTS"," configured",[52,360,361,364],{},[71,362,363],{"align":57},"Observability",[71,365,366,367],{"align":57},"Health checks with ",[80,368,369],{},"depends_on: condition: service_healthy",[52,371,372,375],{},[71,373,374],{"align":57},"Resource Governance",[71,376,377],{"align":57},"CPU\u002Fmemory limits per service",[14,379,380,381,384],{},"In production, ",[26,382,383],{},"only nginx"," terminates TLS; the OTOBO web container stays internal on port 5000.",[38,386],{},[41,388,390],{"id":389},"security-in-detail","Security in Detail",[177,392,394],{"id":393},"network-frontend-vs-backend","Network: Frontend vs. Backend",[269,396,400],{"className":397,"code":398,"language":399,"meta":277,"style":277},"language-yaml shiki shiki-themes one-dark-pro","networks:\n  frontend: # nginx ↔ web\n  backend: # web\u002Fdaemon ↔ db\u002Fredis\u002Felastic\n","yaml",[80,401,402,415,428],{"__ignoreMap":277},[403,404,407,411],"span",{"class":405,"line":406},"line",1,[403,408,410],{"class":409},"sVyAn","networks",[403,412,414],{"class":413},"sn6KH",":\n",[403,416,418,421,424],{"class":405,"line":417},2,[403,419,420],{"class":409},"  frontend",[403,422,423],{"class":413},": ",[403,425,427],{"class":426},"sV9Aq","# nginx ↔ web\n",[403,429,431,434,436],{"class":405,"line":430},3,[403,432,433],{"class":409},"  backend",[403,435,423],{"class":413},[403,437,438],{"class":426},"# web\u002Fdaemon ↔ db\u002Fredis\u002Felastic\n",[14,440,441,442,445],{},"The database and cache are ",[26,443,444],{},"not"," on the same network as the reverse proxy. Even if the nginx container is compromised, direct access to MariaDB remains blocked.",[177,447,123],{"id":448},"container-hardening",[14,450,451],{},"Every service starts with:",[197,453,454,463,468],{},[200,455,456,459,460],{},[80,457,458],{},"cap_drop: [ALL]"," plus minimally required ",[80,461,462],{},"cap_add",[200,464,465],{},[80,466,467],{},"security_opt: [no-new-privileges:true]",[200,469,470,471,225,474,477],{},"Dedicated Linux users (",[80,472,473],{},"mysql:mysql",[80,475,476],{},"redis:redis",", UID mapping for OTOBO)",[177,479,481],{"id":480},"nginx-as-the-single-entry-point","Nginx as the Single Entry Point",[14,483,484],{},"The production override sets up:",[197,486,487,493,499,513,519],{},[200,488,489,492],{},[26,490,491],{},"HTTP → HTTPS"," redirect",[200,494,495,498],{},[26,496,497],{},"TLS 1.2\u002F1.3"," (Mozilla Intermediate Profile)",[200,500,501,225,504,225,507,225,510],{},[26,502,503],{},"HSTS",[80,505,506],{},"X-Frame-Options",[80,508,509],{},"X-Content-Type-Options",[80,511,512],{},"Referrer-Policy",[200,514,515,518],{},[26,516,517],{},"Rate limiting"," and connection limits on dynamic requests",[200,520,521,524,525,528],{},[26,522,523],{},"Proxy cache"," for ",[80,526,527],{},"\u002Fotobo-web\u002F"," assets (skins, JS, CSS) — offloads Perl\u002FPSGI",[177,530,532],{"id":531},"config-outside-the-container","Config Outside the Container",[14,534,535,538,539,542,543,545,546,548,549,552],{},[80,536,537],{},"Config.pm"," and ",[80,540,541],{},"Kernel\u002FConfig\u002FFiles\u002F"," reside on the host under ",[80,544,214],{}," and are mounted read-only. Changes are made via ",[80,547,245],{}," — not via ",[80,550,551],{},"docker exec"," as root inside the running container.",[38,554],{},[41,556,558],{"id":557},"performance-in-detail","Performance in Detail",[177,560,562],{"id":561},"mariadb","MariaDB",[197,564,565,570,576,582],{},[200,566,567,569],{},[80,568,349],{}," ≈ 70–80% of the DB container limit",[200,571,572,575],{},[80,573,574],{},"innodb_log_file_size"," 512M (fewer checkpoint churns than the 256M minimum)",[200,577,578,581],{},[80,579,580],{},"max_allowed_packet"," 128M for large ticket attachments",[200,583,584,587,588,591],{},[80,585,586],{},"utf8mb4"," + ",[80,589,590],{},"dynamic"," row format (mandatory for OTOBO)",[177,593,595],{"id":594},"redis","Redis",[197,597,598,608],{},[200,599,600,601,604,605],{},"Pure cache: ",[80,602,603],{},"maxmemory 512mb"," with ",[80,606,607],{},"allkeys-lru",[200,609,610],{},"No host port — internal backend network only",[177,612,614],{"id":613},"elasticsearch","Elasticsearch",[197,616,617,626,629],{},[200,618,619,622,623],{},[80,620,621],{},"bootstrap.memory_lock: true"," + matching ",[80,624,625],{},"ulimits",[200,627,628],{},"JVM heap ≤ 50% of the container memory limit",[200,630,631,632],{},"Host kernel: ",[80,633,634],{},"vm.max_map_count=262144",[177,636,638],{"id":637},"nginx-static-cache","Nginx Static Cache",[14,640,641,642,645],{},"Static assets are cached at the proxy for seven days (",[80,643,644],{},"X-Cache-Status"," header for debugging). Dynamic ticket requests remain uncached but rate-limited.",[38,647],{},[41,649,651],{"id":650},"resource-budget-reference-values","Resource Budget (Reference Values)",[46,653,654,670],{},[49,655,656],{},[52,657,658,661,664,667],{},[55,659,660],{"align":57},"Service",[55,662,663],{"align":57},"CPU",[55,665,666],{"align":57},"RAM",[55,668,669],{"align":57},"Note",[66,671,672,685,696,711,725,737],{},[52,673,674,676,679,682],{},[71,675,562],{"align":57},[71,677,678],{"align":57},"2",[71,680,681],{"align":57},"2 GB",[71,683,684],{"align":57},"Keep buffer pool in sync",[52,686,687,689,691,693],{},[71,688,614],{"align":57},[71,690,678],{"align":57},[71,692,681],{"align":57},[71,694,695],{"align":57},"Heap ≤ 1 GB",[52,697,698,701,703,705],{},[71,699,700],{"align":57},"Web (PSGI)",[71,702,678],{"align":57},[71,704,681],{"align":57},[71,706,707,710],{"align":57},[80,708,709],{},"OTOBO_WEB_OPTION=deployment"," in prod",[52,712,713,716,719,722],{},[71,714,715],{"align":57},"Daemon",[71,717,718],{"align":57},"1",[71,720,721],{"align":57},"1 GB",[71,723,724],{"align":57},"GenericAgent, escalations",[52,726,727,729,731,734],{},[71,728,595],{"align":57},[71,730,718],{"align":57},[71,732,733],{"align":57},"768 MB",[71,735,736],{"align":57},"maxmemory \u003C limit",[52,738,739,742,744,747],{},[71,740,741],{"align":57},"Nginx",[71,743,718],{"align":57},[71,745,746],{"align":57},"256 MB",[71,748,749],{"align":57},"prod only",[14,751,752,755],{},[26,753,754],{},"Minimum Host:"," 8 GB RAM, 2 vCPUs, 50 GB SSD. For productive teams, 16 GB is recommended.",[38,757],{},[41,759,761],{"id":760},"github-repo-yes-and-where","GitHub Repo: Yes — and Where?",[14,763,764,767],{},[26,765,766],{},"Yes, a public repo makes sense"," — for three reasons:",[769,770,771,777,783],"ol",{},[200,772,773,776],{},[26,774,775],{},"Reusability:"," Other OTOBO admins are looking for these exact patterns (hardening, nginx, tuning).",[200,778,779,782],{},[26,780,781],{},"Transparency:"," Security-relevant infrastructure belongs in versioned, reviewable files — not just in client projects.",[200,784,785,788,789,793],{},[26,786,787],{},"SEO & Community:"," Linking from the ",[18,790,792],{"href":791},"\u002Fsystems\u002Fotobo","Open ITSM Hub"," and OTOBO documentation strengthens the ecosystem.",[14,795,796,799,800,803,804,807],{},[26,797,798],{},"Suggested Repo Name:"," ",[80,801,802],{},"otobo-docker-production"," — as a ",[26,805,806],{},"community infrastructure",", not as a fork of RotherOSS.",[14,809,810],{},[26,811,812],{},"Structure:",[269,814,817],{"className":815,"code":816,"language":274,"meta":277},[272],"otobo-docker-production\u002F\n├── overlay\u002F                 # For users of the official RotherOSS stack\n│   ├── otobo-override-hardening.yml\n│   ├── harden-docker.sh\n│   └── otobo-admin.sudoers\n├── compose\u002F                 # Complete 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                # Decision guide: Overlay vs. Compose\n",[80,818,816],{"__ignoreMap":277},[177,820,822,823,826],{"id":821},"what-does-not-belong-in-the-repo","What ",[26,824,825],{},"Does Not"," Belong in the Repo",[46,828,829,839],{},[49,830,831],{},[52,832,833,836],{},[55,834,835],{"align":57},"Do Not Fork Upstream",[55,837,838],{"align":57},"Instead",[66,840,841,850,861,875],{},[52,842,843,847],{},[71,844,845],{"align":57},[80,846,23],{},[71,848,849],{"align":57},"Reference override files, link upstream in README",[52,851,852,858],{},[71,853,854,857],{"align":57},[80,855,856],{},"RotherOSS\u002Fotobo"," images",[71,859,860],{"align":57},"Pin tags, pull images",[52,862,863,869],{},[71,864,865,866,868],{"align":57},"Client-specific ",[80,867,82],{}," secrets",[71,870,871,874],{"align":57},[80,872,873],{},".env.example"," with placeholders",[52,876,877,880],{},[71,878,879],{"align":57},"TLS private keys",[71,881,882,885],{"align":57},[80,883,884],{},".gitignore"," + cert generation script",[177,887,889],{"id":888},"upstream-contributions","Upstream Contributions",[14,891,892,893,211,896,899],{},"Generic improvements (e.g., default volume permissions, documented non-root UIDs) can be submitted as ",[26,894,895],{},"issues or PRs",[18,897,23],{"href":20,"rel":898},[22]," — the overlay approach remains independent of merge speeds.",[38,901],{},[41,903,905],{"id":904},"quick-start-compose-stack","Quick Start (Compose Stack)",[269,907,911],{"className":908,"code":909,"language":910,"meta":277,"style":277},"language-bash shiki shiki-themes one-dark-pro","cd otobo-docker-production\u002Fcompose\ncp .env.example .env\n# Set OTOBO_DB_ROOT_PASSWORD\n\n# Development (HTTP)\ndocker compose -f docker-compose.yml -f docker-compose.dev.yml up -d\n\n# Production (TLS)\n.\u002Fscripts\u002Fgen-selfsigned-cert.sh helpdesk.example.com   # or a real certificate\ndocker compose -f docker-compose.yml -f docker-compose.prod.yml up -d\n","bash",[80,912,913,923,935,940,947,953,980,985,991,1003],{"__ignoreMap":277},[403,914,915,919],{"class":405,"line":406},[403,916,918],{"class":917},"sjrmR","cd",[403,920,922],{"class":921},"subq3"," otobo-docker-production\u002Fcompose\n",[403,924,925,929,932],{"class":405,"line":417},[403,926,928],{"class":927},"sVbv2","cp",[403,930,931],{"class":921}," .env.example",[403,933,934],{"class":921}," .env\n",[403,936,937],{"class":405,"line":430},[403,938,939],{"class":426},"# Set OTOBO_DB_ROOT_PASSWORD\n",[403,941,943],{"class":405,"line":942},4,[403,944,946],{"emptyLinePlaceholder":945},true,"\n",[403,948,950],{"class":405,"line":949},5,[403,951,952],{"class":426},"# Development (HTTP)\n",[403,954,956,959,962,966,969,971,974,977],{"class":405,"line":955},6,[403,957,958],{"class":927},"docker",[403,960,961],{"class":921}," compose",[403,963,965],{"class":964},"sVC51"," -f",[403,967,968],{"class":921}," docker-compose.yml",[403,970,965],{"class":964},[403,972,973],{"class":921}," docker-compose.dev.yml",[403,975,976],{"class":921}," up",[403,978,979],{"class":964}," -d\n",[403,981,983],{"class":405,"line":982},7,[403,984,946],{"emptyLinePlaceholder":945},[403,986,988],{"class":405,"line":987},8,[403,989,990],{"class":426},"# Production (TLS)\n",[403,992,994,997,1000],{"class":405,"line":993},9,[403,995,996],{"class":927},".\u002Fscripts\u002Fgen-selfsigned-cert.sh",[403,998,999],{"class":921}," helpdesk.example.com",[403,1001,1002],{"class":426},"   # or a real certificate\n",[403,1004,1006,1008,1010,1012,1014,1016,1019,1021],{"class":405,"line":1005},10,[403,1007,958],{"class":927},[403,1009,961],{"class":921},[403,1011,965],{"class":964},[403,1013,968],{"class":921},[403,1015,965],{"class":964},[403,1017,1018],{"class":921}," docker-compose.prod.yml",[403,1020,976],{"class":921},[403,1022,979],{"class":964},[14,1024,1025,1026,1029,1030,1033],{},"Web installer: ",[80,1027,1028],{},"https:\u002F\u002F\u003Cfqdn>\u002Fotobo\u002Finstaller.pl"," — DB host = ",[80,1031,1032],{},"db",".",[38,1035],{},[41,1037,1039],{"id":1038},"quick-start-hardening-overlay","Quick Start (Hardening Overlay)",[14,1041,1042,1043,1046],{},"For existing ",[80,1044,1045],{},"\u002Fopt\u002Fotobo-docker"," installations:",[269,1048,1050],{"className":908,"code":1049,"language":910,"meta":277,"style":277},"# After cloning the overlay\u002F folder\nbash harden-docker.sh              # Volume fix, override, sudoers, restart\nbash harden-docker.sh --dry-run    # Preview only\nbash harden-docker.sh --add-admin max.mustermann\n",[80,1051,1052,1057,1067,1079],{"__ignoreMap":277},[403,1053,1054],{"class":405,"line":406},[403,1055,1056],{"class":426},"# After cloning the overlay\u002F folder\n",[403,1058,1059,1061,1064],{"class":405,"line":417},[403,1060,910],{"class":927},[403,1062,1063],{"class":921}," harden-docker.sh",[403,1065,1066],{"class":426},"              # Volume fix, override, sudoers, restart\n",[403,1068,1069,1071,1073,1076],{"class":405,"line":430},[403,1070,910],{"class":927},[403,1072,1063],{"class":921},[403,1074,1075],{"class":964}," --dry-run",[403,1077,1078],{"class":426},"    # Preview only\n",[403,1080,1081,1083,1085,1088],{"class":405,"line":942},[403,1082,910],{"class":927},[403,1084,1063],{"class":921},[403,1086,1087],{"class":964}," --add-admin",[403,1089,1090],{"class":921}," max.mustermann\n",[38,1092],{},[41,1094,1096],{"id":1095},"conclusion","Conclusion",[14,1098,1099,1100,1103],{},"The official OTOBO Docker stack is the right entry point. For ",[26,1101,1102],{},"production",", building an intentional layer on top pays off:",[197,1105,1106,1112],{},[200,1107,1108,1111],{},[26,1109,1110],{},"Overlay"," — fast, upstream-compatible, for existing installations",[200,1113,1114,1117],{},[26,1115,1116],{},"Dedicated Compose stack"," — maximum control, clear dev\u002Fprod separation, reproducible upgrades",[14,1119,1120,1121,1124],{},"Both are valuable open source contributions — and belong in a dedicated repo, not in ",[80,1122,1123],{},"open-itsm-hub"," (directory\u002Fcontent) and not as a fork of RotherOSS.",[38,1126],{},[41,1128,1130],{"id":1129},"further-reading","Further Reading",[197,1132,1133,1138,1144],{},[200,1134,1135],{},[18,1136,1137],{"href":791},"OTOBO in the Open ITSM Hub",[200,1139,1140],{},[18,1141,1143],{"href":20,"rel":1142},[22],"Official otobo-docker Stack",[200,1145,1146],{},[18,1147,1149],{"href":1148},"\u002Fblog\u002Fotobo-11-1-ki-kurzuberblick","OTOBO 11.1 Quick Overview",[1151,1152,1153],"style",{},"html pre.shiki code .sVyAn, html code.shiki .sVyAn{--shiki-default:#E06C75}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}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 pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}",{"title":277,"searchDepth":417,"depth":417,"links":1155},[1156,1157,1162,1168,1174,1175,1180,1181,1182,1183],{"id":43,"depth":417,"text":44},{"id":174,"depth":417,"text":175,"children":1158},[1159,1161],{"id":179,"depth":430,"text":1160},"1. Hardening Overlay (for Existing otobo-docker Installations)",{"id":255,"depth":430,"text":256},{"id":389,"depth":417,"text":390,"children":1163},[1164,1165,1166,1167],{"id":393,"depth":430,"text":394},{"id":448,"depth":430,"text":123},{"id":480,"depth":430,"text":481},{"id":531,"depth":430,"text":532},{"id":557,"depth":417,"text":558,"children":1169},[1170,1171,1172,1173],{"id":561,"depth":430,"text":562},{"id":594,"depth":430,"text":595},{"id":613,"depth":430,"text":614},{"id":637,"depth":430,"text":638},{"id":650,"depth":417,"text":651},{"id":760,"depth":417,"text":761,"children":1176},[1177,1179],{"id":821,"depth":430,"text":1178},"What Does Not Belong in the Repo",{"id":888,"depth":430,"text":889},{"id":904,"depth":417,"text":905},{"id":1038,"depth":417,"text":1039},{"id":1095,"depth":417,"text":1096},{"id":1129,"depth":417,"text":1130},"2026-07-11","A practical guide to hardened OTOBO Docker Compose — network segmentation, non-root containers, nginx TLS proxy, resource limits, and a hardening overlay for the official RotherOSS stack.",false,"md",{"language":1189},"en","\u002Fblog\u002Fotobo-docker-sicherheit-performance-compose",{"title":5,"description":1185},"blog\u002Fotobo-docker-sicherheit-performance-compose","ChOtO-DeWZG60UTpB-iCwj1bfYSR7ndNRyBINL_WlMI",1787732993867]