Skip to main content
POST
/
api
/
stacks
curl -X POST "https://your-dockhand-instance.com/api/stacks?env=1" \
  -H "Content-Type: application/json" \
  -H "Cookie: auth_token=your_token" \
  -d '{
    "name": "my-app",
    "compose": "version: '\''3.8'\''\nservices:\n  web:\n    image: nginx:latest\n    ports:\n      - \"8080:80\"\n    environment:\n      - APP_ENV=${APP_ENV}",
    "start": true,
    "envVars": [
      {
        "key": "APP_ENV",
        "value": "production",
        "isSecret": false
      },
      {
        "key": "API_KEY",
        "value": "secret_key_here",
        "isSecret": true
      }
    ]
  }'
{
  "success": true,
  "started": true,
  "output": "[+] Running 2/2\n ✔ Network my-app_default  Created\n ✔ Container my-app-web-1  Started"
}

Query Parameters

env
string
required
Environment ID where the stack will be deployed

Body Parameters

name
string
required
Stack name (must be unique within the environment)
compose
string
required
Docker Compose file content (YAML)
start
boolean
default:true
Whether to start the stack immediately. If false, only creates the compose file without deploying.
envVars
array
Environment variables for the stack
rawEnvContent
string
Raw .env file content (non-secrets with comments preserved)
composePath
string
Custom path for the compose file (for adopted stacks)
envPath
string
Custom path for the .env file (for adopted stacks)

Response

This endpoint uses Server-Sent Events (SSE) to stream deployment progress.
success
boolean
Whether the deployment succeeded
started
boolean
Whether the stack was started (always true if start was true)
output
string
Docker Compose output from the deployment
error
string
Error message if deployment failed

Behavior

  • If start=false, only creates the compose and env files without running docker compose up
  • Secrets (variables with isSecret=true) are stored in the database and injected at runtime
  • Non-secret variables are written to the .env file
  • The stack is marked as internal source type in the database
  • Deployment uses SSE to keep the connection alive during long operations
curl -X POST "https://your-dockhand-instance.com/api/stacks?env=1" \
  -H "Content-Type: application/json" \
  -H "Cookie: auth_token=your_token" \
  -d '{
    "name": "my-app",
    "compose": "version: '\''3.8'\''\nservices:\n  web:\n    image: nginx:latest\n    ports:\n      - \"8080:80\"\n    environment:\n      - APP_ENV=${APP_ENV}",
    "start": true,
    "envVars": [
      {
        "key": "APP_ENV",
        "value": "production",
        "isSecret": false
      },
      {
        "key": "API_KEY",
        "value": "secret_key_here",
        "isSecret": true
      }
    ]
  }'
{
  "success": true,
  "started": true,
  "output": "[+] Running 2/2\n ✔ Network my-app_default  Created\n ✔ Container my-app-web-1  Started"
}

Compose File Example

compose.yaml
version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    environment:
      - NGINX_HOST=${DOMAIN}
      - NGINX_PORT=80
    volumes:
      - ./html:/usr/share/nginx/html:ro
    restart: unless-stopped

  app:
    image: node:18-alpine
    working_dir: /app
    volumes:
      - ./app:/app
    environment:
      - NODE_ENV=production
      - DATABASE_URL=${DATABASE_URL}
      - API_KEY=${API_KEY}
    command: npm start
    depends_on:
      - db

  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=${DB_NAME}
    volumes:
      - db-data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  db-data:

networks:
  default:
    name: my-app-network

Error Responses

400 Bad Request

  • Stack name is missing or invalid
  • Compose file content is missing or invalid
  • Invalid YAML syntax

403 Forbidden

  • User lacks stacks:create permission
  • User cannot access the specified environment

500 Internal Server Error

  • Docker daemon error
  • File system error
  • Database error

Permissions

Requires stacks:create permission for the specified environment.

Build docs developers (and LLMs) love