What are Workflows?
Workflows define the sequence of actions executed during server lifecycle events. They handle everything from copying template files to installing plugins and applying configurations.How Workflows Work
During server preparation:- Serverhost receives a start request from the Controller
- Loads the setup workflow from
workflows/internal/setup.yml - Executes each step in order with the server context
- Reports status back to the Controller
- Server stop signal received
- Loads the cleanup workflow from
workflows/internal/cleanup.yml - Executes cleanup steps (cache push, directory deletion)
Workflow Structure
Workflows are YAML files in theworkflows/ directory:
Built-in Workflows
Setup Workflow
The default setup workflow (workflows/internal/setup.yml) performs:
- Cache Pull - Copy cached files from previous runs
- Template Copy - Apply template hierarchy (every, type, software, tagged)
- Plugin Installation - Download and install plugins
- Configuration - Apply configurators for server software
Cleanup Workflow
The cleanup workflow (workflows/internal/cleanup.yml) performs:
- Cache Push - Save reusable files for faster future starts
- Directory Deletion - Remove the server directory
Workflow Actions
copy
Copies files or directories from source to destination.
| Field | Type | Description |
|---|---|---|
from | path | Source file or directory |
to | path | Destination file or directory |
replace | boolean | Overwrite existing files (default: true) |
create-dirs | boolean | Create parent directories if missing (default: true) |
delete
Deletes a file or directory.
| Field | Type | Description |
|---|---|---|
path | path | File or directory to delete |
force | boolean | Force deletion of non-empty directories (default: true) |
min-age | duration | Only delete files/directories older than this duration (e.g. 30d, 12h, 60m, 90s) |
compress
Compresses a file or directory into an archive.
Supported formats: .tar.gz, .tgz, .tar.bz2, .tbz2, .tar.xz, .txz, .zip, .tar, .7z
| Field | Type | Description |
|---|---|---|
from | path | Source file or directory to compress |
to | path | Destination archive path |
replace | boolean | Overwrite existing archive (default: true) |
decompress
Extracts files from an archive to a destination directory.
Supported formats: .tar.gz, .tgz, .tar.bz2, .tbz2, .tar.xz, .txz, .zip, .tar, .7z
| Field | Type | Description |
|---|---|---|
from | path | Path to the archive file |
to | path | Destination directory to extract into |
replace | boolean | Overwrite existing files (default: true) |
upload
Uploads a file to a remote URL via HTTP.
| Field | Type | Description |
|---|---|---|
from | path | Path to the local file to upload |
to | string | Target URL |
method | string | HTTP method (default: PUT) |
authorization-bearer | string | Bearer token for authorization |
| Variable | Description |
|---|---|
upload.response.code | HTTP response status code |
upload.response.body | HTTP response body |
for-each
Iterates over a list and executes nested steps for each item.
| Field | Type | Description |
|---|---|---|
items | list | Items to iterate over |
as | string | Variable name for current item |
steps | list | Steps to execute for each item |
plugins-load
Installs plugins from configured sources (Modrinth, Hangar, Spigot, URL).
| Field | Type | Description |
|---|---|---|
dir | path | Directory to install plugins into |
- Server software (Paper, Velocity, etc.)
- Minecraft version
- Platform compatibility
configurator
Applies a configurator to configure server files.
| Field | Type | Description |
|---|---|---|
configurator | string | Configurator name (from options/configurators/) |
dir | path | Server directory to configure |
Placeholders
Workflows support dynamic placeholders replaced at runtime:Server Context
| Placeholder | Description |
|---|---|
{{server-dir}} | Server’s working directory |
{{server-name}} | Server name (e.g., lobby-1) |
{{group}} | Group name |
{{port}} | Assigned port |
{{max-players}} | Maximum player count |
{{memory}} | Allocated memory (MB) |
Path Context
| Placeholder | Description |
|---|---|
{{templates}} | Templates base directory |
{{running}} | Running servers directory |
{{cache}} | Cache directory |
Blueprint Context
| Placeholder | Description |
|---|---|
{{configurator}} | Configurator name from blueprint |
{{software}} | Server software (paper, velocity, etc.) |
{{minecraft-version}} | Minecraft version |
{{type}} | Server type (proxy, server, lobby) |
Custom Properties
Access custom properties from the server:$. prefix accesses the server’s properties map.
Default Setup Flow
The built-in setup workflow follows this order:Customizing Workflows
Override Default Workflow
Create your own setup workflow:Add Custom Steps
Extend the workflow with additional actions:Troubleshooting
Workflow not executing
Workflow not executing
Symptom: Server starts but workflow steps don’t run.Solution:
- Verify file exists:
workflows/internal/setup.yml - Validate YAML syntax (use a linter)
- Check serverhost logs:
sc logs serverhost
Placeholder not replaced
Placeholder not replaced
Symptom: Files contain literal
{{name}} instead of values.Solution:- Check syntax:
{{name}}(double braces, no spaces) - Verify property exists in server context
- For custom properties use:
{{$.property-name}}
Copy action fails
Copy action fails
Symptom: Workflow fails at copy step.Solution:
- Verify source path exists
- Check file permissions
- Add
create-dirs: trueif parent directories missing
Plugin installation fails
Plugin installation fails
Symptom: Plugins not downloaded during workflow.Solution:
- Check network connectivity to Modrinth/Hangar
- Verify plugin exists for your Minecraft version
- Check
options/modrinth-platform-mappings.yml
Compress/decompress action fails
Compress/decompress action fails
Symptom: Workflow fails at compress or decompress step.Solution:
- Verify the archive format is supported (
.tar.gz,.zip,.7z, etc.) - Ensure the source path exists
- Check available disk space at the destination
Upload action fails
Upload action fails
Symptom: Workflow fails at upload step.Solution:
- Check network connectivity to the target URL
- Verify the bearer token is valid and correctly set
- Inspect the response code via
upload.response.codecontext variable - Ensure the source file exists and is not a directory