Create your own Spin Template

Starting with Spin v2.0, anyone can create a Spin template and publish them on GitHub. Users can run spin new {{your-template}} to get up and running in seconds.

Official Templates vs Community Templates

You may see some references to commands like spin new laravel. These are official templates that are maintained by the Spin team.

If you want to use a community template, you simply append the repo organization and template name to the spin new command. For example, spin new serversideup/spin-template-laravel-basic:

Use the "serversideup/spin-template-laravel-basic" template

spin new serversideup/spin-template-laravel-basic

You can see in this case, we're just appending serversideup/spin-template-laravel-basic to the spin new command which will then prompt the user if they trust that repository to install.

GitHub Actions: Zero-downtime Deployment

Structuring your repository

You can check out the serversideup/spin-template-laravel-basic project to get a feel for how to structure your repository. Here are some key points:

meta.yml

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.

Here's an example of a meta.yml file:

meta.yml

---
title: My Awesome Project Template
authors:
  - John Smith (@johnsmith)
  - Susan Doe (@susandoe)
description: My awesome project template is the best template ever.
repository: https://github.com/example/my-awesome-project-template
issues: https://github.com/example/my-awesome-project-template/issues

Be sure to replace the values with your own information and completely fill out the meta.yml file.

template/ directory

This is where you place your template files for Docker Compose and Docker Swarm. Be sure to follow the structure of:

  • Base Docker Compose File: docker-compose.yml
  • Development Docker Compose File: docker-compose.dev.yml
  • Production Docker Compose File: docker-compose.prod.yml

You can also put any configurations under .infrastructure/conf/ if you need to provide any default configurations for your project.

install.sh

This file is required for Spin to install or initialize your template for a project. Spin someone runs spin new or spin init, it will load this file from your repository and execute what you have in this file.

Take special note of the two separate actions of new (creating a new project with your template) and init (adding your templates to an existing project). Your project must support both of these actions.

Inside of your install.sh file, you can choose what get's executed by organizing your file to have two bash functions:

  • new()
  • init()

In our templates, when someone calls new, there are usually a few steps to do, but then we call init because there's a lot of overlap that can be shared between the two actions. This means you can call init from new to share the same code.

See our install.sh file for the serversideup/spin-template-laravel-basic template for an example.

post-install.sh

This file is optional and is used to run any additional commands after the install.sh file has been executed. This is useful for running any additional commands that need to be run after the template has been installed.

You can review our init source code to see exactly when this file is executed.

README.md

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.

Helpful functions you can use in your templates

When Spin runs your install.sh file, you have access to a number of functions to help you get started. Any function from our functions.sh file is available to be called, but here are our favorites:

add_user_todo_item

If a user needs to take action after installing your template, you can show a "todo" to the user for them to take action.

`add_user_todo_item` example

add_user_todo_item "Please update your .env file with your database credentials."

This will show a message to the user after the template has been installed.

line_in_file

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.

`line_in_file` syntax

line_in_file [--file FILE] [--action ACTION] [ARGUMENTS...]

Parameters

ParameterDescriptionRequiredDefault
--file FILESpecifies the target file(s) to modify. Can be used multiple times for multiple files.YesN/A
--action ACTIONDetermines the operation to perform. Available actions: ensure, replace, after, exact, search.Noensure
ARGUMENTSThe content to manipulate, which varies based on the chosen action.YesN/A

Actions

ActionDescriptionRequired ArgumentsBehavior if Content Not Found
ensureEnsures specified lines exist in the file.One or more lines to ensure.Appends the line(s) to the end of the file.
replaceReplaces a line containing specific content with a new line.Two arguments: search content and replacement line.Appends the replacement line to the file.
afterInserts a new line after a line containing specific content.Two arguments: search content and line to insert.Appends both the search content and new line to the file.
exactPerforms an exact replacement of text within the file.Two arguments: exact text to replace and replacement text.Returns an error.
searchSearches for specified content in the file.One argument: content to search for.Returns false (exit code 1).
deleteDeletes lines containing specified content.One argument: content to delete.Returns an error if the content is not found.

Usage Examples

Ensure a line exists in a file

line_in_file --file /etc/hosts --action ensure "127.0.0.1 localhost"

Replace a line in a file

line_in_file --file config.txt --action replace "old_setting=value" "new_setting=updated_value"

Insert a line after a specific line

  line_in_file --file script.sh --action after "#!/bin/bash" "# This script does something cool"

Perform an exact text replacement

line_in_file --file document.txt --action exact "old text" "new text"

Operate on multiple files

line_in_file --file file1.txt --file file2.txt --action ensure "This line should be in both files"

Error Handling

The function will output error messages to stderr and return a non-zero exit code in the following cases:

  • No file is specified
  • No content is specified
  • Invalid action is provided
  • Incorrect number of arguments for a specific action
  • Exact text not found when using the exact action

Notes

  • The function uses sed_inplace for in-place file modifications. Ensure this function is available in your environment.
  • When using the replace action, forward slashes in the replacement string are automatically escaped.
  • The function creates the target file if it doesn't exist.

Testing your template

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.

You can also provide a branch to download with the --branch option or you can test locally with the --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 main branch.

Test a branch

spin new serversideup/spin-template-laravel-basic --branch test-branch

The above command will pull the test-branch from the https://github.com/serversideup/spin-template-laravel-basic repository and use that version of the template.

Test locally

spin new --local /path/to/your/template

Publishing your template

Once you're ready to publish your template, simply push to your main branch on GitHub. Users can then run spin new {{your-template}} to get up and running in seconds.

Getting your template listed on the community

We're working on a way to list community templates on the Spin website. If you're interested in having your template listed, please open a Discussion on GitHub and we'll get you added to the list.