Skip to content

Create Stack

Mikhail Konin edited this page Feb 28, 2026 · 1 revision

Create Stack

Step-by-step guide for creating a new application stack.

Stack Structure

stacks/my-app/
β”œβ”€β”€ docker-stack.yml     # Docker Compose for Swarm
β”œβ”€β”€ services.yaml        # Service definitions
β”œβ”€β”€ variables.yaml       # Build/deploy variables
β”œβ”€β”€ externals.yaml       # Required secrets
β”œβ”€β”€ settings.yaml        # Stack settings
β”œβ”€β”€ templates.yaml       # Jinja2 config (optional)
β”œβ”€β”€ templates/           # Jinja2 templates (optional)
β”‚   └── docker-stack.j2
└── hooks/
    β”œβ”€β”€ pre-deploy.sh    # Runs BEFORE deploy
    └── post-deploy.sh   # Runs AFTER deploy

Option A: Via Wizard (Recommended)

swarmcli create
# Select: Stack
# Choose profile, enter stack name
# Wizard creates all files with documenting comments

Then edit the generated files β€” fill in your services and configuration.

Option B: Manual

Step 1: Create Structure

cd /opt/swarmcli/profiles/server-dev/stacks
mkdir -p my-app/hooks
cd my-app

Step 2: services.yaml

Each service needs a type: git (built from source), registry (pre-built image), or none (derived service).

services:
  api:
    type: git
    repo: https://github.com/your-org/api.git
    default_branch: develop
    build:
      context: .
      dockerfile: Dockerfile
    image: local/api
    meta:
      group: backend
      name: API Service

  redis:
    type: registry
    image: redis:7-alpine
    meta:
      group: cache

See Services for type details.

Step 3: docker-stack.yml

For type: git services, use TAG_* variables (auto-generated from service name, uppercased, hyphens become underscores):

services:
  api:
    image: local/api:${TAG_API}
    ports:
      - "8080:8080"
    environment:
      - TZ=${GLOBAL_TZ}
      - LOG_LEVEL=${DEPLOY_LOG_LEVEL}
    networks:
      - backend
    deploy:
      replicas: 2
      update_config:
        parallelism: 1
        delay: 10s

  redis:
    image: redis:7-alpine
    networks:
      - backend

networks:
  backend:
    driver: overlay

Step 4: variables.yaml

build:
  NODE_ENV: production

runtime:
  env:
    LOG_LEVEL: info
    API_VERSION: "1.0.0"

Step 5: settings.yaml

services_ready_timeout: 45
diagnostics_logs_tail: 30

Step 6: externals.yaml

secrets: []

If secrets needed:

secrets:
  - db_password
  - api_key

Step 7: Hooks

hooks/pre-deploy.sh:

#!/usr/bin/env bash
set -eo pipefail
echo "Pre-deploy: $STACK"

hooks/post-deploy.sh:

#!/usr/bin/env bash
set -eo pipefail
echo "Post-deploy: $STACK"
chmod +x hooks/*.sh

Validate and Deploy

cd /opt/swarmcli

swarmcli check my-app              # Validate
swarmcli deploy my-app --dry-run   # Preview
swarmcli deploy my-app             # Deploy

Stack Examples

Simple (Registry Only)

# services.yaml
services:
  nginx:
    type: registry
    image: nginx:alpine
    meta:
      group: frontend
# docker-stack.yml
services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"

Microservice with Database

# services.yaml
services:
  api:
    type: git
    repo: https://github.com/your-org/api.git
    image: local/api
  postgres:
    type: registry
    image: postgres:15

Multi-Service (API + Worker)

Use type: none for services sharing the same image:

# services.yaml
services:
  api:
    type: git
    repo: https://github.com/your-org/backend.git
    image: local/backend
  worker:
    type: none
  redis:
    type: registry
    image: redis:7-alpine
# docker-stack.yml
services:
  api:
    image: local/backend:${TAG_API}
    command: ["./app", "serve"]
  worker:
    image: local/backend:${TAG_API}
    command: ["./app", "worker"]
  redis:
    image: redis:7-alpine

Using Jinja2 Templates

For complex stacks with variable substitution and resource injection:

swarmcli template init my-app

See Jinja2-Templating for details.

Checklist

  • Stack directory created
  • services.yaml with service definitions
  • docker-stack.yml with Swarm config
  • variables.yaml with variables
  • settings.yaml with timeouts
  • externals.yaml (even if empty)
  • Hooks executable (chmod +x)
  • swarmcli check passes

Next: Deployment-Guide

Clone this wiki locally