Stacker - is an application that helps users to create custom IT solutions based on dockerized open source apps and user's custom applications docker containers. Users can build their own project of applications, and deploy the final result to their favorite clouds using TryDirect API. See CHANGELOG.md for the latest platform updates.
When you start the Stacker server, you'll see a welcome banner displaying version and configuration info:
██████ ████████ █████ ██████ ██ ██ ███████ ██████
██ ██ ██ ██ ██ ██ ██ ██ ██ ██
███████ ██ ███████ ██ █████ █████ ██████
██ ██ ██ ██ ██ ██ ██ ██ ██ ██
██████ ██ ██ ██ █████ ██ ██ ███████ ██ ██
╭────────────────────────────────────────────────────────╮
│ Stacker │
│ Version: 0.2.1t │
│ Build: 0.2.0 │
│ Edition: 2021 │
╰────────────────────────────────────────────────────────╯
📋 Configuration Loaded
🌐 Server Address: http://127.0.0.1:8000
📦 Ready to accept connections
- Allows users to build projects using both open source and custom Docker containers
- Provides deployment capabilities to various cloud platforms through TryDirect API
- Helps manage and orchestrate Docker-based application stacks
- Project Structure
- Web UI (Stack Builder)
- Command Line Interface
- RESTful API Backend
- Key Features
- User Authentication (via TryDirect OAuth)
- API Client Management
- Cloud Provider Key Management
- Docker Compose Generation
- Project Rating System
- Project Deployment Management
- Technical Architecture
- Written in Rust
- Uses PostgreSQL database
- Implements REST API endpoints
- Includes Docker image validation
- Supports project deployment workflows
- Has RabbitMQ integration for deployment status updates
- Data Models The core Project model includes:
- Unique identifiers (id, stack_id)
- User identification
- Project metadata (name, metadata, request_json)
- Timestamps (created_at, updated_at)
- API Endpoints (user-facing)
/project- Project management/project/deploy- Deployment handling/project/deploy/status- Deployment status tracking/rating- Rating system/client- API client management
- Agent + Command Flow (self-hosted runner)
- Register agent (no auth required):
POST /api/v1/agent/register- Body:
deployment_hash, optionalcapabilities,system_info - Response:
agent_id,agent_token
- Body:
- Agent long-poll for commands:
GET /api/v1/agent/commands/wait/:deployment_hash- Headers:
X-Agent-Id: <agent_id>,Authorization: Bearer <agent_token> - Optional query params:
timeout(seconds),interval(seconds)
- Headers:
- Agent report command result:
POST /api/v1/agent/commands/report- Headers:
X-Agent-Id,Authorization: Bearer <agent_token> - Body:
command_id,deployment_hash,status(completed|failed),result/error, optionalstarted_at, requiredcompleted_at
- Headers:
- Create command (user auth via OAuth Bearer):
POST /api/v1/commands- Body:
deployment_hash,command_type,priority(low|normal|high|critical),parameters, optionaltimeout_seconds
- Body:
- List commands for a deployment:
GET /api/v1/commands/:deployment_hash
- Stacker → Agent HMAC-signed POSTs (v2)
- All POST calls from Stacker to the agent must be signed per STACKER_INTEGRATION_REQUIREMENTS.md
- Required headers:
X-Agent-Id,X-Timestamp,X-Request-Id,X-Agent-Signature - Signature: base64(HMAC_SHA256(AGENT_TOKEN, raw_body_bytes))
- Helper available:
helpers::AgentClient - Base URL: set
AGENT_BASE_URLto point Stacker at the target agent (e.g.,http://agent:5000).
Example:
use stacker::helpers::AgentClient;
use serde_json::json;
let client = AgentClient::new("http://agent:5000", agent_id, agent_token);
let payload = json!({"deployment_hash": dh, "type": "restart_service", "parameters": {"service": "web"}});
let resp = client.get("/api/v1/status").await?;Stacker uses a pull-only architecture for agent communication. Stacker never dials out to agents. Commands are enqueued in the database; agents poll and sign their own requests.
Flow:
- UI/API calls
POST /api/v1/commandsorPOST /api/v1/agent/commands/enqueue - Command is inserted into
commands+command_queuetables - Agent polls
GET /api/v1/agent/commands/wait/{deployment_hash}with HMAC headers - Stacker verifies agent's HMAC, returns queued commands
- Agent executes locally and calls
POST /api/v1/agent/commands/report
Note: AGENT_BASE_URL environment variable is NOT required for Status Panel commands.
Token rotation (writes to Vault; agent pulls latest):
use stacker::services::agent_dispatcher;
// Rotate token - stored in Vault, agent fetches on next poll
agent_dispatcher::rotate_token(&pg, &vault, &deployment_hash, "NEW_TOKEN").await?;Console token rotation:
cargo run --bin console -- Agent rotate-token \
--deployment-hash <hash> \
--new-token <NEW_TOKEN>- In configuration.yaml.dist, set:
- vault.address: Vault URL (e.g., http://127.0.0.1:8200)
- vault.token: Vault access token (dev/test only)
- vault.agent_path_prefix: KV mount/prefix for agent tokens (e.g., agent or kv/agent)
- Environment variable overrides (optional): VAULT_ADDRESS, VAULT_TOKEN, VAULT_AGENT_PATH_PREFIX
- Agent tokens are stored at: {vault.agent_path_prefix}/{deployment_hash}/token
agent_command_poll_timeout_secs(default 30)agent_command_poll_interval_secs(default 3)casbin_reload_enabled(default true)casbin_reload_interval_secs(default 10)
Environment overrides:
STACKER_AGENT_POLL_TIMEOUT_SECSSTACKER_AGENT_POLL_INTERVAL_SECSSTACKER_CASBIN_RELOAD_ENABLEDSTACKER_CASBIN_RELOAD_INTERVAL_SECS
The project appears to be a sophisticated orchestration platform that bridges the gap between Docker container management and cloud deployment, with a focus on user-friendly application stack building and management.
This is a high-level overview based on the code snippets provided. The project seems to be actively developed with features being added progressively, as indicated by the TODO sections in the documentation.
Authentication through TryDirect OAuth /api/auth checks client's creds, api token, api secret /apiclient (Create/Manage user's api clients) example: BeerMaster (email, callback) /rating
Authentication made through TryDirect OAuth, here we have only client Database (Read only) Logging/Tracing (Files) / Quickwit for future /project (WebUI, as a result we have a JSON) /project/deploy -> sends deploy command to TryDirect Install service /project/deploy/status - get installation progress (rabbitmq client),
Find out how to get user's token for queue Limit Requests Frequency (Related to user's settings/role/group etc) Callback event, example: subscribe on get_report (internally from rabbitmq client),
main client (AllMasters) -> client (Beermaster)
sqlx migrate run
sqlx migrate revert
Stacker ships targeted tests for the new User Service marketplace integrations. Run them with:
cargo test user_service_client
cargo test marketplace_webhook
cargo test deployment_validator
Each suite uses WireMock-backed HTTP servers, so they run offline and cover the actual request/response flows for the connector, webhook sender, and deployment validator.
curl -X POST
curl -vX POST 'http://localhost:8000/rating' -d '{"obj_id": 1, "category": "application", "comment":"some comment", "rate": 10}' --header 'Content-Type: application/json'
curl -X POST -H "Content-Type: application/json" -d @tests/mock_data/custom-stack-payload.json http://127.0.0.1:8000/project -H "Authorization: Bearer $TD_BEARER"
curl -X POST http://localhost:8000/client --header 'Content-Type: application/json' -H "Authorization: Bearer $TD_BEARER"
test client deploy http://localhost:8000/test/deploy
Test casbin rule
cargo r --bin console --features=explain debug casbin --path /client --action POST --subject admin_petru
"cargo sqlx prepare" requires setting the DATABASE_URL environment variable to a valid database URL.
export DATABASE_URL=postgres://postgres:postgres@localhost:5432/stacker