[{"data":1,"prerenderedAt":1308},["ShallowReactive",2],{"navigation":3,"/docs/advanced/create-your-own-template":285,"/docs/advanced/create-your-own-template-surround":1303},[4],{"title":5,"path":6,"stem":7,"children":8},"Introduction","/docs","docs/1.index",[9,10,36,53,70,83,100,121,138,155,176],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13,"children":14,"page":35},"Installation","/docs/installation","docs/1.installation",[15,19,23,27,31],{"title":16,"path":17,"stem":18},"Install to macOS","/docs/installation/install-macos","docs/1.installation/1.install-macos",{"title":20,"path":21,"stem":22},"Install to Windows","/docs/installation/install-windows","docs/1.installation/2.install-windows",{"title":24,"path":25,"stem":26},"Install to Linux","/docs/installation/install-linux","docs/1.installation/3.install-linux",{"title":28,"path":29,"stem":30},"Install via Composer","/docs/installation/install-composer","docs/1.installation/4.install-composer",{"title":32,"path":33,"stem":34},"Install via NPM/Yarn","/docs/installation/install-npm-yarn","docs/1.installation/5.install-npm-yarn",false,{"title":37,"path":38,"stem":39,"children":40,"page":35},"Community","/docs/community","docs/11.community",[41,45,49],{"title":42,"path":43,"stem":44},"Get Help","/docs/community/get-help","docs/11.community/1.get-help",{"title":46,"path":47,"stem":48},"Testing New Releases","/docs/community/testing","docs/11.community/2.testing",{"title":50,"path":51,"stem":52},"Contributing","/docs/community/contributing","docs/11.community/3.contributing",{"title":54,"path":55,"stem":56,"children":57,"page":35},"Getting Started","/docs/getting-started","docs/2.getting-started",[58,62,66],{"title":59,"path":60,"stem":61},"How Spin Works","/docs/getting-started/how-spin-works","docs/2.getting-started/1.how-spin-works",{"title":63,"path":64,"stem":65},"Create a New Project with Spin","/docs/getting-started/create-a-new-project-with-spin","docs/2.getting-started/2.create-a-new-project-with-spin",{"title":67,"path":68,"stem":69},"Add Spin to an Existing Project","/docs/getting-started/add-spin-to-an-existing-project","docs/2.getting-started/3.add-spin-to-an-existing-project",{"title":71,"path":72,"stem":73,"children":74,"page":35},"Development Environment","/docs/development-environment","docs/3.development-environment",[75,79],{"title":76,"path":77,"stem":78},"Starting Up Your Development Environment","/docs/development-environment/starting-up-your-development-environment","docs/3.development-environment/1.starting-up-your-development-environment",{"title":80,"path":81,"stem":82},"Running Commands in Development","/docs/development-environment/running-commands-in-development","docs/3.development-environment/2.running-commands-in-development",{"title":84,"path":85,"stem":86,"children":87,"page":35},"Server Configuration","/docs/server-configuration","docs/4.server-configuration",[88,92,96],{"title":89,"path":90,"stem":91},"Server Requirements","/docs/server-configuration/server-requirements","docs/4.server-configuration/1.server-requirements",{"title":93,"path":94,"stem":95},"Server Configuration Basics","/docs/server-configuration/server-configuration-basics","docs/4.server-configuration/2.server-configuration-basics",{"title":97,"path":98,"stem":99},".spin.yml Usage","/docs/server-configuration/spin-yml-usage","docs/4.server-configuration/3.spin-yml-usage",{"title":101,"path":102,"stem":103,"children":104,"page":35},"Providers","/docs/providers","docs/5.providers",[105,109,113,117],{"title":106,"path":107,"stem":108},"DigitalOcean","/docs/providers/digitalocean","docs/5.providers/0.digitalocean",{"title":110,"path":111,"stem":112},"Hetzner","/docs/providers/hetzner","docs/5.providers/0.hetzner",{"title":114,"path":115,"stem":116},"Vultr","/docs/providers/vultr","docs/5.providers/0.vultr",{"title":118,"path":119,"stem":120},"Use Any Host","/docs/providers/use-any-host","docs/5.providers/99.use-any-host",{"title":122,"path":123,"stem":124,"children":125,"page":35},"Deployment","/docs/deployment","docs/6.deployment",[126,130,134],{"title":127,"path":128,"stem":129},"Choosing a Deployment Strategy","/docs/deployment/choosing-a-deployment-strategy","docs/6.deployment/1.choosing-a-deployment-strategy",{"title":131,"path":132,"stem":133},"Automated Deployments with GitHub Actions","/docs/deployment/automated-deployments-with-github-actions","docs/6.deployment/2.automated-deployments-with-github-actions",{"title":135,"path":136,"stem":137},"Using \"spin deploy\"","/docs/deployment/using-spin-deploy","docs/6.deployment/3.using-spin-deploy",{"title":139,"path":140,"stem":141,"children":142,"page":35},"Server Access","/docs/server-access","docs/7.server-access",[143,147,151],{"title":144,"path":145,"stem":146},"Connecting to Your Server","/docs/server-access/connecting-to-your-server","docs/7.server-access/1.connecting-to-your-server",{"title":148,"path":149,"stem":150},"Troubleshooting Your Application","/docs/server-access/troubleshooting-your-application","docs/7.server-access/2.troubleshooting-your-application",{"title":152,"path":153,"stem":154},"Updating Your Server","/docs/server-access/updating-your-server","docs/7.server-access/3.updating-your-server",{"title":156,"path":157,"stem":158,"children":159,"page":35},"Advanced","/docs/advanced","docs/8.advanced",[160,164,168,172],{"title":161,"path":162,"stem":163},"Generating a Secure SSH Key","/docs/advanced/generating-a-secure-ssh-key","docs/8.advanced/2.generating-a-secure-ssh-key",{"title":165,"path":166,"stem":167},"Adding Other Services","/docs/advanced/adding-other-services","docs/8.advanced/3.adding-other-services",{"title":169,"path":170,"stem":171},"Create your own Spin Template","/docs/advanced/create-your-own-template","docs/8.advanced/99.create-your-own-template",{"title":173,"path":174,"stem":175},"Migrating from Spin v2 to v3","/docs/advanced/migrating-from-spin-v2-to-v3","docs/8.advanced/migrating-from-spin-v2-to-v3",{"title":177,"path":178,"stem":179,"children":180,"page":35},"Command Reference","/docs/command-reference","docs/9.command-reference",[181,185,189,193,197,201,205,209,213,217,221,225,229,233,237,241,245,249,253,257,261,265,269,273,277,281],{"title":182,"path":183,"stem":184},"base64","/docs/command-reference/base64","docs/9.command-reference/base64",{"title":186,"path":187,"stem":188},"build","/docs/command-reference/build","docs/9.command-reference/build",{"title":190,"path":191,"stem":192},"configure","/docs/command-reference/configure","docs/9.command-reference/configure",{"title":194,"path":195,"stem":196},"debug","/docs/command-reference/debug","docs/9.command-reference/debug",{"title":198,"path":199,"stem":200},"deploy","/docs/command-reference/deploy","docs/9.command-reference/deploy",{"title":202,"path":203,"stem":204},"down","/docs/command-reference/down","docs/9.command-reference/down",{"title":206,"path":207,"stem":208},"exec","/docs/command-reference/exec","docs/9.command-reference/exec",{"title":210,"path":211,"stem":212},"gh","/docs/command-reference/gh","docs/9.command-reference/gh",{"title":214,"path":215,"stem":216},"help","/docs/command-reference/help","docs/9.command-reference/help",{"title":218,"path":219,"stem":220},"init","/docs/command-reference/init","docs/9.command-reference/init",{"title":222,"path":223,"stem":224},"kill","/docs/command-reference/kill","docs/9.command-reference/kill",{"title":226,"path":227,"stem":228},"latest","/docs/command-reference/latest","docs/9.command-reference/latest",{"title":230,"path":231,"stem":232},"logs","/docs/command-reference/logs","docs/9.command-reference/logs",{"title":234,"path":235,"stem":236},"maintain","/docs/command-reference/maintain","docs/9.command-reference/maintain",{"title":238,"path":239,"stem":240},"mkpasswd","/docs/command-reference/mkpasswd","docs/9.command-reference/mkpasswd",{"title":242,"path":243,"stem":244},"new","/docs/command-reference/new","docs/9.command-reference/new",{"title":246,"path":247,"stem":248},"provision","/docs/command-reference/provision","docs/9.command-reference/provision",{"title":250,"path":251,"stem":252},"prune","/docs/command-reference/prune","docs/9.command-reference/prune",{"title":254,"path":255,"stem":256},"ps","/docs/command-reference/ps","docs/9.command-reference/ps",{"title":258,"path":259,"stem":260},"pull","/docs/command-reference/pull","docs/9.command-reference/pull",{"title":262,"path":263,"stem":264},"run","/docs/command-reference/run","docs/9.command-reference/run",{"title":266,"path":267,"stem":268},"stop","/docs/command-reference/stop","docs/9.command-reference/stop",{"title":270,"path":271,"stem":272},"up","/docs/command-reference/up","docs/9.command-reference/up",{"title":274,"path":275,"stem":276},"update","/docs/command-reference/update","docs/9.command-reference/update",{"title":278,"path":279,"stem":280},"vault","/docs/command-reference/vault","docs/9.command-reference/vault",{"title":282,"path":283,"stem":284},"version","/docs/command-reference/version","docs/9.command-reference/version",{"id":286,"title":169,"body":287,"canonical":1293,"description":1294,"extension":1295,"layout":1296,"meta":1297,"navigation":1300,"path":170,"seo":1301,"stem":171,"__hash__":1302},"docs/docs/8.advanced/99.create-your-own-template.md",{"type":288,"value":289,"toc":1276},"minimark",[290,302,307,314,325,351,361,368,372,383,388,391,397,481,487,491,494,516,523,527,537,546,552,564,579,587,591,597,606,610,613,617,629,634,637,657,660,665,668,694,699,789,793,903,907,937,972,1007,1041,1091,1122,1126,1129,1149,1153,1176,1180,1183,1198,1219,1229,1247,1251,1259,1263,1272],[291,292,293],"lead-p",{},[294,295,296,297,301],"p",{},"Starting with Spin v2.0, anyone can create a Spin template and publish them on GitHub. Users can run ",[298,299,300],"code",{},"spin new {{your-template}}"," to get up and running in seconds.",[303,304,306],"h2",{"id":305},"official-templates-vs-community-templates","Official Templates vs Community Templates",[294,308,309,310,313],{},"You may see some references to commands like ",[298,311,312],{},"spin new laravel",". These are official templates that are maintained by the Spin team.",[294,315,316,317,320,321,324],{},"If you want to use a community template, you simply append the repo organization and template name to the ",[298,318,319],{},"spin new"," command. For example, ",[298,322,323],{},"spin new serversideup/spin-template-laravel-basic",":",[326,327,333],"pre",{"className":328,"code":329,"filename":330,"language":331,"meta":332,"style":332},"language-bash shiki shiki-themes material-theme-lighter github-dark github-dark","spin new serversideup/spin-template-laravel-basic\n","Use the \"serversideup/spin-template-laravel-basic\" template","bash","",[298,334,335],{"__ignoreMap":332},[336,337,340,344,348],"span",{"class":338,"line":339},"line",1,[336,341,343],{"class":342},"soiBB","spin",[336,345,347],{"class":346},"s0vBq"," new",[336,349,350],{"class":346}," serversideup/spin-template-laravel-basic\n",[294,352,353,354,357,358,360],{},"You can see in this case, we're just appending ",[298,355,356],{},"serversideup/spin-template-laravel-basic"," to the ",[298,359,319],{}," command which will then prompt the user if they trust that repository to install.",[294,362,363],{},[364,365],"img",{"alt":366,"src":367},"GitHub Actions: Zero-downtime Deployment","/images/docs/community-templates/spin-new-community-template.png",[303,369,371],{"id":370},"structuring-your-repository","Structuring your repository",[294,373,374,375,382],{},"You can check out the ",[376,377,356],"a",{"href":378,"rel":379,"target":381},"https://github.com/serversideup/spin-template-laravel-basic",[380],"nofollow","_blank"," project to get a feel for how to structure your repository. Here are some key points:",[384,385,387],"h3",{"id":386},"metayml","meta.yml",[294,389,390],{},"This file is required and contains the metadata for your template. Spin will load the data from here to show where users can report bugs, get help, contribute to your project, and more.",[294,392,393,394,396],{},"Here's an example of a ",[298,395,387],{}," file:",[326,398,402],{"className":399,"code":400,"filename":387,"language":401,"meta":332,"style":332},"language-yaml shiki shiki-themes material-theme-lighter github-dark github-dark","---\ntitle: My Awesome Project Template\nauthors:\n  - John Smith (@johnsmith)\n  - Susan Doe (@susandoe)\ndescription: My awesome project template is the best template ever.\nrepository: https://github.com/example/my-awesome-project-template\nissues: https://github.com/example/my-awesome-project-template/issues\n","yaml",[298,403,404,409,422,431,440,448,459,470],{"__ignoreMap":332},[336,405,406],{"class":338,"line":339},[336,407,408],{"class":342},"---\n",[336,410,412,416,419],{"class":338,"line":411},2,[336,413,415],{"class":414},"sqIbZ","title",[336,417,324],{"class":418},"sG-J9",[336,420,421],{"class":346}," My Awesome Project Template\n",[336,423,425,428],{"class":338,"line":424},3,[336,426,427],{"class":414},"authors",[336,429,430],{"class":418},":\n",[336,432,434,437],{"class":338,"line":433},4,[336,435,436],{"class":418},"  -",[336,438,439],{"class":346}," John Smith (@johnsmith)\n",[336,441,443,445],{"class":338,"line":442},5,[336,444,436],{"class":418},[336,446,447],{"class":346}," Susan Doe (@susandoe)\n",[336,449,451,454,456],{"class":338,"line":450},6,[336,452,453],{"class":414},"description",[336,455,324],{"class":418},[336,457,458],{"class":346}," My awesome project template is the best template ever.\n",[336,460,462,465,467],{"class":338,"line":461},7,[336,463,464],{"class":414},"repository",[336,466,324],{"class":418},[336,468,469],{"class":346}," https://github.com/example/my-awesome-project-template\n",[336,471,473,476,478],{"class":338,"line":472},8,[336,474,475],{"class":414},"issues",[336,477,324],{"class":418},[336,479,480],{"class":346}," https://github.com/example/my-awesome-project-template/issues\n",[294,482,483,484,486],{},"Be sure to replace the values with your own information and completely fill out the ",[298,485,387],{}," file.",[384,488,490],{"id":489},"template-directory","template/ directory",[294,492,493],{},"This is where you place your template files for Docker Compose and Docker Swarm. Be sure to follow the structure of:",[495,496,497,504,510],"ul",{},[498,499,500,501],"li",{},"Base Docker Compose File: ",[298,502,503],{},"docker-compose.yml",[498,505,506,507],{},"Development Docker Compose File: ",[298,508,509],{},"docker-compose.dev.yml",[498,511,512,513],{},"Production Docker Compose File: ",[298,514,515],{},"docker-compose.prod.yml",[294,517,518,519,522],{},"You can also put any configurations under ",[298,520,521],{},".infrastructure/conf/"," if you need to provide any default configurations for your project.",[384,524,526],{"id":525},"installsh","install.sh",[294,528,529,530,532,533,536],{},"This file is required for Spin to install or initialize your template for a project. Spin someone runs ",[298,531,319],{}," or ",[298,534,535],{},"spin init",", it will load this file from your repository and execute what you have in this file.",[294,538,539,540,542,543,545],{},"Take special note of the two separate actions of ",[298,541,242],{}," (creating a new project with your template) and ",[298,544,218],{}," (adding your templates to an existing project). Your project must support both of these actions.",[294,547,548,549,551],{},"Inside of your ",[298,550,526],{}," file, you can choose what get's executed by organizing your file to have two bash functions:",[495,553,554,559],{},[498,555,556],{},[298,557,558],{},"new()",[498,560,561],{},[298,562,563],{},"init()",[294,565,566,567,569,570,572,573,575,576,578],{},"In our templates, when someone calls ",[298,568,242],{},", there are usually a few steps to do, but then we call ",[298,571,218],{}," because there's a lot of overlap that can be shared between the two actions. This means you can call ",[298,574,218],{}," from ",[298,577,242],{}," to share the same code.",[294,580,581,586],{},[376,582,585],{"href":583,"rel":584,"target":381},"https://github.com/serversideup/spin-template-laravel-basic/blob/main/install.sh",[380],"See our install.sh file"," for the serversideup/spin-template-laravel-basic template for an example.",[384,588,590],{"id":589},"post-installsh","post-install.sh",[294,592,593,594,596],{},"This file is optional and is used to run any additional commands after the ",[298,595,526],{}," file has been executed. This is useful for running any additional commands that need to be run after the template has been installed.",[294,598,599,600,605],{},"You can review ",[376,601,604],{"href":602,"rel":603,"target":381},"https://github.com/serversideup/spin/blob/main/lib/actions/init.sh",[380],"our init source code"," to see exactly when this file is executed.",[384,607,609],{"id":608},"readmemd","README.md",[294,611,612],{},"This file is extremely important. It's the first thing users will see when they visit your repository. Be sure to include a description of your template, how to use it, and any other important information for people to get started.",[303,614,616],{"id":615},"helpful-functions-you-can-use-in-your-templates","Helpful functions you can use in your templates",[294,618,619,620,622,623,628],{},"When Spin runs your ",[298,621,526],{}," file, you have access to a number of functions to help you get started. Any function from our ",[376,624,627],{"href":625,"rel":626,"target":381},"https://github.com/serversideup/spin/blob/main/lib/functions.sh",[380],"functions.sh"," file is available to be called, but here are our favorites:",[384,630,632],{"id":631},"add_user_todo_item",[298,633,631],{},[294,635,636],{},"If a user needs to take action after installing your template, you can show a \"todo\" to the user for them to take action.",[326,638,641],{"className":328,"code":639,"filename":640,"language":331,"meta":332,"style":332},"add_user_todo_item \"Please update your .env file with your database credentials.\"\n","\"add_user_todo_item\" example",[298,642,643],{"__ignoreMap":332},[336,644,645,647,651,654],{"class":338,"line":339},[336,646,631],{"class":342},[336,648,650],{"class":649},"sF_wb"," \"",[336,652,653],{"class":346},"Please update your .env file with your database credentials.",[336,655,656],{"class":649},"\"\n",[294,658,659],{},"This will show a message to the user after the template has been installed.",[384,661,663],{"id":662},"line_in_file",[298,664,662],{},[294,666,667],{},"You can use this function to manipulate files in your project. This is useful for replacing values in files or adding new lines to files.",[326,669,672],{"className":328,"code":670,"filename":671,"language":331,"meta":332,"style":332},"line_in_file [--file FILE] [--action ACTION] [ARGUMENTS...]\n","\"\"line_in_file\" syntax\"",[298,673,674],{"__ignoreMap":332},[336,675,676,678,682,685,688,691],{"class":338,"line":339},[336,677,662],{"class":342},[336,679,681],{"class":680},"sMo7A"," [--file ",[336,683,684],{"class":346},"FILE]",[336,686,687],{"class":680}," [--action ",[336,689,690],{"class":346},"ACTION]",[336,692,693],{"class":680}," [ARGUMENTS...]\n",[695,696,698],"h4",{"id":697},"parameters","Parameters",[700,701,702,721],"table",{},[703,704,705],"thead",{},[706,707,708,712,715,718],"tr",{},[709,710,711],"th",{},"Parameter",[709,713,714],{},"Description",[709,716,717],{},"Required",[709,719,720],{},"Default",[722,723,724,741,775],"tbody",{},[706,725,726,732,735,738],{},[727,728,729],"td",{},[298,730,731],{},"--file FILE",[727,733,734],{},"Specifies the target file(s) to modify. Can be used multiple times for multiple files.",[727,736,737],{},"Yes",[727,739,740],{},"N/A",[706,742,743,748,768,771],{},[727,744,745],{},[298,746,747],{},"--action ACTION",[727,749,750,751,754,755,754,758,754,761,754,764,767],{},"Determines the operation to perform. Available actions: ",[298,752,753],{},"ensure",", ",[298,756,757],{},"replace",[298,759,760],{},"after",[298,762,763],{},"exact",[298,765,766],{},"search",".",[727,769,770],{},"No",[727,772,773],{},[298,774,753],{},[706,776,777,782,785,787],{},[727,778,779],{},[298,780,781],{},"ARGUMENTS",[727,783,784],{},"The content to manipulate, which varies based on the chosen action.",[727,786,737],{},[727,788,740],{},[695,790,792],{"id":791},"actions","Actions",[700,794,795,810],{},[703,796,797],{},[706,798,799,802,804,807],{},[709,800,801],{},"Action",[709,803,714],{},[709,805,806],{},"Required Arguments",[709,808,809],{},"Behavior if Content Not Found",[722,811,812,827,842,857,872,887],{},[706,813,814,818,821,824],{},[727,815,816],{},[298,817,753],{},[727,819,820],{},"Ensures specified lines exist in the file.",[727,822,823],{},"One or more lines to ensure.",[727,825,826],{},"Appends the line(s) to the end of the file.",[706,828,829,833,836,839],{},[727,830,831],{},[298,832,757],{},[727,834,835],{},"Replaces a line containing specific content with a new line.",[727,837,838],{},"Two arguments: search content and replacement line.",[727,840,841],{},"Appends the replacement line to the file.",[706,843,844,848,851,854],{},[727,845,846],{},[298,847,760],{},[727,849,850],{},"Inserts a new line after a line containing specific content.",[727,852,853],{},"Two arguments: search content and line to insert.",[727,855,856],{},"Appends both the search content and new line to the file.",[706,858,859,863,866,869],{},[727,860,861],{},[298,862,763],{},[727,864,865],{},"Performs an exact replacement of text within the file. Special characters (dots, brackets, parentheses, etc.) are treated as literal characters.",[727,867,868],{},"Two arguments: exact text to replace and replacement text.",[727,870,871],{},"Returns an error.",[706,873,874,878,881,884],{},[727,875,876],{},[298,877,766],{},[727,879,880],{},"Searches for specified content in the file.",[727,882,883],{},"One argument: content to search for.",[727,885,886],{},"Returns false (exit code 1).",[706,888,889,894,897,900],{},[727,890,891],{},[298,892,893],{},"delete",[727,895,896],{},"Deletes lines containing specified content.",[727,898,899],{},"One argument: content to delete.",[727,901,902],{},"Returns an error if the content is not found.",[695,904,906],{"id":905},"usage-examples","Usage Examples",[326,908,911],{"className":328,"code":909,"filename":910,"language":331,"meta":332,"style":332},"line_in_file --file /etc/hosts --action ensure \"127.0.0.1 localhost\"\n","Ensure a line exists in a file",[298,912,913],{"__ignoreMap":332},[336,914,915,917,921,924,927,930,932,935],{"class":338,"line":339},[336,916,662],{"class":342},[336,918,920],{"class":919},"sSJ72"," --file",[336,922,923],{"class":346}," /etc/hosts",[336,925,926],{"class":919}," --action",[336,928,929],{"class":346}," ensure",[336,931,650],{"class":649},[336,933,934],{"class":346},"127.0.0.1 localhost",[336,936,656],{"class":649},[326,938,941],{"className":328,"code":939,"filename":940,"language":331,"meta":332,"style":332},"line_in_file --file config.txt --action replace \"old_setting=value\" \"new_setting=updated_value\"\n","Replace a line in a file",[298,942,943],{"__ignoreMap":332},[336,944,945,947,949,952,954,957,959,962,965,967,970],{"class":338,"line":339},[336,946,662],{"class":342},[336,948,920],{"class":919},[336,950,951],{"class":346}," config.txt",[336,953,926],{"class":919},[336,955,956],{"class":346}," replace",[336,958,650],{"class":649},[336,960,961],{"class":346},"old_setting=value",[336,963,964],{"class":649},"\"",[336,966,650],{"class":649},[336,968,969],{"class":346},"new_setting=updated_value",[336,971,656],{"class":649},[326,973,976],{"className":328,"code":974,"filename":975,"language":331,"meta":332,"style":332},"  line_in_file --file script.sh --action after \"#!/bin/bash\" \"# This script does something cool\"\n","Insert a line after a specific line",[298,977,978],{"__ignoreMap":332},[336,979,980,983,985,988,990,993,995,998,1000,1002,1005],{"class":338,"line":339},[336,981,982],{"class":342},"  line_in_file",[336,984,920],{"class":919},[336,986,987],{"class":346}," script.sh",[336,989,926],{"class":919},[336,991,992],{"class":346}," after",[336,994,650],{"class":649},[336,996,997],{"class":346},"#!/bin/bash",[336,999,964],{"class":649},[336,1001,650],{"class":649},[336,1003,1004],{"class":346},"# This script does something cool",[336,1006,656],{"class":649},[326,1008,1011],{"className":328,"code":1009,"filename":1010,"language":331,"meta":332,"style":332},"line_in_file --file document.txt --action exact \"old text\" \"new text\"\n","Perform an exact text replacement",[298,1012,1013],{"__ignoreMap":332},[336,1014,1015,1017,1019,1022,1024,1027,1029,1032,1034,1036,1039],{"class":338,"line":339},[336,1016,662],{"class":342},[336,1018,920],{"class":919},[336,1020,1021],{"class":346}," document.txt",[336,1023,926],{"class":919},[336,1025,1026],{"class":346}," exact",[336,1028,650],{"class":649},[336,1030,1031],{"class":346},"old text",[336,1033,964],{"class":649},[336,1035,650],{"class":649},[336,1037,1038],{"class":346},"new text",[336,1040,656],{"class":649},[326,1042,1045],{"className":328,"code":1043,"filename":1044,"language":331,"meta":332,"style":332},"# Works perfectly with special regex characters\nline_in_file --file docker-compose.yml --action exact \\\n  \"traefik.http.services.app.loadbalancer.server.port=8443\" \\\n  \"traefik.http.services.app.loadbalancer.server.port=8080\"\n","Replace text with special characters (dots, parentheses, etc.)",[298,1046,1047,1053,1070,1082],{"__ignoreMap":332},[336,1048,1049],{"class":338,"line":339},[336,1050,1052],{"class":1051},"sutJx","# Works perfectly with special regex characters\n",[336,1054,1055,1057,1059,1062,1064,1066],{"class":338,"line":411},[336,1056,662],{"class":342},[336,1058,920],{"class":919},[336,1060,1061],{"class":346}," docker-compose.yml",[336,1063,926],{"class":919},[336,1065,1026],{"class":346},[336,1067,1069],{"class":1068},"sVPC0"," \\\n",[336,1071,1072,1075,1078,1080],{"class":338,"line":424},[336,1073,1074],{"class":649},"  \"",[336,1076,1077],{"class":346},"traefik.http.services.app.loadbalancer.server.port=8443",[336,1079,964],{"class":649},[336,1081,1069],{"class":1068},[336,1083,1084,1086,1089],{"class":338,"line":433},[336,1085,1074],{"class":649},[336,1087,1088],{"class":346},"traefik.http.services.app.loadbalancer.server.port=8080",[336,1090,656],{"class":649},[326,1092,1095],{"className":328,"code":1093,"filename":1094,"language":331,"meta":332,"style":332},"line_in_file --file file1.txt --file file2.txt --action ensure \"This line should be in both files\"\n","Operate on multiple files",[298,1096,1097],{"__ignoreMap":332},[336,1098,1099,1101,1103,1106,1108,1111,1113,1115,1117,1120],{"class":338,"line":339},[336,1100,662],{"class":342},[336,1102,920],{"class":919},[336,1104,1105],{"class":346}," file1.txt",[336,1107,920],{"class":919},[336,1109,1110],{"class":346}," file2.txt",[336,1112,926],{"class":919},[336,1114,929],{"class":346},[336,1116,650],{"class":649},[336,1118,1119],{"class":346},"This line should be in both files",[336,1121,656],{"class":649},[695,1123,1125],{"id":1124},"error-handling","Error Handling",[294,1127,1128],{},"The function will output error messages to stderr and return a non-zero exit code in the following cases:",[495,1130,1131,1134,1137,1140,1143],{},[498,1132,1133],{},"No file is specified",[498,1135,1136],{},"No content is specified",[498,1138,1139],{},"Invalid action is provided",[498,1141,1142],{},"Incorrect number of arguments for a specific action",[498,1144,1145,1146,1148],{},"Exact text not found when using the ",[298,1147,763],{}," action",[695,1150,1152],{"id":1151},"notes","Notes",[495,1154,1155,1162,1168,1173],{},[498,1156,1157,1158,1161],{},"The function uses ",[298,1159,1160],{},"sed_inplace"," for in-place file modifications. Ensure this function is available in your environment.",[498,1163,1164,1165,1167],{},"When using the ",[298,1166,757],{}," action, forward slashes in the replacement string are automatically escaped.",[498,1169,1164,1170,1172],{},[298,1171,763],{}," action, all regex special characters (dots, brackets, parentheses, etc.) are automatically escaped, ensuring true literal matching. This makes it perfect for replacing configuration values, URLs, or any text containing special characters.",[498,1174,1175],{},"The function creates the target file if it doesn't exist.",[303,1177,1179],{"id":1178},"testing-your-template","Testing your template",[294,1181,1182],{},"Before publishing, be sure to test your template a number of times between adding a new project and initializing into an existing project. This will help you prevent any issues that users may run into.",[294,1184,1185,1186,1189,1190,1193,1194,1197],{},"You can also provide a branch to download with the ",[298,1187,1188],{},"--branch"," option or you can test locally with the ",[298,1191,1192],{},"--local"," option if you're working on a new feature or bug fix. This way, users can test your changes before you merge them into your ",[298,1195,1196],{},"main"," branch.",[326,1199,1202],{"className":328,"code":1200,"filename":1201,"language":331,"meta":332,"style":332},"spin new serversideup/spin-template-laravel-basic --branch test-branch\n","Test a branch",[298,1203,1204],{"__ignoreMap":332},[336,1205,1206,1208,1210,1213,1216],{"class":338,"line":339},[336,1207,343],{"class":342},[336,1209,347],{"class":346},[336,1211,1212],{"class":346}," serversideup/spin-template-laravel-basic",[336,1214,1215],{"class":919}," --branch",[336,1217,1218],{"class":346}," test-branch\n",[294,1220,1221,1222,1225,1226,1228],{},"The above command will pull the ",[298,1223,1224],{},"test-branch"," from the ",[298,1227,378],{}," repository and use that version of the template.",[326,1230,1233],{"className":328,"code":1231,"filename":1232,"language":331,"meta":332,"style":332},"spin new --local /path/to/your/template\n","Test locally",[298,1234,1235],{"__ignoreMap":332},[336,1236,1237,1239,1241,1244],{"class":338,"line":339},[336,1238,343],{"class":342},[336,1240,347],{"class":346},[336,1242,1243],{"class":919}," --local",[336,1245,1246],{"class":346}," /path/to/your/template\n",[303,1248,1250],{"id":1249},"publishing-your-template","Publishing your template",[294,1252,1253,1254,1256,1257,301],{},"Once you're ready to publish your template, simply push to your ",[298,1255,1196],{}," branch on GitHub. Users can then run ",[298,1258,300],{},[303,1260,1262],{"id":1261},"getting-your-template-listed-on-the-community","Getting your template listed on the community",[294,1264,1265,1266,1271],{},"We're working on a way to list community templates on the Spin website. If you're interested in having your template listed, ",[376,1267,1270],{"href":1268,"rel":1269,"target":381},"https://github.com/serversideup/spin/discussions",[380],"please open a Discussion on GitHub"," and we'll get you added to the list.",[1273,1274,1275],"style",{},"html pre.shiki code .soiBB, html code.shiki .soiBB{--shiki-light:#E2931D;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .s0vBq, html code.shiki .s0vBq{--shiki-light:#91B859;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .sqIbZ, html code.shiki .sqIbZ{--shiki-light:#E53935;--shiki-default:#85E89D;--shiki-dark:#85E89D}html pre.shiki code .sG-J9, html code.shiki .sG-J9{--shiki-light:#39ADB5;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .sF_wb, html code.shiki .sF_wb{--shiki-light:#39ADB5;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .sMo7A, html code.shiki .sMo7A{--shiki-light:#90A4AE;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .sSJ72, html code.shiki .sSJ72{--shiki-light:#91B859;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sVPC0, html code.shiki .sVPC0{--shiki-light:#90A4AE;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}",{"title":332,"searchDepth":411,"depth":411,"links":1277},[1278,1279,1286,1290,1291,1292],{"id":305,"depth":411,"text":306},{"id":370,"depth":411,"text":371,"children":1280},[1281,1282,1283,1284,1285],{"id":386,"depth":424,"text":387},{"id":489,"depth":424,"text":490},{"id":525,"depth":424,"text":526},{"id":589,"depth":424,"text":590},{"id":608,"depth":424,"text":609},{"id":615,"depth":411,"text":616,"children":1287},[1288,1289],{"id":631,"depth":424,"text":631},{"id":662,"depth":424,"text":662},{"id":1178,"depth":411,"text":1179},{"id":1249,"depth":411,"text":1250},{"id":1261,"depth":411,"text":1262},null,"Learn how to create your own Spin template.","md","docs",{"head":1298},{"title":1299},"Create your own Spin Template - Spin by Server Side Up",true,{"title":169,"description":1294},"Oz5FrP69f8DyxBdHerKLYijTN9b_ExBcGVJeYxW002Y",[1304,1306],{"title":165,"path":166,"stem":167,"description":1305,"children":-1},"Look at common templates on how to add services to your project.",{"title":173,"path":174,"stem":175,"description":1307,"children":-1},"Learn how to migrate from Spin v2 to v3.",1769465036433]