Version: 1.1 Status: Planning Phase
Deploy one container. Get a complete production infrastructure.
Stack App transforms your Docker host into a production-ready platform with automatic reverse proxy, SSL certificates, and intelligent routing. Deploy complex multi-service applications, route to external APIs, and manage everything through a single REST APIβall from one container.
Stack App is CloudFront + API Gateway + Lambda for your own infrastructure, packaged as a single container.
Think of it as your local AWS edge infrastructure - route domains to multiple origins (containers, external APIs, S3, Lambda functions) with automatic SSL, all managed via REST API.
The Problem It Solves: Setting up production Docker infrastructure typically requires manually configuring Traefik/Nginx, managing SSL certificates, writing docker-compose files, and maintaining routing rules. AWS makes this easy with CloudFront + API Gateway + Lambda, but you're locked into AWS.
The Stack App Solution: Get AWS-like routing and orchestration on your own infrastructure:
- Origin Mapping (like CloudFront) - Route domains to multiple backends (containers, URLs, S3)
- Path-based Routing (like API Gateway) -
/api
β Lambda,/auth
β external SaaS,/
β frontend - Lambda Runtime - Run AWS Lambda container images as persistent services
- SSL/TLS Automation - Let's Encrypt certificates with auto-renewal
- Multi-Environment Portability - Same Lambda images run in AWS Lambda AND Stack App
- Infrastructure as Code - Entire routing configuration via JSON API
Real-World Example (CloudFront-style Origin Mapping):
example.com β Docker container (like CF Origin: ALB)
example.com/api β Lambda container (like CF Origin: API Gateway)
example.com/auth β External auth SaaS (like CF Origin: Custom HTTP)
example.com/media β S3 bucket (like CF Origin: S3)
All configured through a single JSON API call. SSL certificates automatically provisioned. No AWS required.
Deploy Stack App, and it automatically creates and manages the Traefik reverse proxy. No manual Traefik setup required.
- Create stacks with multiple services
- Start, stop, restart entire stacks or individual services
- Update service configurations on the fly
- Monitor real-time container status
- Access centralized logs
- Container Origins: Route to Docker containers (like CF β ALB)
- External Origins: Route to any HTTP/HTTPS endpoint (like CF β Custom Origin)
- Lambda Origins: Run Lambda container images (like CF β API Gateway β Lambda)
- S3 Origins: Route to S3 buckets or any static hosting
- Path Patterns: Priority-based routing (e.g.,
/api
before/
) - Domain Mapping: Multiple domains and subdomains
- SSL/TLS: Automatic Let's Encrypt certificates with auto-renewal
- API key authentication for all endpoints
- SSL/TLS encryption via Let's Encrypt
- ForwardAuth integration for Traefik dashboard
- Configurable middleware support
- Stack App API:
http://your-server/stack/api/v1/*
- Traefik Dashboard:
http://your-server/traefik/dashboard/
graph TB
subgraph Internet
Client[External Traffic<br/>Ports 80/443]
end
subgraph Host["Docker Host"]
subgraph Traefik["Traefik Container (auto-deployed)"]
TraefikProxy[Traefik Reverse Proxy]
Routes["Routes:<br/>β’ /stack/* β Stack App<br/>β’ /traefik/* β Dashboard<br/>β’ Custom service routes<br/>β’ External routes"]
end
subgraph StackApp["Stack App Container (You Deploy This)"]
API[REST API]
DB[(SQLite DB)]
Manager["Manager:<br/>β’ Traefik<br/>β’ Stacks<br/>β’ Routes<br/>β’ SSL"]
end
subgraph ManagedContainers["Managed Containers"]
Frontend[web-app-frontend<br/>with Traefik labels]
Backend[web-app-backend<br/>with Traefik labels]
Database[db-postgres<br/>with Traefik labels]
end
subgraph ExternalTargets["External Targets"]
LocalHost[localhost:8080]
LAN[192.168.1.50:3000]
External[api.external.com]
end
end
Client --> TraefikProxy
TraefikProxy --> API
TraefikProxy --> Routes
Routes --> Frontend
Routes --> Backend
Routes --> Database
Routes --> LocalHost
Routes --> LAN
Routes --> External
StackApp --> Traefik
Manager --> ManagedContainers
Manager --> Traefik
style Client fill:#e1f5ff
style Traefik fill:#fff4e6
style StackApp fill:#e8f5e9
style ManagedContainers fill:#f3e5f5
style ExternalTargets fill:#fce4ec
Stack App provides AWS-like routing and orchestration on your own infrastructure:
AWS Service | Stack App Equivalent | Capability |
---|---|---|
CloudFront Distribution | Stack with routes | Domain β multiple origins mapping |
CloudFront Origins | serviceId or externalTarget |
Route to containers, APIs, S3, etc. |
CloudFront Path Patterns | Route pathPrefix + priority |
/api/* , /auth/* routing |
API Gateway | Traefik path-based routing | HTTP routing, SSL termination |
Lambda Functions | Lambda container images | Run same Lambda images locally |
AWS Certificate Manager | Let's Encrypt automation | Free SSL certificates |
Lambda Function URLs | Route externalTarget |
Proxy to actual Lambda functions |
Key Difference: Stack App runs on your infrastructure - no AWS lock-in, no per-request pricing, full control.
Key Similarity: Using AWS Lambda Web Adapter, the same container image runs in both AWS Lambda (serverless) and Stack App (persistent containers) with zero code changes.
AWS Setup:
CloudFront Distribution (example.com)
ββ Origin: ALB β EC2 instances (/)
ββ Origin: API Gateway β Lambda (/api)
ββ Origin: S3 bucket (/media)
ββ Origin: auth.external.com (/auth)
Stack App Equivalent:
{
"id": "example-com",
"services": [{"id": "frontend", "image": "nginx"}],
"routes": [
{"serviceId": "frontend", "domains": ["example.com"], "port": 80},
{"externalTarget": "https://lambda-url.on.aws", "pathPrefix": "/api"},
{"externalTarget": "https://bucket.s3.amazonaws.com", "pathPrefix": "/media"},
{"externalTarget": "https://auth.external.com", "pathPrefix": "/auth"}
]
}
Same architecture, your infrastructure, one API call.
- Linux-based operating system
- Docker or Docker-compatible container runtime (Docker Engine, Podman)
- Ports 80 and 443 available on the host
- Domain name(s) pointing to your server (for SSL/TLS)
npm install -g @stack-app/docker-stack-api
stack-app --config /path/to/config.yaml
# Create required directories
mkdir -p stack-app/{config,data}
# Create configuration file
cat > stack-app/config/config.yaml <<EOF
database:
type: sqlite
path: /var/lib/stack-app/stacks.db
api:
port: 3001
keys:
- "your-api-key-here"
docker:
socketPath: /var/run/docker.sock
network: traefik-proxy
proxy:
enabled: true
provider: traefik
traefikImage: traefik:v3.0
httpPort: 80
httpsPort: 443
ssl:
enabled: true
provider: letsencrypt
email: admin@example.com
staging: false
challengeType: http
systemRoutes:
stackApi:
enabled: true
pathPrefix: /stack
stripPrefix: true
traefik:
enabled: true
pathPrefix: /traefik
stripPrefix: true
requireAuth: true
logging:
level: info
path: /var/log/stack-app
EOF
# Run Stack App container
docker run -d \
--name stack-app \
--restart unless-stopped \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v $(pwd)/stack-app/config:/etc/stack-app:ro \
-v $(pwd)/stack-app/data:/var/lib/stack-app:rw \
--network traefik-proxy \
stack-app/docker-stack-api:latest
Stack App will automatically:
- Create the
traefik-proxy
Docker network - Deploy and configure the Traefik container
- Expose itself at
http://your-server/stack/*
- Expose Traefik dashboard at
http://your-server/traefik/*
Stack App works with any Docker API-compatible container runtime:
- β Docker Engine (recommended)
- β Podman (Docker API compatibility mode)
- β Docker CE/EE
- β Moby
# Update system
sudo apt update && sudo apt upgrade -y
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add current user to docker group (optional)
sudo usermod -aG docker $USER
newgrp docker
# Verify Docker installation
docker --version
docker ps
# Create Stack App directory structure
mkdir -p ~/stack-app/{config,data}
cd ~/stack-app
# Create config.yaml (see Quick Start above)
# Deploy Stack App
docker run -d \
--name stack-app \
--restart unless-stopped \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v ~/stack-app/config:/etc/stack-app:ro \
-v ~/stack-app/data:/var/lib/stack-app:rw \
--network bridge \
stack-app/docker-stack-api:latest
# Verify Stack App is running
docker logs stack-app
# Verify Traefik was auto-created
docker ps | grep traefik
Podman provides Docker API compatibility via a socket:
# Install Podman (Ubuntu/Debian)
sudo apt update
sudo apt install -y podman
# Or on RHEL/CentOS/Fedora
sudo dnf install -y podman
# Enable Podman socket (Docker API compatibility)
systemctl --user enable --now podman.socket
# Verify Podman socket
systemctl --user status podman.socket
# Get socket path
export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock
# Create Stack App directory
mkdir -p ~/stack-app/{config,data}
cd ~/stack-app
# Create config.yaml with Podman socket path
cat > config/config.yaml <<EOF
database:
type: sqlite
path: /var/lib/stack-app/stacks.db
api:
port: 3001
keys:
- "your-api-key-here"
docker:
socketPath: /run/user/$(id -u)/podman/podman.sock
network: traefik-proxy
proxy:
enabled: true
provider: traefik
traefikImage: traefik:v3.0
httpPort: 80
httpsPort: 443
ssl:
enabled: true
provider: letsencrypt
email: admin@example.com
systemRoutes:
stackApi:
enabled: true
pathPrefix: /stack
traefik:
enabled: true
pathPrefix: /traefik
logging:
level: info
EOF
# Run with Podman
podman run -d \
--name stack-app \
--restart unless-stopped \
-v /run/user/$(id -u)/podman/podman.sock:/var/run/docker.sock:ro \
-v ~/stack-app/config:/etc/stack-app:ro \
-v ~/stack-app/data:/var/lib/stack-app:rw \
stack-app/docker-stack-api:latest
# Verify
podman ps
Before deploying, ensure required ports are available:
# Check if ports 80 and 443 are free
sudo netstat -tulpn | grep -E ':80|:443'
# Or with ss
sudo ss -tulpn | grep -E ':80|:443'
# If ports are occupied, stop the conflicting service
# Example for nginx:
sudo systemctl stop nginx
sudo systemctl disable nginx
# UFW (Ubuntu/Debian)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload
# firewalld (RHEL/CentOS)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
# iptables
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables-save
π Comprehensive Examples: See Requirements Examples for detailed real-world configurations:
- Full Stack Application - Complete web app with mixed container and external routing
- Lambda Containers - Running AWS Lambda container images
- Internal Services - Private network deployment with DNS-01 SSL
Quick Reference:
# Create a stack with services and routes
curl -X POST http://your-server/stack/api/v1/stacks \
-H "X-API-Key: your-api-key-here" \
-H "Content-Type: application/json" \
-d '{
"id": "web-app",
"services": [{
"id": "frontend",
"image": "nginx:latest",
"containerConfig": {
"ports": [{"name": "http", "containerPort": 80}]
}
}],
"routes": [{
"name": "main",
"serviceId": "frontend",
"domains": ["example.com"],
"port": 80,
"ssl": {"enabled": true, "provider": "letsencrypt"},
"priority": 100
}]
}'
# Start the stack
curl -X POST http://your-server/stack/api/v1/stacks/web-app/start \
-H "X-API-Key: your-api-key-here"
# Check status
curl http://your-server/stack/api/v1/stacks/web-app/status \
-H "X-API-Key: your-api-key-here"
Stack App provides a comprehensive REST API for managing stacks, services, and routes.
Key Endpoint Categories:
- Stack Management - Create, read, update, delete stacks
- Stack Lifecycle - Start, stop, restart operations
- Service Management - View service details and logs
- Proxy Management - Manage routes and SSL certificates
- Health & Monitoring - Health checks and status
π Complete API Reference: See API Specification for detailed endpoint documentation with request/response formats and examples.
Quick Examples:
# List all stacks
GET /api/v1/stacks
# Create a stack
POST /api/v1/stacks
# Start a stack
POST /api/v1/stacks/{stackId}/start
# Get stack status
GET /api/v1/stacks/{stackId}/status
# View SSL certificates
GET /api/v1/proxy/certificates
Stack App uses YAML configuration files for application settings, database configuration, and proxy defaults.
Configuration File Locations (priority order):
- CLI parameter:
--config /path/to/config.yaml
- Environment:
STACK_APP_CONFIG=/path/to/config.yaml
/etc/stack-app/config.yaml
/etc/stack-app/config.json
π Complete Configuration Schema: See Requirements - Deployment Configuration for the full configuration reference.
Minimal Example:
api:
port: 3001
keys:
- "your-api-key-here"
proxy:
enabled: true
ssl:
email: admin@example.com
Quick Start: See the Quick Start section above for a complete configuration example.
Stack App automatically configures two system routes:
- Default Path:
http://{any-host}/stack/*
- Purpose: Access Stack App REST API through Traefik
- Example:
http://your-server/stack/api/v1/stacks
- Authentication: X-API-Key header required
- Default Path:
http://{any-host}/traefik/*
- Purpose: Access Traefik dashboard and API
- Example:
http://your-server/traefik/dashboard/
- Authentication: X-API-Key header required (same as Stack App)
Both routes can be customized or disabled in configuration.
# Access Stack App API via system route (works on any configured domain)
curl https://example.com/stack/api/v1/stacks \
-H "X-API-Key: your-api-key-here"
# Create a stack via system route
curl -X POST https://example.com/stack/api/v1/stacks \
-H "X-API-Key: your-api-key-here" \
-H "Content-Type: application/json" \
-d '{"id": "my-app", "services": [...], "routes": [...]}'
# Access Traefik dashboard
# Open in browser: https://example.com/traefik/dashboard/
# Direct API access (bypasses Traefik)
curl http://your-server:3001/api/v1/stacks \
-H "X-API-Key: your-api-key-here"
Note: System routes work on ANY domain pointing to Traefik, making API access convenient without exposing port 3001 directly.
Stack App supports three types of routes:
When you create a service with proxy.enabled: true
, Stack App automatically:
- Generates Traefik Docker labels
- Configures domain and path routing
- Provisions SSL certificates via Let's Encrypt
- Sets up health checks
Example:
{
"proxy": {
"enabled": true,
"domains": ["app.example.com"],
"port": 80,
"ssl": true
}
}
Route traffic to non-Docker targets:
- Services running on host ports (
http://localhost:8080
) - LAN servers (
http://192.168.1.50:3000
) - External APIs (
https://api.external.com
)
Example:
{
"name": "internal-tool",
"domains": ["tools.example.com"],
"target": "http://192.168.1.100:9000",
"ssl": true
}
Built-in routes for Stack App and Traefik management interfaces.
Stack App automatically manages SSL certificates via Let's Encrypt:
- β Automatic certificate provisioning
- β Automatic renewal (90-day expiry)
- β HTTP-01, TLS-ALPN-01, and DNS-01 challenge support
- β Wildcard certificates (with DNS-01 challenge)
- β Custom certificate support
- β Certificate status monitoring
π SSL Configuration Details: See Data Models - SSL Configuration for complete schema and options.
Quick Examples:
# Let's Encrypt (HTTP-01)
ssl:
enabled: true
provider: letsencrypt
email: admin@example.com
challengeType: http
# DNS-01 for internal domains or wildcards
ssl:
enabled: true
provider: letsencrypt
challengeType: dns
dnsProvider: cloudflare
# Custom certificate
ssl:
enabled: true
provider: custom
customCert:
certFile: /path/to/cert.pem
keyFile: /path/to/key.pem
Stack App uses SQLite for persistent storage of all stack, service, and route configurations.
Database Location: /var/lib/stack-app/stacks.db
π Database Schema: See Database Schema for complete table definitions, indexes, and relationships.
What's Stored:
- Stack definitions and metadata
- Service configurations (container config as JSON)
- Route configurations (service routes + external routes)
- SSL certificate metadata
Backup Example:
# Stop Stack App
docker stop stack-app
# Backup database
cp ~/stack-app/data/stacks.db ~/stack-app-backup-$(date +%Y%m%d).db
# Start Stack App
docker start stack-app
# Find what's using the ports
sudo netstat -tulpn | grep -E ':80|:443'
# Stop conflicting service (e.g., nginx, apache)
sudo systemctl stop nginx
sudo systemctl disable nginx
# Check Stack App logs
docker logs stack-app
# Verify Traefik was created
docker ps -a | grep traefik
# Check Traefik logs
docker logs stack-app-traefik
- Ensure ports 80 and 443 are accessible from the internet
- Verify domain DNS points to your server IP
- Check Let's Encrypt rate limits (use
staging: true
for testing) - Review Traefik logs:
docker logs stack-app-traefik
# Test API key
curl -I http://your-server/stack/health # Should return 200 (no auth)
curl -I http://your-server/stack/api/v1/stacks \
-H "X-API-Key: your-key" # Should return 200 or 401
# Ensure socket is running
systemctl --user status podman.socket
# Restart socket
systemctl --user restart podman.socket
# Check socket path
ls -la /run/user/$UID/podman/podman.sock
- Use strong, randomly generated API keys (minimum 32 characters)
- Rotate keys regularly
- Store keys securely (environment variables, secrets management)
- Never commit keys to version control
Generate secure key:
openssl rand -hex 32
- Use firewall rules to restrict access
- Enable SSL/TLS for all production routes
- Consider VPN for Stack App API access
- Use Traefik middleware for rate limiting and security headers
- Run Stack App as non-root user (when available)
- Use read-only Docker socket when possible
- Regularly update base images
- Monitor container logs for suspicious activity
Minimum:
- 1 CPU core
- 512 MB RAM
- 1 GB disk space
Recommended:
- 2 CPU cores
- 2 GB RAM
- 10 GB disk space (for logs, certificates)
- Stack App supports 100+ concurrent stacks
- SQLite suitable for single-server deployments
- For multi-server setups, consider database migration (future enhancement)
- Traefik scales horizontally with load balancer
- NPM package distribution
- OpenAPI specification
- Web UI for stack management
- Multi-server support
- Kubernetes integration
- PostgreSQL/MySQL database option
- Metrics and monitoring integration (Prometheus)
- Webhook notifications
- Backup and restore functionality
- Import/export stack definitions
Complete technical specifications organized for easy navigation:
- Requirements Overview - Main Software Requirements Specification (SRS)
- API Specification - Complete REST API reference
- Data Models - JSON schemas for all objects
- Database Schema - SQLite tables and relationships
- Validation Rules - Input validation patterns
- Examples - Real-world configuration examples
- CLAUDE.md - Development guidelines for Claude Code
[License Type - TBD]
For issues, questions, and contributions:
- GitHub Issues: [Repository URL - TBD]
- Documentation: [Docs URL - TBD]
Built with β€οΈ for Docker infrastructure management