[{"data":1,"prerenderedAt":746},["ShallowReactive",2],{"navigation":3,"/docs/framework-guides/laravel/health-checks":249,"/docs/framework-guides/laravel/health-checks-surround":741},[4],{"title":5,"path":6,"stem":7,"children":8},"Docs","/docs","docs",[9,12,48,77,132,160,185,206,219,236],{"title":10,"path":6,"stem":11},"","docs/index",{"title":13,"path":14,"stem":15,"children":16,"icon":47},"Getting Started","/docs/getting-started","docs/1.getting-started/1.index",[17,19,23,27,31,35,39,43],{"title":18,"path":14,"stem":15},"Introduction",{"title":20,"path":21,"stem":22},"Container basics","/docs/getting-started/container-basics","docs/1.getting-started/2.container-basics",{"title":24,"path":25,"stem":26},"Installation","/docs/getting-started/installation","docs/1.getting-started/3.installation",{"title":28,"path":29,"stem":30},"These images vs others","/docs/getting-started/these-images-vs-others","docs/1.getting-started/4.these-images-vs-others",{"title":32,"path":33,"stem":34},"Choosing an image","/docs/getting-started/choosing-an-image","docs/1.getting-started/5.choosing-an-image",{"title":36,"path":37,"stem":38},"Default configurations","/docs/getting-started/default-configurations","docs/1.getting-started/6.default-configurations",{"title":40,"path":41,"stem":42},"Migrating from official PHP images","/docs/getting-started/migrating-from-official-php-images","docs/1.getting-started/7.migrating-from-official-php-images",{"title":44,"path":45,"stem":46},"Contributing","/docs/getting-started/contributing","docs/1.getting-started/99.contributing",false,{"title":49,"path":50,"stem":51,"children":52,"page":47},"Image Variations","/docs/image-variations","docs/2.image-variations",[53,57,61,65,69,73],{"title":54,"path":55,"stem":56},"CLI","/docs/image-variations/cli","docs/2.image-variations/cli",{"title":58,"path":59,"stem":60},"FPM","/docs/image-variations/fpm","docs/2.image-variations/fpm",{"title":62,"path":63,"stem":64},"FPM-Apache","/docs/image-variations/fpm-apache","docs/2.image-variations/fpm-apache",{"title":66,"path":67,"stem":68},"FPM-NGINX","/docs/image-variations/fpm-nginx","docs/2.image-variations/fpm-nginx",{"title":70,"path":71,"stem":72},"FrankenPHP","/docs/image-variations/frankenphp","docs/2.image-variations/frankenphp",{"title":74,"path":75,"stem":76},"NGINX Unit (removed)","/docs/image-variations/unit","docs/2.image-variations/unit",{"title":78,"path":79,"stem":80,"children":81,"page":47},"Framework Guides","/docs/framework-guides","docs/3.framework-guides",[82,123],{"title":83,"icon":47,"defaultOpen":47,"path":84,"stem":85,"children":86,"page":47},"Laravel","/docs/framework-guides/laravel","docs/3.framework-guides/1.laravel",[87,91,95,99,103,107,111,115,119],{"title":88,"path":89,"stem":90},"Automations","/docs/framework-guides/laravel/automations","docs/3.framework-guides/1.laravel/1.automations",{"title":92,"path":93,"stem":94},"Running workers","/docs/framework-guides/laravel/workers","docs/3.framework-guides/1.laravel/2.workers",{"title":96,"path":97,"stem":98},"Health checks","/docs/framework-guides/laravel/health-checks","docs/3.framework-guides/1.laravel/3.health-checks",{"title":100,"path":101,"stem":102},"Horizon","/docs/framework-guides/laravel/horizon","docs/3.framework-guides/1.laravel/4.horizon",{"title":104,"path":105,"stem":106},"Nightwatch","/docs/framework-guides/laravel/nightwatch","docs/3.framework-guides/1.laravel/5.nightwatch",{"title":108,"path":109,"stem":110},"Octane","/docs/framework-guides/laravel/octane","docs/3.framework-guides/1.laravel/6.octane",{"title":112,"path":113,"stem":114},"Queue","/docs/framework-guides/laravel/queue","docs/3.framework-guides/1.laravel/7.queue",{"title":116,"path":117,"stem":118},"Reverb","/docs/framework-guides/laravel/reverb","docs/3.framework-guides/1.laravel/8.reverb",{"title":120,"path":121,"stem":122},"Task scheduler","/docs/framework-guides/laravel/task-scheduler","docs/3.framework-guides/1.laravel/9.task-scheduler",{"title":124,"icon":47,"defaultOpen":47,"path":125,"stem":126,"children":127,"page":47},"WordPress","/docs/framework-guides/wordpress","docs/3.framework-guides/2.wordpress",[128],{"title":129,"path":130,"stem":131},"Using WordPress with Docker","/docs/framework-guides/wordpress/using-wordpress-with-docker","docs/3.framework-guides/2.wordpress/4.using-wordpress-with-docker",{"title":133,"path":134,"stem":135,"children":136,"page":47},"Deployment And Production","/docs/deployment-and-production","docs/4.deployment-and-production",[137,141,145,148,152,156],{"title":138,"path":139,"stem":140},"Packaging your app for deployment","/docs/deployment-and-production/packaging-your-app-for-deployment","docs/4.deployment-and-production/1.packaging-your-app-for-deployment",{"title":142,"path":143,"stem":144},"Configuring SSL","/docs/deployment-and-production/configuring-ssl","docs/4.deployment-and-production/2.configuring-ssl",{"title":96,"path":146,"stem":147},"/docs/deployment-and-production/health-checks","docs/4.deployment-and-production/3.health-checks",{"title":149,"path":150,"stem":151},"Configuring trusted proxies","/docs/deployment-and-production/configuring-trusted-proxies","docs/4.deployment-and-production/4.configuring-trusted-proxies",{"title":153,"path":154,"stem":155},"Production performance tuning","/docs/deployment-and-production/production-performance-tuning","docs/4.deployment-and-production/5.production-performance-tuning",{"title":157,"path":158,"stem":159},"Choosing a host","/docs/deployment-and-production/choosing-a-host","docs/4.deployment-and-production/6.choosing-a-host",{"title":161,"icon":47,"defaultOpen":47,"path":162,"stem":163,"children":164,"page":47},"Customization","/docs/customizing-the-image","docs/5.customizing-the-image",[165,169,173,177,181],{"title":166,"path":167,"stem":168},"Changing php.ini settings","/docs/customizing-the-image/changing-common-php-settings","docs/5.customizing-the-image/1.changing-common-php-settings",{"title":170,"path":171,"stem":172},"Installing PHP extensions","/docs/customizing-the-image/installing-additional-php-extensions","docs/5.customizing-the-image/2.installing-additional-php-extensions",{"title":174,"path":175,"stem":176},"Adding start up scripts","/docs/customizing-the-image/adding-your-own-start-up-scripts","docs/5.customizing-the-image/3.adding-your-own-start-up-scripts",{"title":178,"path":179,"stem":180},"Using S6 Overlay","/docs/customizing-the-image/using-s6-overlay","docs/5.customizing-the-image/4.using-s6-overlay",{"title":182,"path":183,"stem":184},"Understanding file permissions","/docs/customizing-the-image/understanding-file-permissions","docs/5.customizing-the-image/5.understanding-file-permissions",{"title":186,"icon":47,"defaultOpen":47,"path":187,"stem":188,"children":189,"page":47},"Upgrading","/docs/upgrading","docs/6.upgrading",[190,194,198,202],{"title":191,"path":192,"stem":193},"Upgrade guide","/docs/upgrading/upgrade-guide","docs/6.upgrading/1.upgrade-guide",{"title":195,"path":196,"stem":197},"Upgrade to v5","/docs/upgrading/upgrade-to-v5","docs/6.upgrading/2.upgrade-to-v5",{"title":199,"path":200,"stem":201},"Upgrade to v4","/docs/upgrading/upgrade-to-v4","docs/6.upgrading/3.upgrade-to-v4",{"title":203,"path":204,"stem":205},"Upgrade to v3","/docs/upgrading/upgrade-to-v3","docs/6.upgrading/4.upgrade-to-v3",{"title":207,"path":208,"stem":209,"children":210,"page":47},"Troubleshooting","/docs/troubleshooting","docs/7.troubleshooting",[211,215],{"title":212,"path":213,"stem":214},"Common issues","/docs/troubleshooting/common-issues","docs/7.troubleshooting/1.common-issues",{"title":216,"path":217,"stem":218},"Getting help","/docs/troubleshooting/getting-help","docs/7.troubleshooting/2.getting-help",{"title":220,"path":221,"stem":222,"children":223,"page":47},"Security","/docs/security","docs/8.security",[224,228,232],{"title":225,"path":226,"stem":227},"How images are built","/docs/security/how-images-are-built","docs/8.security/1.how-images-are-built",{"title":229,"path":230,"stem":231},"Verifying images","/docs/security/verifying-images","docs/8.security/2.verifying-images",{"title":233,"path":234,"stem":235},"Vulnerability scanning","/docs/security/vulnerability-scanning","docs/8.security/3.vulnerability-scanning",{"title":237,"path":238,"stem":239,"children":240,"page":47},"Reference","/docs/reference","docs/9.reference",[241,245],{"title":242,"path":243,"stem":244},"Environment variable specification","/docs/reference/environment-variable-specification","docs/9.reference/1.environment-variable-specification",{"title":246,"path":247,"stem":248},"Command reference","/docs/reference/command-reference","docs/9.reference/2.command-reference",{"id":250,"title":96,"body":251,"description":732,"extension":733,"links":734,"meta":735,"navigation":738,"path":97,"redirect":734,"seo":739,"stem":98,"__hash__":740},"docs/docs/3.framework-guides/1.laravel/3.health-checks.md",{"type":252,"value":253,"toc":725},"minimark",[254,266,345,368,373,380,429,435,441,462,468,484,487,491,494,607,614,709,716,721],[255,256,257],"lead-p",{},[258,259,260,261,265],"p",{},"A container can look healthy while your app is broken. A bad ",[262,263,264],"code",{},".env"," value or a crashing service provider still leaves the web server answering. Add one line, and Docker checks that Laravel itself boots.",[267,268,273],"pre",{"className":269,"code":270,"filename":271,"language":272,"meta":10,"style":10},"language-yaml shiki shiki-themes github-dark","services:\n  app:\n    image: my-org/my-app:1.0.0\n    ports:\n      - \"80:8080\"\n    environment:\n      HEALTHCHECK_PATH: \"/up\"\n","compose.yml","yaml",[262,274,275,288,296,309,317,326,334],{"__ignoreMap":10},[276,277,280,284],"span",{"class":278,"line":279},"line",1,[276,281,283],{"class":282},"s4JwU","services",[276,285,287],{"class":286},"s95oV",":\n",[276,289,291,294],{"class":278,"line":290},2,[276,292,293],{"class":282},"  app",[276,295,287],{"class":286},[276,297,299,302,305],{"class":278,"line":298},3,[276,300,301],{"class":282},"    image",[276,303,304],{"class":286},": ",[276,306,308],{"class":307},"sU2Wk","my-org/my-app:1.0.0\n",[276,310,312,315],{"class":278,"line":311},4,[276,313,314],{"class":282},"    ports",[276,316,287],{"class":286},[276,318,320,323],{"class":278,"line":319},5,[276,321,322],{"class":286},"      - ",[276,324,325],{"class":307},"\"80:8080\"\n",[276,327,329,332],{"class":278,"line":328},6,[276,330,331],{"class":282},"    environment",[276,333,287],{"class":286},[276,335,337,340,342],{"class":278,"line":336},7,[276,338,339],{"class":282},"      HEALTHCHECK_PATH",[276,341,304],{"class":286},[276,343,344],{"class":307},"\"/up\"\n",[258,346,347,348,359,360,363,364,367],{},"Laravel 11 and newer ship the ",[349,350,355,358],"a",{"href":351,"rel":352,"target":354},"https://laravel.com/docs/13.x/deployment#the-health-route",[353],"nofollow","_blank",[262,356,357],{},"/up"," health route",". It returns ",[262,361,362],{},"200"," when your app boots and ",[262,365,366],{},"500"," when it throws an exception. With the official PHP images, you'd write this health check yourself.",[369,370],"youtube-video",{"id":371,"title":372},"cuYIB5VrH1Q","Docker Health Checks with PHP & Laravel: New Feature for serversideup/php",[374,375,377,379],"h2",{"id":376},"up-checks-what-your-users-hit",[262,378,357],{}," checks what your users hit",[381,382,383,405],"table",{},[384,385,386],"thead",{},[387,388,389,393,400],"tr",{},[390,391,392],"th",{},"What gets checked",[390,394,396,397],{"align":395},"center","Default ",[262,398,399],{},"/healthcheck",[390,401,402],{"align":395},[262,403,404],{},"HEALTHCHECK_PATH: \"/up\"",[406,407,408,419],"tbody",{},[387,409,410,414,417],{},[411,412,413],"td",{},"The web server responds",[411,415,416],{"align":395},"✅",[411,418,416],{"align":395},[387,420,421,424,427],{},[411,422,423],{},"Laravel boots",[411,425,426],{"align":395},"❌",[411,428,416],{"align":395},[258,430,431,432,434],{},"The default check never reaches your app. That's fine for a plain PHP site. For Laravel, ",[262,433,357],{}," catches the failures that matter.",[258,436,437,438,440],{},"When ",[262,439,357],{}," fails, Docker marks the container unhealthy. Docker Swarm replaces it. During a rolling update, Swarm waits for each new container to pass. If one fails, the update pauses instead of rolling a broken release onto every replica.",[258,442,443,446,447,450,451,454,455,458,459,461],{},[262,444,445],{},"HEALTHCHECK_PATH"," works in ",[262,448,449],{},"fpm-nginx",", ",[262,452,453],{},"fpm-apache",", and ",[262,456,457],{},"frankenphp",". ",[349,460,96],{"href":146}," explains the timing and what each variation checks.",[374,463,465,466],{"id":464},"add-your-own-checks-to-up","Add your own checks to ",[262,467,357],{},[258,469,470,471,474,475,477,478,480,481,483],{},"Laravel fires a ",[262,472,473],{},"DiagnosingHealth"," event on each request to ",[262,476,357],{},". Listen for it to check your database, cache, or anything else your app needs. Throw an exception, and ",[262,479,357],{}," returns ",[262,482,366],{},".",[258,485,486],{},"Keep the checks fast. Docker runs the health check every 10 seconds and gives it 3 seconds to answer. Check only what the container can't run without: when a database check fails, Swarm replaces every app container at once.",[374,488,490],{"id":489},"every-worker-gets-a-check","Every worker gets a check",[258,492,493],{},"Queue, Horizon, and scheduler containers don't run a web server. The image's built-in check fails in them. Every image ships a script for each Laravel worker instead:",[381,495,496,509],{},[384,497,498],{},[387,499,500,503,506],{},[390,501,502],{},"Script",[390,504,505],{},"What it runs",[390,507,508],{},"Use it for",[406,510,511,527,543,559,575,591],{},[387,512,513,518,523],{},[411,514,515],{},[262,516,517],{},"healthcheck-horizon",[411,519,520],{},[262,521,522],{},"php artisan horizon:status",[411,524,525],{},[349,526,100],{"href":101},[387,528,529,534,539],{},[411,530,531],{},[262,532,533],{},"healthcheck-nightwatch",[411,535,536],{},[262,537,538],{},"php artisan nightwatch:status",[411,540,541],{},[349,542,104],{"href":105},[387,544,545,550,555],{},[411,546,547],{},[262,548,549],{},"healthcheck-octane",[411,551,552],{},[262,553,554],{},"php artisan octane:status",[411,556,557],{},[349,558,108],{"href":109},[387,560,561,566,571],{},[411,562,563],{},[262,564,565],{},"healthcheck-queue",[411,567,568],{},[262,569,570],{},"pgrep -f \"queue:work\"",[411,572,573],{},[349,574,112],{"href":113},[387,576,577,582,587],{},[411,578,579],{},[262,580,581],{},"healthcheck-reverb",[411,583,584],{},[262,585,586],{},"pgrep -f \"reverb:start\"",[411,588,589],{},[349,590,116],{"href":117},[387,592,593,598,603],{},[411,594,595],{},[262,596,597],{},"healthcheck-schedule",[411,599,600],{},[262,601,602],{},"pgrep -f \"schedule:work\"",[411,604,605],{},[349,606,120],{"href":121},[258,608,609,610,613],{},"Set the script as the container's ",[262,611,612],{},"healthcheck",":",[267,615,617],{"className":269,"code":616,"filename":271,"language":272,"meta":10,"style":10},"services:\n  queue:\n    image: my-org/my-app:1.0.0\n    command: [\"php\", \"artisan\", \"queue:work\"]\n    stop_signal: SIGTERM\n    healthcheck:\n      test: [\"CMD\", \"healthcheck-queue\"]\n      start_period: 10s\n",[262,618,619,625,632,640,664,674,681,698],{"__ignoreMap":10},[276,620,621,623],{"class":278,"line":279},[276,622,283],{"class":282},[276,624,287],{"class":286},[276,626,627,630],{"class":278,"line":290},[276,628,629],{"class":282},"  queue",[276,631,287],{"class":286},[276,633,634,636,638],{"class":278,"line":298},[276,635,301],{"class":282},[276,637,304],{"class":286},[276,639,308],{"class":307},[276,641,642,645,648,651,653,656,658,661],{"class":278,"line":311},[276,643,644],{"class":282},"    command",[276,646,647],{"class":286},": [",[276,649,650],{"class":307},"\"php\"",[276,652,450],{"class":286},[276,654,655],{"class":307},"\"artisan\"",[276,657,450],{"class":286},[276,659,660],{"class":307},"\"queue:work\"",[276,662,663],{"class":286},"]\n",[276,665,666,669,671],{"class":278,"line":319},[276,667,668],{"class":282},"    stop_signal",[276,670,304],{"class":286},[276,672,673],{"class":307},"SIGTERM\n",[276,675,676,679],{"class":278,"line":328},[276,677,678],{"class":282},"    healthcheck",[276,680,287],{"class":286},[276,682,683,686,688,691,693,696],{"class":278,"line":336},[276,684,685],{"class":282},"      test",[276,687,647],{"class":286},[276,689,690],{"class":307},"\"CMD\"",[276,692,450],{"class":286},[276,694,695],{"class":307},"\"healthcheck-queue\"",[276,697,663],{"class":286},[276,699,701,704,706],{"class":278,"line":700},8,[276,702,703],{"class":282},"      start_period",[276,705,304],{"class":286},[276,707,708],{"class":307},"10s\n",[258,710,711,712,715],{},"The ",[262,713,714],{},"pgrep"," scripts confirm the process is running. They don't check that it's processing jobs. The Artisan scripts ask Laravel for the worker's status, and they boot your app on every check.",[258,717,718,720],{},[349,719,92],{"href":93}," has a full Compose file with the web server, Horizon, and the scheduler, each with its health check.",[722,723,724],"style",{},"html pre.shiki code .s4JwU, html code.shiki .s4JwU{--shiki-default:#85E89D}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#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);}",{"title":10,"searchDepth":290,"depth":290,"links":726},[727,729,731],{"id":376,"depth":290,"text":728},"/up checks what your users hit",{"id":464,"depth":290,"text":730},"Add your own checks to /up",{"id":489,"depth":290,"text":490},"Point the Docker health check at Laravel with one line, and check queue workers, Horizon, the scheduler, and Reverb with built-in scripts.","md",null,{"head":736,"layout":7},{"title":737},"Laravel Health Checks with Docker - Docker PHP - Server Side Up",true,{"title":96,"description":732},"0zpP7IwH4GyyvajeobIB77lLckCRFX_xb6mZz8ZgCeQ",[742,744],{"title":92,"path":93,"stem":94,"description":743,"children":-1},"Run the Laravel scheduler, queue workers, Horizon, Reverb, and Nightwatch in their own containers from the same image as your web service.",{"title":100,"path":101,"stem":102,"description":745,"children":-1},"Run Laravel Horizon in its own Docker container to process and monitor Redis queues.",1793811945939]