[{"data":1,"prerenderedAt":693},["ShallowReactive",2],{"docs-navigation":3,"-docs-templates-contributing-":150,"-docs-templates-contributing--surround":692},[4,43,114,122],{"title":5,"icon":6,"path":7,"stem":8,"children":9},"Get Started","i-lucide-rocket","\u002Fdocs\u002Fget-started","docs\u002F1.get-started\u002Findex",[10,13,18,23,28,33,38],{"title":11,"path":7,"stem":8,"icon":12},"Introduction","i-lucide-compass",{"title":14,"path":15,"stem":16,"icon":17},"Key Concepts","\u002Fdocs\u002Fget-started\u002Fconcepts","docs\u002F1.get-started\u002F2.concepts","i-lucide-lightbulb",{"title":19,"path":20,"stem":21,"icon":22},"Browsing the Catalog","\u002Fdocs\u002Fget-started\u002Fbrowsing-the-catalog","docs\u002F1.get-started\u002F3.browsing-the-catalog","i-lucide-search",{"title":24,"path":25,"stem":26,"icon":27},"Managing Apps","\u002Fdocs\u002Fget-started\u002Fmanaging-apps","docs\u002F1.get-started\u002F4.managing-apps","i-lucide-settings-2",{"title":29,"path":30,"stem":31,"icon":32},"Configuration","\u002Fdocs\u002Fget-started\u002Fconfiguration","docs\u002F1.get-started\u002F5.configuration","i-lucide-sliders-horizontal",{"title":34,"path":35,"stem":36,"icon":37},"Accessing Apps","\u002Fdocs\u002Fget-started\u002Faccessing-apps","docs\u002F1.get-started\u002F6.accessing-apps","i-lucide-globe",{"title":39,"path":40,"stem":41,"icon":42},"Experimental Features","\u002Fdocs\u002Fget-started\u002Fexperimental-features","docs\u002F1.get-started\u002F7.experimental-features","i-lucide-flask-conical",{"title":44,"icon":45,"path":46,"stem":47,"children":48},"Templates","i-lucide-puzzle","\u002Fdocs\u002Ftemplates","docs\u002F2.templates\u002Findex",[49,51,56,79,101,105,109],{"title":11,"path":46,"stem":47,"icon":50},"i-lucide-book-open",{"title":52,"path":53,"stem":54,"icon":55},"Directory Structure","\u002Fdocs\u002Ftemplates\u002Fdirectory-structure","docs\u002F2.templates\u002F1.directory-structure","i-lucide-folder-tree",{"title":29,"icon":57,"path":58,"stem":59,"children":60},"i-lucide-settings","\u002Fdocs\u002Ftemplates\u002Fconfiguration","docs\u002F2.templates\u002F2.configuration\u002Findex",[61,64,69,74],{"title":62,"path":58,"stem":59,"icon":63},"Overview","i-lucide-list",{"title":65,"path":66,"stem":67,"icon":68},"Variables","\u002Fdocs\u002Ftemplates\u002Fconfiguration\u002Fvariables","docs\u002F2.templates\u002F2.configuration\u002F1.variables","i-lucide-braces",{"title":70,"path":71,"stem":72,"icon":73},"Localization","\u002Fdocs\u002Ftemplates\u002Fconfiguration\u002Flocalization","docs\u002F2.templates\u002F2.configuration\u002F2.localization","i-lucide-languages",{"title":75,"path":76,"stem":77,"icon":78},"Merging","\u002Fdocs\u002Ftemplates\u002Fconfiguration\u002Fmerging","docs\u002F2.templates\u002F2.configuration\u002F3.merging","i-lucide-git-merge",{"title":80,"icon":81,"path":82,"stem":83,"children":84},"Lawn Compose","i-lucide-file-code","\u002Fdocs\u002Ftemplates\u002Flawn-compose","docs\u002F2.templates\u002F3.lawn-compose\u002Findex",[85,86,91,96],{"title":62,"path":82,"stem":83,"icon":63},{"title":87,"path":88,"stem":89,"icon":90},"Format","\u002Fdocs\u002Ftemplates\u002Flawn-compose\u002Fformat","docs\u002F2.templates\u002F3.lawn-compose\u002F2.format","i-lucide-list-checks",{"title":92,"path":93,"stem":94,"icon":95},"Extensions","\u002Fdocs\u002Ftemplates\u002Flawn-compose\u002Fextensions","docs\u002F2.templates\u002F3.lawn-compose\u002F3.extensions","i-lucide-blocks",{"title":97,"path":98,"stem":99,"icon":100},"Validation","\u002Fdocs\u002Ftemplates\u002Flawn-compose\u002Fvalidation","docs\u002F2.templates\u002F3.lawn-compose\u002F4.validation","i-lucide-check-circle",{"title":102,"path":103,"stem":104,"icon":42},"Testing","\u002Fdocs\u002Ftemplates\u002Ftesting","docs\u002F2.templates\u002F4.testing",{"title":106,"path":107,"stem":108,"icon":81},"Complete Example","\u002Fdocs\u002Ftemplates\u002Fexample","docs\u002F2.templates\u002F5.example",{"title":110,"path":111,"stem":112,"icon":113},"Contributing","\u002Fdocs\u002Ftemplates\u002Fcontributing","docs\u002F2.templates\u002F6.contributing","i-lucide-git-pull-request",{"title":115,"path":116,"stem":117,"children":118,"icon":121},"Models","\u002Fdocs\u002Finference","docs\u002F3.inference\u002Findex",[119],{"title":11,"path":116,"stem":117,"icon":120},"i-lucide-construction","i-lucide-brain",{"title":123,"icon":124,"path":125,"stem":126,"children":127},"CLI","i-lucide-terminal","\u002Fdocs\u002Fcli","docs\u002F4.cli\u002Findex",[128,129,133,138,142,146],{"title":62,"path":125,"stem":126,"icon":63},{"title":130,"path":131,"stem":132,"icon":22},"lawn catalog","\u002Fdocs\u002Fcli\u002Fcatalog","docs\u002F4.cli\u002F2.catalog",{"title":134,"path":135,"stem":136,"icon":137},"lawn app","\u002Fdocs\u002Fcli\u002Fapp","docs\u002F4.cli\u002F3.app","i-lucide-box",{"title":139,"path":140,"stem":141,"icon":57},"lawn system","\u002Fdocs\u002Fcli\u002Fsystem","docs\u002F4.cli\u002F4.system",{"title":143,"path":144,"stem":145,"icon":81},"lawn compose","\u002Fdocs\u002Fcli\u002Fcompose","docs\u002F4.cli\u002F5.compose",{"title":147,"path":148,"stem":149,"icon":45},"lawn template","\u002Fdocs\u002Fcli\u002Ftemplate","docs\u002F4.cli\u002F6.template",{"id":151,"title":110,"body":152,"description":680,"extension":681,"head":682,"links":683,"meta":687,"navigation":688,"ogImage":682,"path":111,"robots":682,"schemaOrg":682,"seo":689,"sitemap":690,"stem":112,"__hash__":691},"docs\u002Fdocs\u002F2.templates\u002F6.contributing.md",{"type":153,"value":154,"toc":663},"minimark",[155,171,176,202,223,227,244,253,257,323,327,330,335,393,397,439,443,480,483,565,569,598,601,626,629],[156,157,158,159,170],"p",{},"Templates live in the ",[160,161,166],"a",{"href":162,"rel":163,"target":165},"https:\u002F\u002Fgithub.com\u002Fgetlawn\u002Ftemplates",[164],"nofollow","_blank",[167,168,169],"code",{},"getlawn\u002Ftemplates"," repository. This page covers the conventions and requirements for contributing a new template via pull request.",[172,173,175],"h2",{"id":174},"naming-conventions","Naming Conventions",[156,177,178,182,183,186,187,190,191,194,195,194,198,201],{},[179,180,181],"strong",{},"App ID"," — Lowercase, hyphen-separated. Must match the directory name and the ",[167,184,185],{},"id"," field in ",[167,188,189],{},"manifest.yaml",". Use the app's commonly known name (e.g., ",[167,192,193],{},"paperless-ngx",", ",[167,196,197],{},"uptime-kuma",[167,199,200],{},"adguard-home",").",[156,203,204,207,208,211,212,194,215,218,219,222],{},[179,205,206],{},"Compose filenames"," — Use ",[167,209,210],{},"v"," followed by the app version: ",[167,213,214],{},"v1.0.0.yaml",[167,216,217],{},"v10.10.yaml",", or ",[167,220,221],{},"v32.yaml",". The version can have one, two, or three parts depending on the app's versioning scheme.",[172,224,226],{"id":225},"icon-requirements","Icon Requirements",[156,228,229,230,233,234,194,237,218,240,243],{},"Include an ",[167,231,232],{},"icon.svg"," (preferred), ",[167,235,236],{},"icon.png",[167,238,239],{},"icon.heif",[167,241,242],{},"icon.pdf"," in the template directory. SVG is preferred because it scales to any size. For PNG, use at least 256×256 pixels.",[156,245,246,247,186,250,252],{},"The ",[167,248,249],{},"icon",[167,251,189],{}," specifies an SF Symbol name used as a fallback when no icon file is present.",[172,254,256],{"id":255},"style-guidelines","Style Guidelines",[258,259,260,270,284,298,304,313],"ul",{},[261,262,263,265,266,269],"li",{},[179,264,70],{}," — All user-facing strings (display names, descriptions, labels, notice titles) belong in ",[167,267,268],{},"locales\u002Fen.json",", not in the YAML template.",[261,271,272,275,276,279,280,283],{},[179,273,274],{},"Notices"," — Use a maximum of 2-3 per template. Reserve them for information users genuinely need to act on: login credentials, required setup steps, or warnings about values they should not change. Use ",[167,277,278],{},"info"," for general guidance and ",[167,281,282],{},"warning"," for critical actions.",[261,285,286,289,290,293,294,297],{},[179,287,288],{},"Environment defaults"," — Always provide ",[167,291,292],{},"${VAR:-default}"," fallbacks so the compose file works standalone with ",[167,295,296],{},"docker compose config",".",[261,299,300,303],{},[179,301,302],{},"Descriptions"," — Write clear, concise descriptions for variables and environment metadata. Describe what the value controls, not just what it is.",[261,305,306,207,309,312],{},[179,307,308],{},"Display ordering",[167,310,311],{},"weight"," to order config variables logically. Group related settings together and put important ones first.",[261,314,315,318,319,322],{},[179,316,317],{},"Volumes"," — Use relative paths (",[167,320,321],{},".\u002Fdata:\u002Fapp\u002Fdata",") for persistent data. Avoid absolute paths unless strictly necessary.",[172,324,326],{"id":325},"pr-checklist","PR Checklist",[156,328,329],{},"Before submitting a template, verify each item:",[331,332,334],"h3",{"id":333},"manifest","Manifest",[258,336,339,352,370,378,387],{"className":337},[338],"contains-task-list",[261,340,343,348,349,351],{"className":341},[342],"task-list-item",[344,345],"input",{"disabled":346,"type":347},true,"checkbox"," ",[167,350,185],{}," matches the directory name",[261,353,355,348,357,194,360,194,363,365,366,369],{"className":354},[342],[344,356],{"disabled":346,"type":347},[167,358,359],{},"name",[167,361,362],{},"description",[167,364,249],{},", and ",[167,367,368],{},"category"," are set",[261,371,373,348,375,377],{"className":372},[342],[344,374],{"disabled":346,"type":347},[167,376,368],{}," is one of: Documents, Media, Development, Networking, Utilities, Databases, Monitoring",[261,379,381,348,383,386],{"className":380},[342],[344,382],{"disabled":346,"type":347},[167,384,385],{},"webPort"," is set if the app has a web UI",[261,388,390,392],{"className":389},[342],[344,391],{"disabled":346,"type":347}," At least one link (GitHub or documentation) is included",[331,394,396],{"id":395},"compose-file","Compose File",[258,398,400,410,418,427,433],{"className":399},[338],[261,401,403,405,406,409],{"className":402},[342],[344,404],{"disabled":346,"type":347}," All images use explicit version tags (no ",[167,407,408],{},"latest",")",[261,411,413,415,416],{"className":412},[342],[344,414],{"disabled":346,"type":347}," Compose file validates with ",[167,417,296],{},[261,419,421,423,424,426],{"className":420},[342],[344,422],{"disabled":346,"type":347}," Environment variables use ",[167,425,292],{}," substitution with sensible defaults",[261,428,430,432],{"className":429},[342],[344,431],{"disabled":346,"type":347}," Volumes use relative paths for persistent data",[261,434,436,438],{"className":435},[342],[344,437],{"disabled":346,"type":347}," Ports are declared for services with a web UI",[331,440,442],{"id":441},"variables-and-secrets","Variables and Secrets",[258,444,446,456,465,474],{"className":445},[338],[261,447,449,451,452,455],{"className":448},[342],[344,450],{"disabled":346,"type":347}," Passwords and tokens use ",[167,453,454],{},"generatedSecret"," (not hardcoded defaults)",[261,457,459,348,461,464],{"className":458},[342],[344,460],{"disabled":346,"type":347},[167,462,463],{},"userProvided"," variables are only used when the user must supply the value (API keys, external URLs)",[261,466,468,348,470,473],{"className":467},[342],[344,469],{"disabled":346,"type":347},[167,471,472],{},"inputType"," is set for boolean and number config variables",[261,475,477,479],{"className":476},[342],[344,478],{"disabled":346,"type":347}," Config options use compose overlays for each selectable value",[331,481,70],{"id":482},"localization",[258,484,486,494,506,515,527,535,543,559],{"className":485},[338],[261,487,489,348,491,493],{"className":488},[342],[344,490],{"disabled":346,"type":347},[167,492,268],{}," exists with entries for all user-facing strings",[261,495,497,499,500,503,504],{"className":496},[342],[344,498],{"disabled":346,"type":347}," Every config variable has ",[167,501,502],{},"displayName"," and ",[167,505,362],{},[261,507,509,511,512],{"className":508},[342],[344,510],{"disabled":346,"type":347}," Every config option value has a ",[167,513,514],{},"label",[261,516,518,520,521,503,524,409],{"className":517},[342],[344,519],{"disabled":346,"type":347}," Boolean config variables have exactly 2 option labels (",[167,522,523],{},"\"true\"",[167,525,526],{},"\"false\"",[261,528,530,532,533],{"className":529},[342],[344,531],{"disabled":346,"type":347}," Every environment variable has a ",[167,534,362],{},[261,536,538,540,541],{"className":537},[342],[344,539],{"disabled":346,"type":347}," Every health check has a ",[167,542,362],{},[261,544,546,548,549,552,553,555,556],{"className":545},[342],[344,547],{"disabled":346,"type":347}," Every notice has a ",[167,550,551],{},"title"," and all elements have ",[167,554,514],{},"\u002F",[167,557,558],{},"content",[261,560,562,564],{"className":561},[342],[344,563],{"disabled":346,"type":347}," No dangling keys (JSON entries without matching YAML structures)",[331,566,568],{"id":567},"health-checks","Health Checks",[258,570,572,582,588],{"className":571},[338],[261,573,575,577,578,581],{"className":574},[342],[344,576],{"disabled":346,"type":347}," At least one Lawn health check (",[167,579,580],{},"x-lawn.healthChecks",") is defined for the main service",[261,583,585,587],{"className":584},[342],[344,586],{"disabled":346,"type":347}," HTTP checks use a reliable endpoint (health or root path)",[261,589,591,593,594,597],{"className":590},[342],[344,592],{"disabled":346,"type":347}," Database services have a standard ",[167,595,596],{},"healthcheck"," in the compose spec",[331,599,274],{"id":600},"notices",[258,602,604,610,620],{"className":603},[338],[261,605,607,609],{"className":606},[342],[344,608],{"disabled":346,"type":347}," Login credentials are surfaced in a notice (if applicable)",[261,611,613,615,616,619],{"className":612},[342],[344,614],{"disabled":346,"type":347}," Notices use ",[167,617,618],{},"sourceField"," for dynamic values instead of hardcoding passwords",[261,621,623,625],{"className":622},[342],[344,624],{"disabled":346,"type":347}," No more than 2-3 notices per template",[331,627,102],{"id":628},"testing",[258,630,632,641,657],{"className":631},[338],[261,633,635,348,637,640],{"className":634},[342],[344,636],{"disabled":346,"type":347},[167,638,639],{},"lawn template validate ."," passes (catches missing localization entries)",[261,642,644,348,646,649,650,653,654,656],{"className":643},[342],[344,645],{"disabled":346,"type":347},[167,647,648],{},"lawn template test ."," passes (with ",[167,651,652],{},"--var"," for any ",[167,655,463],{}," variables)",[261,658,660,662],{"className":659},[342],[344,661],{"disabled":346,"type":347}," All health checks pass within the default timeout",{"title":664,"searchDepth":665,"depth":665,"links":666},"",2,[667,668,669,670],{"id":174,"depth":665,"text":175},{"id":225,"depth":665,"text":226},{"id":255,"depth":665,"text":256},{"id":325,"depth":665,"text":326,"children":671},[672,674,675,676,677,678,679],{"id":333,"depth":673,"text":334},3,{"id":395,"depth":673,"text":396},{"id":441,"depth":673,"text":442},{"id":482,"depth":673,"text":70},{"id":567,"depth":673,"text":568},{"id":600,"depth":673,"text":274},{"id":628,"depth":673,"text":102},"Guidelines and checklist for submitting new templates.","md",null,[684],{"label":685,"icon":686,"to":162,"target":165},"GitHub","i-simple-icons-github",{},{"icon":113},{"title":110,"description":680},{"loc":111},"cbfao557Gyo2kUCA-EWWQ__BCN6VdIBHC1N3Vb1DMdg",[682,682],1775508104762]