[{"data":1,"prerenderedAt":746},["ShallowReactive",2],{"docs-nav":3,"docs:\u002Fdocs\u002Flocal-services":139},[4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130,133,136],{"path":5,"title":6},"\u002Fdocs\u002Faccess-gating","Protect a local route",{"path":8,"title":9},"\u002Fdocs\u002Farchitecture\u002Fsecurity-and-trust","Security and trust",{"path":11,"title":12},"\u002Fdocs\u002Fconcepts\u002Fbuilds-and-deployments","Build and deploy",{"path":14,"title":15},"\u002Fdocs\u002Fconcepts\u002Fconfiguration-ownership","Where configuration belongs",{"path":17,"title":18},"\u002Fdocs\u002Fconcepts\u002Fenvironments-and-secrets","Environment values and secrets",{"path":20,"title":21},"\u002Fdocs\u002Fconcepts\u002Fmental-model","How projects fit together",{"path":23,"title":24},"\u002Fdocs\u002Fconcepts\u002Fplans-and-apply","Plans and apply",{"path":26,"title":27},"\u002Fdocs\u002Fconcepts\u002Ftargets-and-runtimes","Choose a target and runtime",{"path":29,"title":30},"\u002Fdocs\u002Fcontribute\u002Freleases","Publish a release",{"path":32,"title":33},"\u002Fdocs\u002Fdevelopment-mounts","Development mounts",{"path":35,"title":36},"\u002Fdocs\u002Fgetting-started","Getting started",{"path":38,"title":39},"\u002Fdocs\u002Fhelp\u002Ffaq","FAQ",{"path":41,"title":42},"\u002Fdocs\u002Fhelp\u002Ftroubleshooting","Troubleshooting",{"path":44,"title":45},"\u002Fdocs\u002Fhow-to\u002Fdeploy-production","Prepare a deployment environment",{"path":47,"title":48},"\u002Fdocs\u002Fhow-to\u002Fswarm-cluster","Run on a multi-node Swarm",{"path":50,"title":51},"\u002Fdocs","mm documentation",{"path":53,"title":54},"\u002Fdocs\u002Fjobs-and-schedules","Jobs and schedules",{"path":56,"title":57},"\u002Fdocs\u002Flocal-dashboard","Local dashboard",{"path":59,"title":60},"\u002Fdocs\u002Flocal-https","Local HTTPS",{"path":62,"title":63},"\u002Fdocs\u002Flocal-services","Local services",{"path":65,"title":66},"\u002Fdocs\u002Fmcp","Let an AI agent work on your project",{"path":68,"title":69},"\u002Fdocs\u002Fmulti-project-hosts","Run multiple projects on one host",{"path":71,"title":72},"\u002Fdocs\u002Fonboarding","Set up a project",{"path":74,"title":75},"\u002Fdocs\u002Fopenbao","Use OpenBao",{"path":77,"title":78},"\u002Fdocs\u002Fproject\u002Fcontributing","Contributing",{"path":80,"title":81},"\u002Fdocs\u002Fproject\u002Flicense","License",{"path":83,"title":84},"\u002Fdocs\u002Fproject\u002Fsecurity","Security",{"path":86,"title":87},"\u002Fdocs\u002Freference\u002Fcapability-matrix","Supported features and platforms",{"path":89,"title":90},"\u002Fdocs\u002Freference\u002Fcli","CLI command reference",{"path":92,"title":93},"\u002Fdocs\u002Freference\u002Fconfiguration","Configuration",{"path":95,"title":96},"\u002Fdocs\u002Freference\u002Fenvironment-variables","Environment variables",{"path":98,"title":99},"\u002Fdocs\u002Freference\u002Ferrors-and-exit-codes","Errors and exit codes",{"path":101,"title":102},"\u002Fdocs\u002Freference\u002Fknown-issues","Known limitations",{"path":104,"title":105},"\u002Fdocs\u002Fremote-access","Manage remote access",{"path":107,"title":108},"\u002Fdocs\u002Fremote-daemon","Set up a remote host",{"path":110,"title":111},"\u002Fdocs\u002Fruntime-observability","Status, logs, and commands",{"path":113,"title":114},"\u002Fdocs\u002Fsecret-delivery","Pass secrets to your app",{"path":116,"title":117},"\u002Fdocs\u002Fsecret-providers","Choose a secret store",{"path":119,"title":120},"\u002Fdocs\u002Fstart\u002Finstall","Install mm",{"path":122,"title":123},"\u002Fdocs\u002Fterminal-ui","Terminal UI",{"path":125,"title":126},"\u002Fdocs\u002Ftutorials\u002Fdotnet-web-api",".NET web API example",{"path":128,"title":129},"\u002Fdocs\u002Ftutorials\u002Ffirst-local-app","First local app",{"path":131,"title":132},"\u002Fdocs\u002Ftutorials\u002Flaravel-rust","Laravel and Rust example",{"path":134,"title":135},"\u002Fdocs\u002Ftutorials\u002Fnode-fullstack","Node full stack example",{"path":137,"title":138},"\u002Fdocs\u002Fvault","Use HashiCorp Vault",{"id":140,"title":63,"body":141,"description":740,"extension":741,"meta":742,"navigation":288,"path":62,"seo":743,"stem":744,"__hash__":745},"docs\u002Fdocs\u002Flocal-services.md",{"type":142,"value":143,"toc":735},"minimark",[144,148,169,172,207,210,218,223,230,414,428,431,476,483,532,538,542,575,578,629,640,718,722,728,731],[145,146,147],"p",{},"Shared local services give your projects HTTPS, a dashboard, and development\nemail. One installation serves the local target using your chosen runtime:",[149,150,151,155,158,161],"ul",{},[152,153,154],"li",{},"Traefik for local HTTP and HTTPS routes;",[152,156,157],{},"the mm dashboard;",[152,159,160],{},"Mailpit for development email;",[152,162,163,164,168],{},"Cap and Valkey only when an access-gate policy requires them, or when a\nreviewed ",[165,166,167],"code",{},"--gate"," plan prepares them.",[145,170,171],{},"Run TLS setup first. To install everything in one guided flow:",[173,174,179],"pre",{"className":175,"code":176,"language":177,"meta":178,"style":178},"language-sh shiki shiki-themes mm","mm --runtime podman-compose dev setup --services\n","sh","",[165,180,181],{"__ignoreMap":178},[182,183,186,190,194,198,201,204],"span",{"class":184,"line":185},"line",1,[182,187,189],{"class":188},"svrjQ","mm",[182,191,193],{"class":192},"sbRf1"," --runtime",[182,195,197],{"class":196},"sv8ni"," podman-compose",[182,199,200],{"class":196}," dev",[182,202,203],{"class":196}," setup",[182,205,206],{"class":192}," --services\n",[145,208,209],{},"Docker Compose is also supported. Docker Swarm is not supported for this local\ntopology. A recorded installation belongs to its exact target and runtime, so\nalways select the runtime that originally installed it.",[145,211,212,213,217],{},"The complete topology requires HAProxy and one of these workstations: Linux with\nsystemd, or macOS with Docker Desktop and the Docker Compose runtime. On macOS\nthe ingress forwarder, Compose autostart, and dashboard run as launchd agents of\nyour user; see ",[214,215,120],"a",{"href":216},".\u002Fstart\u002Finstall#privileges-and-binary-ownership",".\nWindows supports CA trust management only.",[219,220,222],"h2",{"id":221},"install-check-or-repair","Install, check, or repair",[145,224,225,226,229],{},"Review each plan, then replace ",[165,227,228],{},"PLAN_HASH"," with the hash it prints:",[173,231,233],{"className":175,"code":232,"language":177,"meta":178,"style":178},"# Install or update the shared services.\nmm --runtime podman-compose dev services plan\nmm --runtime podman-compose dev services apply --plan PLAN_HASH --yes\n\nmm --runtime podman-compose dev services status\n\n# Upgrade an older installed stack.\nmm --runtime podman-compose dev services plan --operation upgrade\nmm --runtime podman-compose dev services upgrade --plan PLAN_HASH --yes\n\n# Repair an interrupted operation or changed resources.\nmm --runtime podman-compose dev services plan --operation repair\nmm --runtime podman-compose dev services repair --plan PLAN_HASH --yes\n",[165,234,235,241,258,283,290,306,311,317,339,361,366,372,392],{"__ignoreMap":178},[182,236,237],{"class":184,"line":185},[182,238,240],{"class":239},"sP7nD","# Install or update the shared services.\n",[182,242,244,246,248,250,252,255],{"class":184,"line":243},2,[182,245,189],{"class":188},[182,247,193],{"class":192},[182,249,197],{"class":196},[182,251,200],{"class":196},[182,253,254],{"class":196}," services",[182,256,257],{"class":196}," plan\n",[182,259,261,263,265,267,269,271,274,277,280],{"class":184,"line":260},3,[182,262,189],{"class":188},[182,264,193],{"class":192},[182,266,197],{"class":196},[182,268,200],{"class":196},[182,270,254],{"class":196},[182,272,273],{"class":196}," apply",[182,275,276],{"class":192}," --plan",[182,278,279],{"class":196}," PLAN_HASH",[182,281,282],{"class":192}," --yes\n",[182,284,286],{"class":184,"line":285},4,[182,287,289],{"emptyLinePlaceholder":288},true,"\n",[182,291,293,295,297,299,301,303],{"class":184,"line":292},5,[182,294,189],{"class":188},[182,296,193],{"class":192},[182,298,197],{"class":196},[182,300,200],{"class":196},[182,302,254],{"class":196},[182,304,305],{"class":196}," status\n",[182,307,309],{"class":184,"line":308},6,[182,310,289],{"emptyLinePlaceholder":288},[182,312,314],{"class":184,"line":313},7,[182,315,316],{"class":239},"# Upgrade an older installed stack.\n",[182,318,320,322,324,326,328,330,333,336],{"class":184,"line":319},8,[182,321,189],{"class":188},[182,323,193],{"class":192},[182,325,197],{"class":196},[182,327,200],{"class":196},[182,329,254],{"class":196},[182,331,332],{"class":196}," plan",[182,334,335],{"class":192}," --operation",[182,337,338],{"class":196}," upgrade\n",[182,340,342,344,346,348,350,352,355,357,359],{"class":184,"line":341},9,[182,343,189],{"class":188},[182,345,193],{"class":192},[182,347,197],{"class":196},[182,349,200],{"class":196},[182,351,254],{"class":196},[182,353,354],{"class":196}," upgrade",[182,356,276],{"class":192},[182,358,279],{"class":196},[182,360,282],{"class":192},[182,362,364],{"class":184,"line":363},10,[182,365,289],{"emptyLinePlaceholder":288},[182,367,369],{"class":184,"line":368},11,[182,370,371],{"class":239},"# Repair an interrupted operation or changed resources.\n",[182,373,375,377,379,381,383,385,387,389],{"class":184,"line":374},12,[182,376,189],{"class":188},[182,378,193],{"class":192},[182,380,197],{"class":196},[182,382,200],{"class":196},[182,384,254],{"class":196},[182,386,332],{"class":196},[182,388,335],{"class":192},[182,390,391],{"class":196}," repair\n",[182,393,395,397,399,401,403,405,408,410,412],{"class":184,"line":394},13,[182,396,189],{"class":188},[182,398,193],{"class":192},[182,400,197],{"class":196},[182,402,200],{"class":196},[182,404,254],{"class":196},[182,406,407],{"class":196}," repair",[182,409,276],{"class":192},[182,411,279],{"class":196},[182,413,282],{"class":192},[145,415,416,417,419,420,423,424,427],{},"Repeat all options that affect a plan when applying it. For example, prepare\nCap and Valkey with ",[165,418,167],{}," on both ",[165,421,422],{},"plan"," and ",[165,425,426],{},"apply",". A stale hash, changed\nruntime, changed target, or changed prior state is rejected.",[145,429,430],{},"Normal removal deletes only matching mm-owned runtime resources and retains\npersistent data:",[173,432,434],{"className":175,"code":433,"language":177,"meta":178,"style":178},"mm --runtime podman-compose dev services plan --operation remove\nmm --runtime podman-compose dev services remove --plan PLAN_HASH --yes\n",[165,435,436,455],{"__ignoreMap":178},[182,437,438,440,442,444,446,448,450,452],{"class":184,"line":185},[182,439,189],{"class":188},[182,441,193],{"class":192},[182,443,197],{"class":196},[182,445,200],{"class":196},[182,447,254],{"class":196},[182,449,332],{"class":196},[182,451,335],{"class":192},[182,453,454],{"class":196}," remove\n",[182,456,457,459,461,463,465,467,470,472,474],{"class":184,"line":243},[182,458,189],{"class":188},[182,460,193],{"class":192},[182,462,197],{"class":196},[182,464,200],{"class":196},[182,466,254],{"class":196},[182,468,469],{"class":196}," remove",[182,471,276],{"class":192},[182,473,279],{"class":196},[182,475,282],{"class":192},[145,477,478,479,482],{},"To delete retained Mailpit and optional Cap\u002FValkey data, explicitly review and\nrepeat ",[165,480,481],{},"--purge",":",[173,484,486],{"className":175,"code":485,"language":177,"meta":178,"style":178},"mm --runtime podman-compose dev services plan --operation remove --purge\nmm --runtime podman-compose dev services remove --plan PLAN_HASH --purge --yes\n",[165,487,488,509],{"__ignoreMap":178},[182,489,490,492,494,496,498,500,502,504,506],{"class":184,"line":185},[182,491,189],{"class":188},[182,493,193],{"class":192},[182,495,197],{"class":196},[182,497,200],{"class":196},[182,499,254],{"class":196},[182,501,332],{"class":196},[182,503,335],{"class":192},[182,505,469],{"class":196},[182,507,508],{"class":192}," --purge\n",[182,510,511,513,515,517,519,521,523,525,527,530],{"class":184,"line":243},[182,512,189],{"class":188},[182,514,193],{"class":192},[182,516,197],{"class":196},[182,518,200],{"class":196},[182,520,254],{"class":196},[182,522,469],{"class":196},[182,524,276],{"class":192},[182,526,279],{"class":196},[182,528,529],{"class":192}," --purge",[182,531,282],{"class":192},[145,533,534,535,537],{},"Purge is irreversible. Removal also fails if project workloads still use a\nmanaged network; stop those workloads first. ",[165,536,189],{}," does not disconnect foreign\ncontainers or adopt same-named resources without matching ownership.",[219,539,541],{"id":540},"urls-and-mail","URLs and mail",[149,543,544,550,555,561,568],{},[152,545,546,547],{},"Dashboard: ",[165,548,549],{},"https:\u002F\u002Fmm.test",[152,551,552,553],{},"Project dashboard: follow the project link from ",[165,554,549],{},[152,556,557,558],{},"Mailpit UI: ",[165,559,560],{},"https:\u002F\u002Fmail.mm.test",[152,562,563,564,567],{},"Container SMTP: ",[165,565,566],{},"mailpit:1025"," on the managed development network",[152,569,570,571,574],{},"Cap widget\u002Fchallenge origin when installed: ",[165,572,573],{},"https:\u002F\u002Fcap.mm.test","; only pinned\nassets and site-scoped challenge, redeem, and verification paths are public.\nThe root dashboard and administration API are not exposed.",[145,576,577],{},"Host SMTP is disabled by default. For a host-native application, choose an\nunused loopback port and repeat it during apply:",[173,579,581],{"className":175,"code":580,"language":177,"meta":178,"style":178},"mm --runtime podman-compose dev services plan --smtp-port 10252\nmm --runtime podman-compose dev services apply --smtp-port 10252 --plan PLAN_HASH --yes\n",[165,582,583,604],{"__ignoreMap":178},[182,584,585,587,589,591,593,595,597,600],{"class":184,"line":185},[182,586,189],{"class":188},[182,588,193],{"class":192},[182,590,197],{"class":196},[182,592,200],{"class":196},[182,594,254],{"class":196},[182,596,332],{"class":196},[182,598,599],{"class":192}," --smtp-port",[182,601,603],{"class":602},"s1Wbj"," 10252\n",[182,605,606,608,610,612,614,616,618,620,623,625,627],{"class":184,"line":243},[182,607,189],{"class":188},[182,609,193],{"class":192},[182,611,197],{"class":196},[182,613,200],{"class":196},[182,615,254],{"class":196},[182,617,273],{"class":196},[182,619,599],{"class":192},[182,621,622],{"class":602}," 10252",[182,624,276],{"class":192},[182,626,279],{"class":196},[182,628,282],{"class":192},[145,630,631,632,635,636,639],{},"The port binds as ",[165,633,634],{},"127.0.0.1:10252","; it is never published on all interfaces.\nServices that accept managed development-mail bindings receive defaults such\nas ",[165,637,638],{},"MM_MAIL_SMTP_URL=smtp:\u002F\u002Fmailpit:1025"," without replacing existing values.",[173,641,645],{"className":642,"code":643,"language":644,"meta":178,"style":178},"language-yaml shiki shiki-themes mm","development-mail:\n  enabled: false\n\nmodules:\n  jobs:\n    services:\n      worker:\n        stack: app\n        development-mail: false\n","yaml",[165,646,647,657,667,671,678,685,692,699,709],{"__ignoreMap":178},[182,648,649,653],{"class":184,"line":185},[182,650,652],{"class":651},"sWZmh","development-mail",[182,654,656],{"class":655},"sIbZ0",":\n",[182,658,659,662,664],{"class":184,"line":243},[182,660,661],{"class":651},"  enabled",[182,663,482],{"class":655},[182,665,666],{"class":602}," false\n",[182,668,669],{"class":184,"line":260},[182,670,289],{"emptyLinePlaceholder":288},[182,672,673,676],{"class":184,"line":285},[182,674,675],{"class":651},"modules",[182,677,656],{"class":655},[182,679,680,683],{"class":184,"line":292},[182,681,682],{"class":651},"  jobs",[182,684,656],{"class":655},[182,686,687,690],{"class":184,"line":308},[182,688,689],{"class":651},"    services",[182,691,656],{"class":655},[182,693,694,697],{"class":184,"line":313},[182,695,696],{"class":651},"      worker",[182,698,656],{"class":655},[182,700,701,704,706],{"class":184,"line":319},[182,702,703],{"class":651},"        stack",[182,705,482],{"class":655},[182,707,708],{"class":196}," app\n",[182,710,711,714,716],{"class":184,"line":341},[182,712,713],{"class":651},"        development-mail",[182,715,482],{"class":655},[182,717,666],{"class":602},[219,719,721],{"id":720},"data-and-conflicts","Data and conflicts",[145,723,724,727],{},[165,725,726],{},"mm dev services status"," reports health, changed images or routes, certificate\nproblems, and resource conflicts. If another tool owns a conflicting resource,\nresolve that conflict rather than relabeling it as mm-owned.",[145,729,730],{},"Mailpit and optional Cap\u002FValkey service data live in managed volumes and survive\nnormal removal. Purge removes those declared persistent volumes; access-policy,\nuser, and session records remain in mm's private state rather than those\nvolumes.",[732,733,734],"style",{},"html pre.shiki code .svrjQ, html code.shiki .svrjQ{--shiki-default:var(--mm-code-function)}html pre.shiki code .sbRf1, html code.shiki .sbRf1{--shiki-default:var(--mm-code-option)}html pre.shiki code .sv8ni, html code.shiki .sv8ni{--shiki-default:var(--mm-code-string)}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 .sP7nD, html code.shiki .sP7nD{--shiki-default:var(--mm-code-comment)}html pre.shiki code .s1Wbj, html code.shiki .s1Wbj{--shiki-default:var(--mm-code-constant)}html pre.shiki code .sWZmh, html code.shiki .sWZmh{--shiki-default:var(--mm-code-key)}html pre.shiki code .sIbZ0, html code.shiki .sIbZ0{--shiki-default:var(--mm-code-punctuation)}",{"title":178,"searchDepth":243,"depth":243,"links":736},[737,738,739],{"id":221,"depth":243,"text":222},{"id":540,"depth":243,"text":541},{"id":720,"depth":243,"text":721},"Install and operate the shared local ingress, dashboard, and development services.","md",{},{"title":63,"description":740},"docs\u002Flocal-services","w7WxLl7SgZzJn2eeSlW0VjRDCbp2c4ztO2bLZYG3zwU",1794512546196]