[{"data":1,"prerenderedAt":365},["ShallowReactive",2],{"navigation":3,"docs_health-check":56},[4],{"title":5,"path":6,"stem":7,"children":8},"Docs","\u002Fdocs","docs",[9,12,16,20,24,28,32,36,40,44,48,52],{"title":10,"path":6,"stem":11},"Getting started","docs\u002Findex",{"title":13,"path":14,"stem":15},"Adjust Colors","\u002Fdocs\u002Fadjust-colors","docs\u002Fadjust-colors",{"title":17,"path":18,"stem":19},"Areas","\u002Fdocs\u002Fareas","docs\u002Fareas",{"title":21,"path":22,"stem":23},"Boards","\u002Fdocs\u002Fboards","docs\u002Fboards",{"title":25,"path":26,"stem":27},"Cards","\u002Fdocs\u002Fcards","docs\u002Fcards",{"title":29,"path":30,"stem":31},"Comments","\u002Fdocs\u002Fcomments","docs\u002Fcomments",{"title":33,"path":34,"stem":35},"Contributing","\u002Fdocs\u002Fcontributing","docs\u002Fcontributing",{"title":37,"path":38,"stem":39},"Disable Signup","\u002Fdocs\u002Fdisable-signup","docs\u002Fdisable-signup",{"title":41,"path":42,"stem":43},"Health Check","\u002Fdocs\u002Fhealth-check","docs\u002Fhealth-check",{"title":45,"path":46,"stem":47},"MCP Server","\u002Fdocs\u002Fmcp-server","docs\u002Fmcp-server",{"title":49,"path":50,"stem":51},"Migration","\u002Fdocs\u002Fmigration","docs\u002Fmigration",{"title":53,"path":54,"stem":55},"Users","\u002Fdocs\u002Fusers","docs\u002Fusers",{"id":57,"title":41,"body":58,"description":68,"extension":361,"meta":362,"navigation":294,"path":42,"seo":363,"stem":43,"__hash__":364},"docs\u002Fdocs\u002Fhealth-check.md",{"type":59,"value":60,"toc":355},"minimark",[61,65,69,74,85,92,99,139,145,172,175,179,186,208,219,223,226,337,341,351],[62,63,41],"h1",{"id":64},"health-check",[66,67,68],"p",{},"LokalBoards exposes a public health endpoint so you can monitor whether an instance is up and able to reach its database. This is useful for Docker, Docker Compose, reverse proxies, load balancers, and uptime monitors.",[70,71,73],"h2",{"id":72},"the-endpoint","The endpoint",[75,76,81],"pre",{"className":77,"code":79,"language":80},[78],"language-text","GET \u002Fapi\u002Fhealth\n","text",[82,83,79],"code",{"__ignoreMap":84},"",[66,86,87,88,91],{},"It is public (no authentication) and performs a lightweight ",[82,89,90],{},"SELECT 1"," against the database.",[66,93,94,95,98],{},"When the app is running and can reach its database it responds with HTTP ",[82,96,97],{},"200",":",[75,100,104],{"className":101,"code":102,"language":103,"meta":84,"style":84},"language-json shiki shiki-themes github-light github-dark","{ \"status\": \"ok\", \"database\": \"ok\" }\n","json",[82,105,106],{"__ignoreMap":84},[107,108,111,115,119,122,126,129,132,134,136],"span",{"class":109,"line":110},"line",1,[107,112,114],{"class":113},"sVt8B","{ ",[107,116,118],{"class":117},"sj4cs","\"status\"",[107,120,121],{"class":113},": ",[107,123,125],{"class":124},"sZZnC","\"ok\"",[107,127,128],{"class":113},", ",[107,130,131],{"class":117},"\"database\"",[107,133,121],{"class":113},[107,135,125],{"class":124},[107,137,138],{"class":113}," }\n",[66,140,141,142,98],{},"If the database is unreachable it responds with HTTP ",[82,143,144],{},"503",[75,146,148],{"className":101,"code":147,"language":103,"meta":84,"style":84},"{ \"status\": \"error\", \"database\": \"unreachable\" }\n",[82,149,150],{"__ignoreMap":84},[107,151,152,154,156,158,161,163,165,167,170],{"class":109,"line":110},[107,153,114],{"class":113},[107,155,118],{"class":117},[107,157,121],{"class":113},[107,159,160],{"class":124},"\"error\"",[107,162,128],{"class":113},[107,164,131],{"class":117},[107,166,121],{"class":113},[107,168,169],{"class":124},"\"unreachable\"",[107,171,138],{"class":113},[66,173,174],{},"No internal details are leaked in either case.",[70,176,178],{"id":177},"docker","Docker",[66,180,181,182,185],{},"The official Docker image already declares a ",[82,183,184],{},"HEALTHCHECK"," against this endpoint, so you don't need to configure anything. Container health shows up automatically:",[75,187,191],{"className":188,"code":189,"language":190,"meta":84,"style":84},"language-bash shiki shiki-themes github-light github-dark","docker ps\n# STATUS shows e.g. \"Up 2 minutes (healthy)\"\n","bash",[82,192,193,201],{"__ignoreMap":84},[107,194,195,198],{"class":109,"line":110},[107,196,177],{"class":197},"sScJk",[107,199,200],{"class":124}," ps\n",[107,202,204],{"class":109,"line":203},2,[107,205,207],{"class":206},"sJ8bj","# STATUS shows e.g. \"Up 2 minutes (healthy)\"\n",[66,209,210,211,214,215,218],{},"The check uses Node's built-in ",[82,212,213],{},"fetch",", so no extra tools (like ",[82,216,217],{},"curl",") are required inside the image. It allows a short start-up grace period for the server to boot and apply database migrations before the first probe.",[70,220,222],{"id":221},"docker-compose","Docker Compose",[66,224,225],{},"Because the image ships its own health check, Compose reports it without extra configuration. You can also use it to gate dependent services:",[75,227,231],{"className":228,"code":229,"language":230,"meta":84,"style":84},"language-yaml shiki shiki-themes github-light github-dark","services:\n  app:\n    image: florianstrasser\u002Flokalboards:latest\n    # ...\n  db:\n    image: mysql:8\n    # ...\n\n  # Example: only start something after the app is healthy\n  some-dependent-service:\n    depends_on:\n      app:\n        condition: service_healthy\n","yaml",[82,232,233,242,249,260,266,274,284,289,296,302,310,318,326],{"__ignoreMap":84},[107,234,235,239],{"class":109,"line":110},[107,236,238],{"class":237},"s9eBZ","services",[107,240,241],{"class":113},":\n",[107,243,244,247],{"class":109,"line":203},[107,245,246],{"class":237},"  app",[107,248,241],{"class":113},[107,250,252,255,257],{"class":109,"line":251},3,[107,253,254],{"class":237},"    image",[107,256,121],{"class":113},[107,258,259],{"class":124},"florianstrasser\u002Flokalboards:latest\n",[107,261,263],{"class":109,"line":262},4,[107,264,265],{"class":206},"    # ...\n",[107,267,269,272],{"class":109,"line":268},5,[107,270,271],{"class":237},"  db",[107,273,241],{"class":113},[107,275,277,279,281],{"class":109,"line":276},6,[107,278,254],{"class":237},[107,280,121],{"class":113},[107,282,283],{"class":124},"mysql:8\n",[107,285,287],{"class":109,"line":286},7,[107,288,265],{"class":206},[107,290,292],{"class":109,"line":291},8,[107,293,295],{"emptyLinePlaceholder":294},true,"\n",[107,297,299],{"class":109,"line":298},9,[107,300,301],{"class":206},"  # Example: only start something after the app is healthy\n",[107,303,305,308],{"class":109,"line":304},10,[107,306,307],{"class":237},"  some-dependent-service",[107,309,241],{"class":113},[107,311,313,316],{"class":109,"line":312},11,[107,314,315],{"class":237},"    depends_on",[107,317,241],{"class":113},[107,319,321,324],{"class":109,"line":320},12,[107,322,323],{"class":237},"      app",[107,325,241],{"class":113},[107,327,329,332,334],{"class":109,"line":328},13,[107,330,331],{"class":237},"        condition",[107,333,121],{"class":113},[107,335,336],{"class":124},"service_healthy\n",[70,338,340],{"id":339},"uptime-monitoring","Uptime monitoring",[66,342,343,344,347,348,350],{},"Point any monitor (UptimeRobot, Better Stack, a Kubernetes readiness probe, a load-balancer health check, etc.) at ",[82,345,346],{},"https:\u002F\u002Fyour-domain\u002Fapi\u002Fhealth"," and treat a non-",[82,349,97],{}," response as unhealthy. Because the check also verifies database connectivity, it catches the common failure mode where the app process is alive but its database has gone away.",[352,353,354],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":84,"searchDepth":203,"depth":203,"links":356},[357,358,359,360],{"id":72,"depth":203,"text":73},{"id":177,"depth":203,"text":178},{"id":221,"depth":203,"text":222},{"id":339,"depth":203,"text":340},"md",{},{"title":41,"description":68},"8nuKln8DbHwh6d_jjUIYTlB2nVSxZWaD3kX8CdoWVhI",1786546244248]