Query Parameters
Environment ID where the stack will be deployed
Body Parameters
Stack name (must be unique within the environment)
Docker Compose file content (YAML)
Whether to start the stack immediately. If false, only creates the compose file without deploying.
Environment variables for the stackShow Environment Variable Object
Whether this is a secret (stored in database, not in .env file)
Raw .env file content (non-secrets with comments preserved)
Custom path for the compose file (for adopted stacks)
Custom path for the .env file (for adopted stacks)
Response
This endpoint uses Server-Sent Events (SSE) to stream deployment progress.
Whether the deployment succeeded
Whether the stack was started (always true if start was true)
Docker Compose output from the deployment
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
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.