Docs / Core Concepts / Stacks

Stacks

A stack is the top-level organizational unit in sh0. It groups related applications and services together, providing shared configuration and a unified view of your project.

What is a Stack?

A stack represents a project or product that consists of one or more applications and services. For example, a typical web application stack might include:

  • A frontend app (React, Vue, Svelte)
  • A backend API (Node.js, Python, Go)
  • A PostgreSQL database
  • A Redis cache
  • A background worker

All of these live within one stack, share environment variables, and can communicate over a private Docker network. When you open a stack in the dashboard, you see all its components at a glance.

Stack list view showing three stacks: 'production-api' with 4 services running, 'staging-frontend' with 2 services running, and 'blog' with 1 service running -- each showing status badges and resource usage
The stack list gives you an overview of all your projects

Stacks vs Apps vs Services

Understanding the hierarchy is important:

ConceptDescriptionExample
StackA project or product grouping"E-commerce Platform"
AppA deployable unit within a stack"api", "frontend", "worker"
ServiceA running container instance of an app"api-v3-abc123" (container)

A stack contains one or more apps. Each app runs as one or more services (containers). When you deploy an app, sh0 creates a new service (container) and optionally removes the old one after the health check passes.

Note
All apps within a stack share a Docker network, which means they can communicate with each other using their app name as a hostname. For example, your frontend can reach the API at http://api:3000 without any extra configuration.

Creating a Stack

There are two ways to create a stack:

From the Dashboard:

  1. Click New Stack in the top-right corner or from the stacks page.
  2. Enter a name (lowercase, alphanumeric, and hyphens only).
  3. Add an optional description.
  4. Click Create Stack.
Create Stack dialog with fields for name, description, and a Create Stack button
Creating a new stack from the dashboard

From the API:

Terminal
curl -X POST http://localhost:9000/api/projects \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-stack", "description": "Production web app"}'

Stack Detail View

Clicking on a stack opens the detail view, which provides a complete picture of your project:

Stack detail view showing tabs for Apps, Environment, Domains, Backups, and Settings. The Apps tab is active, showing a grid of three apps: frontend (running), api (running), and database (running) with resource usage bars
The stack detail view with all apps visible
  • Apps tab -- All applications in this stack with their status, resource usage, and quick actions (deploy, restart, stop).
  • Environment tab -- Stack-level environment variables shared across all apps.
  • Domains tab -- All domains assigned to apps in this stack.
  • Backups tab -- Backup schedules and history for databases in this stack.
  • Settings tab -- Stack name, description, danger zone (delete stack).

Stack Environment Variables

Stack-level environment variables are inherited by all apps in the stack. This is useful for shared configuration like API keys, database URLs, or feature flags that apply to the entire project.

Example Stack Variables
DATABASE_URL=postgres://user:pass@db:5432/myapp
REDIS_URL=redis://cache:6379
APP_ENV=production
STRIPE_API_KEY=sk_live_...
Stack Environment tab showing a list of environment variables with name, value (masked), and action buttons. An 'Add Variable' button and 'Import .env' button are at the top
Managing stack-level environment variables
Variable Precedence
App-level environment variables override stack-level ones. If a stack defines APP_ENV=production and an app defines APP_ENV=staging, the app uses staging. This lets you share defaults while allowing per-app overrides.

Stack Settings

The Settings tab lets you modify the stack's metadata and perform administrative actions:

  • Name and Description -- Update the stack's display name and description.
  • Docker Network -- View the internal Docker network name for this stack.
  • Danger Zone -- Delete the stack and all its apps, services, and data. This action is irreversible.
Deleting a Stack
Deleting a stack removes all apps, containers, volumes, and associated data. Always back up any important data before deleting. This action cannot be undone.

Common Patterns

Here are some common ways to organize stacks:

Per-Project

One stack per project with all its services.

saas-app (frontend + api + db + redis)

Per-Environment

Separate stacks for staging and production.

myapp-staging / myapp-production

Per-Client

Agencies can organize by client.

client-acme / client-globex

Shared Services

Common infrastructure in its own stack.

infrastructure (traefik + monitoring + logging)

Managing Stacks via API

All stack operations are available through the REST API. Here are the key endpoints:

Terminal
# List all stacks
curl http://localhost:9000/api/projects \
  -H "Authorization: Bearer YOUR_TOKEN"

# Get a specific stack
curl http://localhost:9000/api/projects/STACK_ID \
  -H "Authorization: Bearer YOUR_TOKEN"

# Update a stack
curl -X PUT http://localhost:9000/api/projects/STACK_ID \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "new-name", "description": "Updated description"}'

# Delete a stack
curl -X DELETE http://localhost:9000/api/projects/STACK_ID \
  -H "Authorization: Bearer YOUR_TOKEN"
Note
For a complete list of API endpoints, see the API Reference.