Skip to content

stackpad.json Reference

The stackpad.json file defines a multi-service stack that can be deployed as a template on Stackpad. This reference documents the full specification.

Basic structure

{
"name": "My Template",
"description": "A template for deploying my stack",
"inputs": {},
"sharedEnv": {},
"services": {}
}

Top-level fields

FieldTypeRequiredDescription
namestringYesDisplay name of the template
descriptionstringNoShort description shown in the template gallery
inputsobjectNoUser-provided values when deploying
sharedEnvobjectNoEnvironment variables shared across all services
servicesobjectYesService definitions

Inputs

Inputs are values that the user provides when deploying the template. They can be referenced in other parts of the template.

{
"inputs": {
"GIT_URL": {
"type": "string",
"description": "GitHub repository URL"
},
"BRANCH": {
"type": "string",
"description": "Branch to deploy",
"default": "main"
}
}
}

Reference inputs with ${{input.GIT_URL}}.

Shared environment variables

Variables defined in sharedEnv are available to all services:

{
"sharedEnv": {
"POSTGRES_PASSWORD": "${{secret(32)}}",
"JWT_SECRET": "${{secret(64)}}",
"NODE_ENV": "production"
}
}

Variable interpolation

Templates support three types of interpolation:

SyntaxDescriptionExample
${{input.NAME}}Reference a user input${{input.GIT_URL}}
${{sharedEnv.NAME}}Reference a shared variable${{sharedEnv.POSTGRES_PASSWORD}}
${{secret(N)}}Generate a random secret of N characters${{secret(32)}}

Services

Each service is defined as a key-value pair in the services object:

{
"services": {
"web": {
"type": "web",
"git": {
"url": "${{input.GIT_URL}}",
"branch": "main"
},
"port": 3000,
"env": {
"DATABASE_URL": "postgresql://postgres:${{sharedEnv.POSTGRES_PASSWORD}}@postgres:5432/app"
},
"dependsOn": ["postgres"]
}
}
}

Service fields

FieldTypeRequiredDescription
typeweb | database | cache | serviceYesService type
imagestringNo*Docker image to use
gitobjectNo*Git repository config
git.urlstringYes (if git)Repository URL
git.branchstringNoBranch name (default: main)
portnumberYesPort the service listens on
envobjectNoService-specific environment variables
dependsOnstring[]NoServices that must start first
volumesobjectNoPersistent volume mounts
healthCheckobjectNoCustom health check config
exposesobjectNoConnection strings to inject into dependent services

* Either image or git is required, not both.

Dependencies

Use dependsOn to control startup order. A service waits for its dependencies to be healthy before starting:

{
"services": {
"web": {
"dependsOn": ["postgres", "redis"]
}
}
}

Exposes

Use exposes to define connection strings that are automatically injected into dependent services:

{
"services": {
"postgres": {
"exposes": {
"DATABASE_URL": "postgresql://postgres:${{sharedEnv.POSTGRES_PASSWORD}}@postgres:5432/app"
}
}
}
}

Full example

{
"name": "Next.js + PostgreSQL",
"description": "Full-stack web application with a PostgreSQL database",
"inputs": {
"GIT_URL": {
"type": "string",
"description": "Your Next.js repository URL"
}
},
"sharedEnv": {
"POSTGRES_PASSWORD": "${{secret(32)}}"
},
"services": {
"postgres": {
"type": "database",
"image": "postgres:16",
"port": 5432,
"env": {
"POSTGRES_PASSWORD": "${{sharedEnv.POSTGRES_PASSWORD}}",
"POSTGRES_DB": "app"
},
"volumes": {
"/var/lib/postgresql/data": "postgres-data"
},
"exposes": {
"DATABASE_URL": "postgresql://postgres:${{sharedEnv.POSTGRES_PASSWORD}}@postgres:5432/app"
}
},
"web": {
"type": "web",
"git": {
"url": "${{input.GIT_URL}}",
"branch": "main"
},
"port": 3000,
"dependsOn": ["postgres"]
}
}
}

What’s next?