[{"data":1,"prerenderedAt":854},["ShallowReactive",2],{"navigation":3,"/docs/framework-guides/laravel/workers":249,"/docs/framework-guides/laravel/workers-surround":849},[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":92,"body":251,"description":841,"extension":842,"links":843,"meta":844,"navigation":602,"path":93,"redirect":843,"seo":847,"stem":94,"__hash__":848},"docs/docs/3.framework-guides/1.laravel/2.workers.md",{"type":252,"value":253,"toc":835},"minimark",[254,266,274,279,383,387,472,479,499,503,518,816,820,831],[255,256,257],"lead-p",{},[258,259,260,261,265],"p",{},"Run each Laravel background process in its own container, from the same image as your web service. Each worker container needs three settings: the Artisan ",[262,263,264],"code",{},"command",", a stop signal, and a health check for that process.",[267,268,271],"tip",{"target":269,"to":270},"_blank","https://getspin.pro/docs/services/laravel-queues",[258,272,273],{},"Spin Pro sets up the scheduler, queues, and Horizon on your own server with zero-downtime deployments.",[275,276,278],"h2",{"id":277},"workers","Workers",[280,281,282,298],"table",{},[283,284,285],"thead",{},[286,287,288,292,295],"tr",{},[289,290,291],"th",{},"Worker",[289,293,294],{},"Command",[289,296,297],{},"Health check",[299,300,301,319,335,351,367],"tbody",{},[286,302,303,309,314],{},[304,305,306],"td",{},[307,308,120],"a",{"href":121},[304,310,311],{},[262,312,313],{},"php artisan schedule:work",[304,315,316],{},[262,317,318],{},"healthcheck-schedule",[286,320,321,325,330],{},[304,322,323],{},[307,324,112],{"href":113},[304,326,327],{},[262,328,329],{},"php artisan queue:work",[304,331,332],{},[262,333,334],{},"healthcheck-queue",[286,336,337,341,346],{},[304,338,339],{},[307,340,100],{"href":101},[304,342,343],{},[262,344,345],{},"php artisan horizon",[304,347,348],{},[262,349,350],{},"healthcheck-horizon",[286,352,353,357,362],{},[304,354,355],{},[307,356,116],{"href":117},[304,358,359],{},[262,360,361],{},"php artisan reverb:start",[304,363,364],{},[262,365,366],{},"healthcheck-reverb",[286,368,369,373,378],{},[304,370,371],{},[307,372,104],{"href":105},[304,374,375],{},[262,376,377],{},"php artisan nightwatch:agent",[304,379,380],{},[262,381,382],{},"healthcheck-nightwatch",[275,384,386],{"id":385},"every-worker-needs-three-settings","Every worker needs three settings",[388,389,390,414,460],"ul",{},[391,392,393,397,398,401,402,405,406,409,410,413],"li",{},[394,395,396],"strong",{},"Command."," The images set ",[262,399,400],{},"WORKDIR"," to ",[262,403,404],{},"/var/www/html"," (",[262,407,408],{},"APP_BASE_DIR","), so ",[262,411,412],{},"php artisan"," works as written. The container runs only this process: no web server, no PHP-FPM.",[391,415,416,422,423,426,427,430,431,434,435,438,439,442,443,446,447,449,450,453,454,457,458,421],{},[394,417,418,421],{},[262,419,420],{},"stop_signal: SIGTERM","."," The ",[262,424,425],{},"fpm",", ",[262,428,429],{},"fpm-nginx",", and ",[262,432,433],{},"fpm-apache"," images set ",[262,436,437],{},"STOPSIGNAL SIGQUIT",", the graceful stop signal for PHP-FPM and S6 Overlay. Laravel's workers stop gracefully on ",[262,440,441],{},"SIGTERM",", and Horizon doesn't handle ",[262,444,445],{},"SIGQUIT"," at all, so set ",[262,448,441],{}," on every worker. The ",[262,451,452],{},"cli"," and ",[262,455,456],{},"frankenphp"," images already stop with ",[262,459,441],{},[391,461,462,465,466,468,469,471],{},[394,463,464],{},"A health check."," The image's own health check tests the web server or PHP-FPM, which isn't running in a worker container. Without an override, a worker built from a web variation is marked unhealthy. The ",[262,467,452],{}," variation has no health check. See ",[307,470,96],{"href":97}," for the scripts.",[258,473,474,475,478],{},"Docker kills a container 10 seconds after the stop signal. If your jobs run longer, raise ",[262,476,477],{},"stop_grace_period"," on the worker so it can finish the current job.",[480,481,482],"caution",{},[258,483,484,487,488,491,492,495,496,498],{},[307,485,486],{"href":89},"Laravel automations",", including migrations, run in every container that starts with ",[262,489,490],{},"AUTORUN_ENABLED=true",", whatever its command. If your workers share the web service's environment through an ",[262,493,494],{},"env_file"," or YAML anchor, each one migrates the database at startup. Set ",[262,497,490],{}," on one service only.",[275,500,502],{"id":501},"full-compose-example","Full Compose example",[258,504,505,506,509,510,513,514,517],{},"This example builds on an application image made from ",[262,507,508],{},"serversideup/php:8.5-fpm-nginx",". Run ",[262,511,512],{},"queue"," or ",[262,515,516],{},"horizon",", not both: Horizon starts its own queue workers.",[519,520,525],"pre",{"className":521,"code":522,"filename":523,"language":524,"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      AUTORUN_ENABLED: \"true\"\n\n  horizon:\n    image: my-org/my-app:1.0.0\n    command: [\"php\", \"artisan\", \"horizon\"]\n    stop_signal: SIGTERM\n    healthcheck:\n      test: [\"CMD\", \"healthcheck-horizon\"]\n      start_period: 10s\n    depends_on:\n      - redis\n\n  scheduler:\n    image: my-org/my-app:1.0.0\n    command: [\"php\", \"artisan\", \"schedule:work\"]\n    stop_signal: SIGTERM\n    healthcheck:\n      test: [\"CMD\", \"healthcheck-schedule\"]\n      start_period: 10s\n\n  redis:\n    image: redis:8-alpine\n","compose.yml","yaml",[262,526,527,540,548,561,569,578,586,597,604,612,621,646,657,665,683,694,702,710,715,723,732,752,761,768,784,793,798,806],{"__ignoreMap":10},[528,529,532,536],"span",{"class":530,"line":531},"line",1,[528,533,535],{"class":534},"s4JwU","services",[528,537,539],{"class":538},"s95oV",":\n",[528,541,543,546],{"class":530,"line":542},2,[528,544,545],{"class":534},"  app",[528,547,539],{"class":538},[528,549,551,554,557],{"class":530,"line":550},3,[528,552,553],{"class":534},"    image",[528,555,556],{"class":538},": ",[528,558,560],{"class":559},"sU2Wk","my-org/my-app:1.0.0\n",[528,562,564,567],{"class":530,"line":563},4,[528,565,566],{"class":534},"    ports",[528,568,539],{"class":538},[528,570,572,575],{"class":530,"line":571},5,[528,573,574],{"class":538},"      - ",[528,576,577],{"class":559},"\"80:8080\"\n",[528,579,581,584],{"class":530,"line":580},6,[528,582,583],{"class":534},"    environment",[528,585,539],{"class":538},[528,587,589,592,594],{"class":530,"line":588},7,[528,590,591],{"class":534},"      AUTORUN_ENABLED",[528,593,556],{"class":538},[528,595,596],{"class":559},"\"true\"\n",[528,598,600],{"class":530,"line":599},8,[528,601,603],{"emptyLinePlaceholder":602},true,"\n",[528,605,607,610],{"class":530,"line":606},9,[528,608,609],{"class":534},"  horizon",[528,611,539],{"class":538},[528,613,615,617,619],{"class":530,"line":614},10,[528,616,553],{"class":534},[528,618,556],{"class":538},[528,620,560],{"class":559},[528,622,624,627,630,633,635,638,640,643],{"class":530,"line":623},11,[528,625,626],{"class":534},"    command",[528,628,629],{"class":538},": [",[528,631,632],{"class":559},"\"php\"",[528,634,426],{"class":538},[528,636,637],{"class":559},"\"artisan\"",[528,639,426],{"class":538},[528,641,642],{"class":559},"\"horizon\"",[528,644,645],{"class":538},"]\n",[528,647,649,652,654],{"class":530,"line":648},12,[528,650,651],{"class":534},"    stop_signal",[528,653,556],{"class":538},[528,655,656],{"class":559},"SIGTERM\n",[528,658,660,663],{"class":530,"line":659},13,[528,661,662],{"class":534},"    healthcheck",[528,664,539],{"class":538},[528,666,668,671,673,676,678,681],{"class":530,"line":667},14,[528,669,670],{"class":534},"      test",[528,672,629],{"class":538},[528,674,675],{"class":559},"\"CMD\"",[528,677,426],{"class":538},[528,679,680],{"class":559},"\"healthcheck-horizon\"",[528,682,645],{"class":538},[528,684,686,689,691],{"class":530,"line":685},15,[528,687,688],{"class":534},"      start_period",[528,690,556],{"class":538},[528,692,693],{"class":559},"10s\n",[528,695,697,700],{"class":530,"line":696},16,[528,698,699],{"class":534},"    depends_on",[528,701,539],{"class":538},[528,703,705,707],{"class":530,"line":704},17,[528,706,574],{"class":538},[528,708,709],{"class":559},"redis\n",[528,711,713],{"class":530,"line":712},18,[528,714,603],{"emptyLinePlaceholder":602},[528,716,718,721],{"class":530,"line":717},19,[528,719,720],{"class":534},"  scheduler",[528,722,539],{"class":538},[528,724,726,728,730],{"class":530,"line":725},20,[528,727,553],{"class":534},[528,729,556],{"class":538},[528,731,560],{"class":559},[528,733,735,737,739,741,743,745,747,750],{"class":530,"line":734},21,[528,736,626],{"class":534},[528,738,629],{"class":538},[528,740,632],{"class":559},[528,742,426],{"class":538},[528,744,637],{"class":559},[528,746,426],{"class":538},[528,748,749],{"class":559},"\"schedule:work\"",[528,751,645],{"class":538},[528,753,755,757,759],{"class":530,"line":754},22,[528,756,651],{"class":534},[528,758,556],{"class":538},[528,760,656],{"class":559},[528,762,764,766],{"class":530,"line":763},23,[528,765,662],{"class":534},[528,767,539],{"class":538},[528,769,771,773,775,777,779,782],{"class":530,"line":770},24,[528,772,670],{"class":534},[528,774,629],{"class":538},[528,776,675],{"class":559},[528,778,426],{"class":538},[528,780,781],{"class":559},"\"healthcheck-schedule\"",[528,783,645],{"class":538},[528,785,787,789,791],{"class":530,"line":786},25,[528,788,688],{"class":534},[528,790,556],{"class":538},[528,792,693],{"class":559},[528,794,796],{"class":530,"line":795},26,[528,797,603],{"emptyLinePlaceholder":602},[528,799,801,804],{"class":530,"line":800},27,[528,802,803],{"class":534},"  redis",[528,805,539],{"class":538},[528,807,809,811,813],{"class":530,"line":808},28,[528,810,553],{"class":534},[528,812,556],{"class":538},[528,814,815],{"class":559},"redis:8-alpine\n",[275,817,819],{"id":818},"run-a-worker-inside-the-web-container","Run a worker inside the web container",[258,821,822,823,513,825,827,828,830],{},"To run a worker in the same container as the web server instead, add it as an S6 Overlay service in ",[262,824,429],{},[262,826,433],{},". See ",[307,829,178],{"href":179},". Separate containers are easier to scale and restart on their own.",[832,833,834],"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":542,"depth":542,"links":836},[837,838,839,840],{"id":277,"depth":542,"text":278},{"id":385,"depth":542,"text":386},{"id":501,"depth":542,"text":502},{"id":818,"depth":542,"text":819},"Run the Laravel scheduler, queue workers, Horizon, Reverb, and Nightwatch in their own containers from the same image as your web service.","md",null,{"head":845,"layout":7},{"title":846},"Laravel Workers with Docker - Docker PHP - Server Side Up",{"title":92,"description":841},"p2DeaO7G_47ODV2eDgKBNPh-l8YMRIB2LDMiNJnn-00",[850,852],{"title":88,"path":89,"stem":90,"description":851,"children":-1},"Link storage, run migrations, and cache your Laravel app each time the container starts, with one environment variable.",{"title":96,"path":97,"stem":98,"description":853,"children":-1},"Point the Docker health check at Laravel with one line, and check queue workers, Horizon, the scheduler, and Reverb with built-in scripts.",1793811944558]