What You'll Build
In this tutorial, you'll deploy three real open-source projects using Stacker — no Docker expertise needed. By the end, you'll have:
- A self-hosted analytics dashboard (Umami)
- A privacy-focused web archiver (ArchiveBox)
- An AWS-compatible local cloud emulator (Floci)
Each deployment takes two commands. Total time: under 5 minutes.
Quick Answer
stacker init --from-github owner/repo --with-ai --force
stacker deploy --target local
That's it. Stacker handles project detection, Docker configuration, service setup, healthchecks, env vars, and secrets generation.
Prerequisites
- Docker installed (
docker --version) - Git installed (
git --version) - Optional: Ollama running locally for AI-assisted config (
ollama serve)
Step 1: Install Stacker
curl -fsSL https://raw.githubusercontent.com/trydirect/stacker/main/install.sh | bash
stacker --version
# Should print: stacker 0.3.0
Step 2: Deploy Umami Analytics
Umami is a privacy-first, open-source alternative to Google Analytics. It uses PostgreSQL for data storage and runs on Node.js.
2.1 Generate the configuration
mkdir ~/umami && cd ~/umami
stacker init --from-github umami-software/umami --with-ai --force
Stacker clones the repo, reads the docker-compose.yml, detects a Node.js app with a PostgreSQL dependency, and generates:
# What you'll see in your directory:
stacker.yml # The deployment config
.stacker/Dockerfile # Optimized Node.js Dockerfile
.stacker/docker-compose.yml # Production compose file
.env.example # Template with detected env vars
scripts/generate-secrets.sh # Auto-generate DB passwords
2.2 Generate secrets and deploy
cp .env.example .env
./scripts/generate-secrets.sh # Fills in DB_PASSWORD, etc.
stacker config validate # ✓ Configuration is valid
stacker deploy --target local # Builds and starts containers
2.3 Verify
stacker status
# Should show: umami (running), postgres (running)
# Open in browser
open http://localhost:3000
Step 3: Deploy ArchiveBox
ArchiveBox is a self-hosted web archiving solution. Python-based, with a more complex setup involving multiple volumes and environment variables.
mkdir ~/archivebox && cd ~/archivebox
stacker init --from-github ArchiveBox/ArchiveBox --with-ai --force
# Review the generated stacker.yml
cat stacker.yml
# Generate secrets and deploy
cp .env.example .env
./scripts/generate-secrets.sh
stacker deploy --target local
Notice how Stacker handled ArchiveBox's complexity: multiple volumes for data persistence, the correct entrypoint command, and all the environment variables pulled from the project's documentation.
Step 4: Deploy Floci (AWS Local Emulator)
Floci emulates AWS services locally. It's a complex Go project with Docker-in-Docker, multiple port ranges, and volume mounts for the Docker socket.
mkdir ~/floci && cd ~/floci
stacker init --from-github floci-io/floci --with-ai --force
Stacker handles the complexity automatically:
- Detects the Dockerfile at the project root
- Reads the docker-compose.yml to find port mappings (4566, plus the port ranges)
- Extracts all 7 FLOCI_* environment variables from the compose file
- Identifies the Docker socket volume mount (
/var/run/docker.sock) - Generates a clean stacker.yml with the app as
app.image: floci/floci:latest
Step 5: Understanding the Generated Config
Let's look at what Stacker produced for Umami. The stacker.yml will look something like:
name: umami
deploy:
target: local
app:
type: node
path: .
ports:
- "3000:3000"
environment:
DATABASE_URL: "postgresql://umami:${DB_PASSWORD}@postgres:5432/umami"
HASH_SALT: "${HASH_SALT}"
services:
- name: postgres
image: postgres:16-alpine
ports:
- "127.0.0.1:5432:5432"
environment:
POSTGRES_DB: umami
POSTGRES_USER: umami
POSTGRES_PASSWORD: "${DB_PASSWORD}"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: "CMD-SHELL pg_isready -U umami -d umami"
interval: 5s
timeout: 2s
retries: 10
volumes:
postgres_data: {}
proxy:
type: none
auto_detect: false
Key things Stacker got right without any manual input:
- Correct app type: Node.js detected from
package.json - Database service: PostgreSQL extracted from docker-compose.yml
- Healthcheck:
pg_isreadyautomatically added - Port isolation: PostgreSQL bound to
127.0.0.1— not exposed externally - Volume persistence: Named volume for database data
- Secret handling: All passwords use
${VAR_NAME}syntax, never hardcoded
Step 6: Customizing the Configuration
Edit stacker.yml to customize your deployment:
# Add a reverse proxy with SSL
proxy:
type: nginx
auto_detect: true
domains:
- domain: umami.yourdomain.com
ssl: auto
upstream: app:3000
# Enable monitoring
monitoring:
status_panel: true
healthcheck:
endpoint: /api/health
interval: 30s
# Add AI troubleshooting for failed deployments
ai:
enabled: true
provider: ollama
After editing, redeploy:
stacker config validate
stacker deploy --target local
Step 7: Deploying to Production
Once your stack works locally, deploy it to your own server:
# Option A: Your own server
stacker config setup server
# Enter: host IP, SSH user, SSH key path
stacker deploy --target server
# Option B: Cloud provider (Hetzner, DO, AWS, etc.)
stacker config setup cloud
# Interactive wizard: choose provider, region, instance size
stacker deploy --target cloud
Stacker provisions the server, installs Docker, deploys your stack, configures the reverse proxy with SSL, and installs the Status Panel agent for ongoing monitoring — all from the CLI.
What to Do When Things Go Wrong
AI generation fails
# Stacker falls back to template-based detection automatically.
# Or try a different AI provider:
stacker init --from-github owner/repo --with-ai \
--ai-provider openai --ai-api-key sk-... --force
Deployment fails
# Check logs
stacker logs
# With AI troubleshooting enabled in stacker.yml:
stacker ai ask "why is my postgres container crashing?" --context ./stacker.yml
Port conflict
# Edit stacker.yml to change the host port:
app:
ports:
- "3001:3000" # Changed host port from 3000 to 3001
# Redeploy
stacker deploy --target local
Need to regenerate
# Use --force to overwrite existing files
stacker init --from-github owner/repo --with-ai --force
Beyond the Tutorial
Stacker does much more than deploy from GitHub:
- Visual Stack Builder: Drag-and-drop interface for composing multi-service stacks at try.direct
- 56+ pre-built stacks: One-click deploy for n8n, Supabase, Ghost, Grafana, Open WebUI, and more
- Pipes: Container-to-container data flows (like self-hosted Zapier)
- CI/CD integration:
stacker ci export --platform githubgenerates GitHub Actions workflows - Vault secrets: Remote secret storage and injection for production deployments
Key Takeaways
- Any GitHub repo with a docker-compose.yml can be deployed in two commands
--with-aidramatically improves config quality by reading README, compose, and source- Healthchecks, port isolation, and secret handling are automatic
- The same
stacker.ymlworks identically on local, server, and cloud targets - You own the infrastructure — Stacker just manages the deployment
- Everything is open source (MIT) on GitHub