From 949a0c4d52791b4c02847d57beae6baa9af95464 Mon Sep 17 00:00:00 2001 From: Vasili Pascal Date: Thu, 5 Nov 2026 15:38:41 +0200 Subject: [PATCH] feat(website): add blog section with AI startup hosting article - Add blog/index.html listing page and blog/ai-startup-hosting.html article - Article covers deploying AI-built apps on own server with Stacker - Cost comparison tables, step-by-step deploy guide, multi-service stacks - Add Blog link to main nav, blog/article styles to styles.css - Update build script to copy blog/ to dist/ - Replace em dashes with hyphens across all website files --- website/dist/blog/ai-startup-hosting.html | 356 ++++++++++++++++++++++ website/dist/blog/index.html | 87 ++++++ website/dist/index.html | 29 +- website/dist/main.js | 4 +- website/dist/styles.css | 304 +++++++++++++++++- website/package.json | 2 +- website/src/blog/ai-startup-hosting.html | 356 ++++++++++++++++++++++ website/src/blog/index.html | 87 ++++++ website/src/index.html | 29 +- website/src/main.ts | 4 +- website/src/styles.css | 304 +++++++++++++++++- 11 files changed, 1527 insertions(+), 35 deletions(-) create mode 100644 website/dist/blog/ai-startup-hosting.html create mode 100644 website/dist/blog/index.html create mode 100644 website/src/blog/ai-startup-hosting.html create mode 100644 website/src/blog/index.html diff --git a/website/dist/blog/ai-startup-hosting.html b/website/dist/blog/ai-startup-hosting.html new file mode 100644 index 00000000..05ebb633 --- /dev/null +++ b/website/dist/blog/ai-startup-hosting.html @@ -0,0 +1,356 @@ + + + + + + How to Deploy an AI-Built Startup Without Burning Cash on Hosting - Stacker Blog + + + + + + + + + + + + + + +
+
+
+
+ +

How to Deploy an AI-Built Startup Without Burning Cash on Hosting

+

+ AI tools let anyone build a working app in hours. But hosting costs can eat your runway before you get your first customer. Here's how to deploy on your own server for a fraction of the price. +

+
+ +
+

The AI Startup Boom

+

+ Something fundamental changed in 2025–2026. Tools like Cursor, v0, Bolt, Claude, and ChatGPT made it possible for anyone - not just engineers - to build a working product in a weekend. You describe what you want, the AI writes the code, and suddenly you have a SaaS, a marketplace, an internal tool, or a mobile backend that actually works. +

+

+ This is great news for founders. The cost of building software dropped to nearly zero. But the cost of running software didn't. +

+ +

The Hosting Cost Trap

+

+ Here's the problem most AI-built startups hit: the app works on your laptop, but to put it in front of real users you need a server. And the "easy" hosting options are expensive. +

+

+ Let's look at the typical monthly cost for a small startup running a web app, a database, Redis, and a few background workers: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PlatformMonthly CostWhat You Get
Vercel / Netlify$20–$250+Frontend only, no database
Railway / Render$50–$300+Full-stack, but usage-based pricing spikes fast
Heroku$100–$500+Easy but expensive at scale
AWS / GCP (managed)$100–$500+Powerful but complex, requires DevOps knowledge
Your own server + Stacker$5–$20Full control, everything included
+ +
+ The math is simple. A $5–$20/month VPS (Hetzner, DigitalOcean, Contabo) can run a production web app, PostgreSQL, Redis, a reverse proxy with SSL, and background workers. That's 10–50x cheaper than managed platforms. +
+ +

Why Stacker?

+

+ The problem with self-hosting has always been the operational overhead. You need to know Docker, networking, SSL certificates, reverse proxies, database backups, firewall rules… It's a full-time job. +

+

+ Stacker removes that overhead. It's a single CLI tool that takes your project - the one AI generated for you - and deploys it to your own server in a few commands. No YAML file hell, no Kubernetes, no manual nginx configuration. +

+ +

Step-by-Step: Deploy Your AI-Built App

+

+ Let's say you built a SaaS with Next.js (frontend), PostgreSQL (database), and Redis (caching) using Cursor or ChatGPT. Here's how to get it live on your own server. +

+ +

1. Get a Cheap Server

+

+ Rent a VPS from any provider. Hetzner is the best value in Europe (CX22: 2 vCPU, 4 GB RAM, 40 GB disk for ~€5/month). DigitalOcean and Vultr are good alternatives. You need roughly 2–4 GB of RAM for most small apps. +

+ +

2. Add a stacker.yml to Your Project

+

+ This is the only file you add. It tells Stacker what your app is, what services it needs, and where to deploy: +

+
# stacker.yml
+name: my-startup
+app:
+  type: node
+  ports:
+    - "3000:3000"
+  environment:
+    NODE_ENV: production
+
+services:
+  - name: postgres
+    image: postgres:16-alpine
+    environment:
+      POSTGRES_PASSWORD: ${DB_PASSWORD}
+    volumes:
+      - pgdata:/var/lib/postgresql/data
+    healthcheck:
+      test: pg_isready -U postgres
+
+  - name: redis
+    image: redis:7-alpine
+    command: redis-server --requirepass ${REDIS_PASSWORD}
+
+volumes:
+  pgdata: {}
+
+deploy:
+  target: server
+  server:
+    host: 123.45.67.89
+    user: root
+    ssh_key: ~/.ssh/id_ed25519
+
+proxy:
+  type: nginx
+  domains:
+    - domain: myapp.com
+      ssl: auto
+      upstream: app:3000
+ +

3. Deploy

+

+ One command: +

+
stacker deploy
+

+ That's it. Stacker will: +

+
    +
  • Detect your project type and generate a Dockerfile
  • +
  • Build a Docker Compose stack from your stacker.yml
  • +
  • Copy everything to your server over SSH
  • +
  • Start all containers (app, database, Redis)
  • +
  • Configure nginx with automatic SSL (Let's Encrypt)
  • +
  • Set up firewall rules to open only the ports you need
  • +
+

+ Your app is now live at myapp.com. +

+ +

What If You Need More Services?

+

+ Most real apps need more than just a web server and a database. Maybe you want analytics, a queue, file storage, or monitoring. Stacker handles multi-service stacks natively: +

+
services:
+  - name: postgres
+    image: postgres:16-alpine
+  - name: redis
+    image: redis:7-alpine
+  - name: rabbitmq
+    image: rabbitmq:3-management
+  - name: minio
+    image: minio/minio
+    command: server /data
+  - name: worker
+    image: myapp/worker:latest
+    command: python worker.py
+

+ All services run in isolated containers on the same Docker network. They can talk to each other by service name (postgres, redis, rabbitmq) - no IP addresses, no manual networking. +

+ +

The Cost Comparison: Real Numbers

+

+ Let's compare a realistic startup setup over 12 months: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SetupMonthlyYearly
Railway (web + DB + Redis + worker)~$150~$1,800
Vercel + PlanetScale + Upstash~$80~$960
Heroku (dyno + Postgres + Redis)~$250~$3,000
Hetzner VPS + Stacker~$8~$96
+ +
+ That's $800–$2,900 saved per year. For a bootstrapped startup, that's real runway - months of server costs covered by the savings alone. +
+ +

Common Concerns

+ +

"What about uptime?"

+

+ A Hetzner CX22 has a 99.9% uptime SLA. For most startups, that's better than you need. If you outgrow one server, Stacker supports multi-server deployments too. And you can always set up a simple status page to monitor your services. +

+ +

"What about backups?"

+

+ Stacker uses named Docker volumes for persistent data. You can back up your database with a simple cron job, or use stacker agent to manage remote operations. Don't rely on your hosting provider's backups as your only safety net - a 5-minute pg_dump cron job is enough for most startups. +

+ +

"What about security?"

+

+ Stacker handles SSL automatically (Let's Encrypt). It also configures firewall rules so only necessary ports are open. The stacker.yml format supports config_contract to declare which fields are secrets - Stacker generates strong values automatically and stores them securely. +

+ +

"I don't know Docker. Is this still for me?"

+

+ Yes. Stacker auto-detects your project type (Node, Python, Rust, Go, PHP, or static) and generates the Docker configuration for you. You never write a Dockerfile. The stacker.yml above is the entire configuration. +

+ +

What About AI-Generated Projects Specifically?

+

+ AI tools produce projects that follow standard conventions: package.json for Node, requirements.txt for Python, Cargo.toml for Rust. Stacker's auto-detection works perfectly with these. The same tools that generated your app in hours now deploy it in seconds. +

+

+ The workflow looks like this: +

+
    +
  1. Build with Cursor / v0 / Claude / ChatGPT (hours, not weeks)
  2. +
  3. Test locally on your laptop
  4. +
  5. Deploy with stacker deploy (seconds, not days)
  6. +
  7. Iterate - push changes with stacker deploy again
  8. +
+

+ Total infrastructure cost: under $10/month. Total time spent on operations: minutes. +

+ +

Getting Started

+

+ Ready to try it? Here's what you need: +

+
    +
  • A server - any VPS with 2+ GB RAM (~$5/month on Hetzner)
  • +
  • Stacker - install with one command: curl -fsSL https://get.stacker.my | sh
  • +
  • Your project - the one you already built with AI
  • +
+

+ Then add your stacker.yml, run stacker deploy, and you're live. +

+ +

The Bottom Line

+

+ AI lowered the cost of building software to near zero. Stacker lowers the cost of running it to near zero. Together, they let a solo founder or small team build and ship a real product for less than the price of a coffee subscription. +

+

+ The next time an AI tool gives you a working app in a weekend, don't pay $200/month to put it online. Get a $5 server, add a stacker.yml, and deploy. +

+ +
+

Ready to deploy?

+

Stacker is open source. Star it on GitHub and try it on your next project.

+ Get Stacker on GitHub +
+
+ + +
+
+
+ + + + + + diff --git a/website/dist/blog/index.html b/website/dist/blog/index.html new file mode 100644 index 00000000..d21d32d9 --- /dev/null +++ b/website/dist/blog/index.html @@ -0,0 +1,87 @@ + + + + + + Blog - Stacker + + + + + + + + + + + +
+
+
+

Blog

+

Guides, tutorials, and insights on deploying applications with Stacker.

+
+ +
+ +
+
+
+ + + + + + diff --git a/website/dist/index.html b/website/dist/index.html index b018e524..f173f5ca 100644 --- a/website/dist/index.html +++ b/website/dist/index.html @@ -3,8 +3,8 @@ - Stacker v0.3.5 — AI Infrastructure CLI by TryDirect - + Stacker v0.3.5 - AI Infrastructure CLI by TryDirect + @@ -39,6 +39,7 @@ Examples Commands Providers + Blog

SSH Key Management

-

Generate, view, and upload SSH keys for your servers — all stored securely in HashiCorp Vault. No manual key juggling.

+

Generate, view, and upload SSH keys for your servers - all stored securely in HashiCorp Vault. No manual key juggling.

@@ -213,7 +214,7 @@

SSH Key Management

-

Stacker v0.3.5
— config sync, per-install secrets & safer marketplace snapshots.

+

Stacker v0.3.5
- config sync, per-install secrets & safer marketplace snapshots.

Releases v0.3.3 through v0.3.5 bring stacker sync for pushing configuration without a deploy, field policies that generate fresh secrets for every marketplace install, secret-free baked snapshots with author-declared volume policies, and cloud deploys that stop with an error instead of a warning when SSH access can't be verified.

@@ -225,7 +226,7 @@

stacker sync

Marketplace

Field policies & generated secrets

-

Mark each field in config_contract as fixed, editable, or generated. Generated values — hex, alphanumeric, uuid, derived_jwt — are stripped at publish and created fresh on every install, so no two buyers share a secret.

+

Mark each field in config_contract as fixed, editable, or generated. Generated values - hex, alphanumeric, uuid, derived_jwt - are stripped at publish and created fresh on every install, so no two buyers share a secret.

Bake @@ -240,7 +241,7 @@

Verified SSH access

Monitoring

stacker monitor

-

A built-in container-down alarm. Declare a monitoring.alerts block and get notified — terminal, webhook (ntfy/Slack), or pipe — the moment a container stops and when it recovers. Edge-triggered and cron-friendly with --once.

+

A built-in container-down alarm. Declare a monitoring.alerts block and get notified - terminal, webhook (ntfy/Slack), or pipe - the moment a container stops and when it recovers. Edge-triggered and cron-friendly with --once.

Pipes @@ -250,12 +251,12 @@

Declarative pipes (IaC)

Pipes

Manual endpoints & retries

-

Create pipes non-interactively with --source-endpoint / --target-endpoint — works for any HTTP API. Attach a retry policy and --on-failure / --on-success handlers.

+

Create pipes non-interactively with --source-endpoint / --target-endpoint - works for any HTTP API. Attach a retry policy and --on-failure / --on-success handlers.

Proxy

Reverse-proxy routing

-

Working routing for Traefik (labels), Caddy (Caddyfile), and Nginx Proxy Manager (proxy hosts), all driven by proxy.domains — platform-managed, so no double-deploy or port collisions.

+

Working routing for Traefik (labels), Caddy (Caddyfile), and Nginx Proxy Manager (proxy hosts), all driven by proxy.domains - platform-managed, so no double-deploy or port collisions.

Config @@ -287,7 +288,7 @@

Remote secret tools

Your infrastructure,
understood by AI.

-

Stacker's AI engine doesn't just guess — it deeply analyzes your project to generate the perfect deployment configuration.

+

Stacker's AI engine doesn't just guess - it deeply analyzes your project to generate the perfect deployment configuration.

@@ -518,7 +519,7 @@

35 top-level commands.
stacker init --with-ai

-

Scan your project and generate stacker.yml — with optional AI assistance.

+

Scan your project and generate stacker.yml - with optional AI assistance.

@@ -531,7 +532,7 @@

35 top-level commands.
stacker sync --verify

-

Push project and app configuration to Stacker without deploying — no server contact, no containers started.

+

Push project and app configuration to Stacker without deploying - no server contact, no containers started.

@@ -583,7 +584,7 @@

35 top-level commands.
stacker service add <name>

-

Add services from 20+ built-in templates — Postgres, Redis, WordPress, and more. Auto-adds dependencies.

+

Add services from 20+ built-in templates - Postgres, Redis, WordPress, and more. Auto-adds dependencies.

diff --git a/website/dist/main.js b/website/dist/main.js index f136a6df..36e04e61 100644 --- a/website/dist/main.js +++ b/website/dist/main.js @@ -1,6 +1,6 @@ "use strict"; // ============================================================ -// Stacker Website — TypeScript Interactions +// Stacker Website - TypeScript Interactions // Particle system, typing effect, scroll animations, counters // ============================================================ class ParticleSystem { @@ -198,7 +198,7 @@ class ScrollAnimator { document.querySelectorAll('[data-animate]').forEach((el) => { const rect = el.getBoundingClientRect(); if (rect.top < vh) { - // Element is already in the viewport — show it immediately + // Element is already in the viewport - show it immediately const delay = parseInt(el.dataset.delay || '0', 10); setTimeout(() => el.classList.add('is-visible'), delay); } diff --git a/website/dist/styles.css b/website/dist/styles.css index 3d40b46a..e8ad5f6f 100644 --- a/website/dist/styles.css +++ b/website/dist/styles.css @@ -1,5 +1,5 @@ /* ============================================================ - Stacker Website — Styles + Stacker Website - Styles TryDirect brand colors + modern visual effects ============================================================ */ @@ -1584,3 +1584,305 @@ code { grid-template-columns: 1fr; } } + +/* ============================================================ + Blog + ============================================================ */ + +.blog-page { + padding: calc(80px + var(--space-4xl)) 0 var(--space-4xl); + min-height: 80vh; +} + +.blog-header { + text-align: center; + margin-bottom: var(--space-4xl); +} + +.blog-header__title { + font-size: clamp(2.5rem, 5vw, 4rem); + font-weight: 800; + margin-bottom: var(--space-md); + background: linear-gradient(135deg, var(--color-text) 0%, var(--color-accent-light) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.blog-header__subtitle { + font-size: 1.125rem; + color: var(--color-text-secondary); + max-width: 600px; + margin: 0 auto; +} + +.blog-grid { + display: grid; + gap: var(--space-xl); + max-width: 800px; + margin: 0 auto; +} + +.blog-card { + background: var(--color-bg-card); + border: 1px solid var(--color-border); + border-radius: var(--radius-lg); + padding: var(--space-xl); + transition: border-color 0.3s var(--ease-out), transform 0.3s var(--ease-out); +} + +.blog-card:hover { + border-color: var(--color-accent); + transform: translateY(-2px); +} + +.blog-card__meta { + display: flex; + align-items: center; + gap: var(--space-md); + margin-bottom: var(--space-md); +} + +.blog-card__tag { + background: rgba(126, 87, 194, 0.15); + color: var(--color-accent-light); + padding: var(--space-xs) var(--space-sm); + border-radius: var(--radius-sm); + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.blog-card__date { + color: var(--color-text-dim); + font-size: 0.875rem; +} + +.blog-card__title { + font-size: 1.5rem; + font-weight: 700; + line-height: 1.3; + margin-bottom: var(--space-md); +} + +.blog-card__title a { + color: var(--color-text); + text-decoration: none; + transition: color 0.2s; +} + +.blog-card__title a:hover { + color: var(--color-accent-light); +} + +.blog-card__excerpt { + color: var(--color-text-secondary); + line-height: 1.7; + margin-bottom: var(--space-lg); +} + +.blog-card__link { + color: var(--color-accent-light); + text-decoration: none; + font-weight: 600; + transition: color 0.2s; +} + +.blog-card__link:hover { + color: var(--color-accent); +} + +/* --- Article Page --- */ + +.article-page { + padding: calc(80px + var(--space-3xl)) 0 var(--space-4xl); +} + +.container--narrow { + max-width: 760px; + margin: 0 auto; +} + +.article__header { + margin-bottom: var(--space-3xl); +} + +.article__meta { + display: flex; + align-items: center; + gap: var(--space-md); + margin-bottom: var(--space-lg); + flex-wrap: wrap; +} + +.article__tag { + background: rgba(126, 87, 194, 0.15); + color: var(--color-accent-light); + padding: var(--space-xs) var(--space-sm); + border-radius: var(--radius-sm); + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.article__meta time, +.article__read-time { + color: var(--color-text-dim); + font-size: 0.875rem; +} + +.article__title { + font-size: clamp(2rem, 4vw, 3rem); + font-weight: 800; + line-height: 1.2; + margin-bottom: var(--space-lg); + background: linear-gradient(135deg, var(--color-text) 0%, var(--color-accent-light) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.article__lead { + font-size: 1.25rem; + color: var(--color-text-secondary); + line-height: 1.7; +} + +.article__content h2 { + font-size: 1.75rem; + font-weight: 700; + margin-top: var(--space-3xl); + margin-bottom: var(--space-lg); + color: var(--color-text); +} + +.article__content h3 { + font-size: 1.25rem; + font-weight: 600; + margin-top: var(--space-2xl); + margin-bottom: var(--space-md); + color: var(--color-text); +} + +.article__content p { + color: var(--color-text-secondary); + line-height: 1.8; + margin-bottom: var(--space-lg); + font-size: 1.05rem; +} + +.article__content ul, +.article__content ol { + color: var(--color-text-secondary); + line-height: 1.8; + margin-bottom: var(--space-lg); + padding-left: var(--space-xl); + font-size: 1.05rem; +} + +.article__content li { + margin-bottom: var(--space-sm); +} + +.article__content code { + background: var(--color-bg-secondary); + padding: 2px 6px; + border-radius: var(--radius-sm); + font-family: var(--font-mono); + font-size: 0.9em; + color: var(--color-accent-light); +} + +.article__content pre { + background: var(--color-bg-secondary); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); + padding: var(--space-lg); + overflow-x: auto; + margin-bottom: var(--space-lg); +} + +.article__content pre code { + background: none; + padding: 0; + color: var(--color-text); + font-size: 0.875rem; + line-height: 1.7; +} + +.article__content table { + width: 100%; + border-collapse: collapse; + margin-bottom: var(--space-lg); + font-size: 0.95rem; +} + +.article__content th { + text-align: left; + padding: var(--space-md); + background: var(--color-bg-secondary); + color: var(--color-text); + font-weight: 600; + border-bottom: 2px solid var(--color-border); +} + +.article__content td { + padding: var(--space-md); + border-bottom: 1px solid var(--color-border); + color: var(--color-text-secondary); +} + +.article__callout { + background: rgba(126, 87, 194, 0.1); + border-left: 3px solid var(--color-accent); + border-radius: 0 var(--radius-md) var(--radius-md) 0; + padding: var(--space-lg); + margin-bottom: var(--space-lg); + color: var(--color-text); + font-size: 1.05rem; + line-height: 1.7; +} + +.article__cta { + background: var(--color-bg-card); + border: 1px solid var(--color-border); + border-radius: var(--radius-lg); + padding: var(--space-2xl); + text-align: center; + margin-top: var(--space-3xl); +} + +.article__cta h3 { + font-size: 1.5rem; + margin-bottom: var(--space-md); +} + +.article__cta p { + color: var(--color-text-secondary); + margin-bottom: var(--space-lg); +} + +.article__footer { + margin-top: var(--space-3xl); + padding-top: var(--space-xl); + border-top: 1px solid var(--color-border); +} + +.article__back { + color: var(--color-accent-light); + text-decoration: none; + font-weight: 600; + transition: color 0.2s; +} + +.article__back:hover { + color: var(--color-accent); +} + +/* --- Nav active state --- */ +.nav__link--active { + color: var(--color-accent-light) !important; +} + diff --git a/website/package.json b/website/package.json index 09512266..9e3f76ce 100644 --- a/website/package.json +++ b/website/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "description": "Stacker CLI - Modern landing page", "scripts": { - "build": "tsc && cp src/index.html dist/ && cp src/styles.css dist/ && cp -r assets dist/", + "build": "tsc && cp src/index.html dist/ && cp src/styles.css dist/ && cp -r assets dist/ && cp -r src/blog dist/blog", "dev": "tsc --watch", "serve": "npx serve dist -p 3456" }, diff --git a/website/src/blog/ai-startup-hosting.html b/website/src/blog/ai-startup-hosting.html new file mode 100644 index 00000000..05ebb633 --- /dev/null +++ b/website/src/blog/ai-startup-hosting.html @@ -0,0 +1,356 @@ + + + + + + How to Deploy an AI-Built Startup Without Burning Cash on Hosting - Stacker Blog + + + + + + + + + + + + + + +
+
+
+
+ +

How to Deploy an AI-Built Startup Without Burning Cash on Hosting

+

+ AI tools let anyone build a working app in hours. But hosting costs can eat your runway before you get your first customer. Here's how to deploy on your own server for a fraction of the price. +

+
+ +
+

The AI Startup Boom

+

+ Something fundamental changed in 2025–2026. Tools like Cursor, v0, Bolt, Claude, and ChatGPT made it possible for anyone - not just engineers - to build a working product in a weekend. You describe what you want, the AI writes the code, and suddenly you have a SaaS, a marketplace, an internal tool, or a mobile backend that actually works. +

+

+ This is great news for founders. The cost of building software dropped to nearly zero. But the cost of running software didn't. +

+ +

The Hosting Cost Trap

+

+ Here's the problem most AI-built startups hit: the app works on your laptop, but to put it in front of real users you need a server. And the "easy" hosting options are expensive. +

+

+ Let's look at the typical monthly cost for a small startup running a web app, a database, Redis, and a few background workers: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PlatformMonthly CostWhat You Get
Vercel / Netlify$20–$250+Frontend only, no database
Railway / Render$50–$300+Full-stack, but usage-based pricing spikes fast
Heroku$100–$500+Easy but expensive at scale
AWS / GCP (managed)$100–$500+Powerful but complex, requires DevOps knowledge
Your own server + Stacker$5–$20Full control, everything included
+ +
+ The math is simple. A $5–$20/month VPS (Hetzner, DigitalOcean, Contabo) can run a production web app, PostgreSQL, Redis, a reverse proxy with SSL, and background workers. That's 10–50x cheaper than managed platforms. +
+ +

Why Stacker?

+

+ The problem with self-hosting has always been the operational overhead. You need to know Docker, networking, SSL certificates, reverse proxies, database backups, firewall rules… It's a full-time job. +

+

+ Stacker removes that overhead. It's a single CLI tool that takes your project - the one AI generated for you - and deploys it to your own server in a few commands. No YAML file hell, no Kubernetes, no manual nginx configuration. +

+ +

Step-by-Step: Deploy Your AI-Built App

+

+ Let's say you built a SaaS with Next.js (frontend), PostgreSQL (database), and Redis (caching) using Cursor or ChatGPT. Here's how to get it live on your own server. +

+ +

1. Get a Cheap Server

+

+ Rent a VPS from any provider. Hetzner is the best value in Europe (CX22: 2 vCPU, 4 GB RAM, 40 GB disk for ~€5/month). DigitalOcean and Vultr are good alternatives. You need roughly 2–4 GB of RAM for most small apps. +

+ +

2. Add a stacker.yml to Your Project

+

+ This is the only file you add. It tells Stacker what your app is, what services it needs, and where to deploy: +

+
# stacker.yml
+name: my-startup
+app:
+  type: node
+  ports:
+    - "3000:3000"
+  environment:
+    NODE_ENV: production
+
+services:
+  - name: postgres
+    image: postgres:16-alpine
+    environment:
+      POSTGRES_PASSWORD: ${DB_PASSWORD}
+    volumes:
+      - pgdata:/var/lib/postgresql/data
+    healthcheck:
+      test: pg_isready -U postgres
+
+  - name: redis
+    image: redis:7-alpine
+    command: redis-server --requirepass ${REDIS_PASSWORD}
+
+volumes:
+  pgdata: {}
+
+deploy:
+  target: server
+  server:
+    host: 123.45.67.89
+    user: root
+    ssh_key: ~/.ssh/id_ed25519
+
+proxy:
+  type: nginx
+  domains:
+    - domain: myapp.com
+      ssl: auto
+      upstream: app:3000
+ +

3. Deploy

+

+ One command: +

+
stacker deploy
+

+ That's it. Stacker will: +

+
    +
  • Detect your project type and generate a Dockerfile
  • +
  • Build a Docker Compose stack from your stacker.yml
  • +
  • Copy everything to your server over SSH
  • +
  • Start all containers (app, database, Redis)
  • +
  • Configure nginx with automatic SSL (Let's Encrypt)
  • +
  • Set up firewall rules to open only the ports you need
  • +
+

+ Your app is now live at myapp.com. +

+ +

What If You Need More Services?

+

+ Most real apps need more than just a web server and a database. Maybe you want analytics, a queue, file storage, or monitoring. Stacker handles multi-service stacks natively: +

+
services:
+  - name: postgres
+    image: postgres:16-alpine
+  - name: redis
+    image: redis:7-alpine
+  - name: rabbitmq
+    image: rabbitmq:3-management
+  - name: minio
+    image: minio/minio
+    command: server /data
+  - name: worker
+    image: myapp/worker:latest
+    command: python worker.py
+

+ All services run in isolated containers on the same Docker network. They can talk to each other by service name (postgres, redis, rabbitmq) - no IP addresses, no manual networking. +

+ +

The Cost Comparison: Real Numbers

+

+ Let's compare a realistic startup setup over 12 months: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SetupMonthlyYearly
Railway (web + DB + Redis + worker)~$150~$1,800
Vercel + PlanetScale + Upstash~$80~$960
Heroku (dyno + Postgres + Redis)~$250~$3,000
Hetzner VPS + Stacker~$8~$96
+ +
+ That's $800–$2,900 saved per year. For a bootstrapped startup, that's real runway - months of server costs covered by the savings alone. +
+ +

Common Concerns

+ +

"What about uptime?"

+

+ A Hetzner CX22 has a 99.9% uptime SLA. For most startups, that's better than you need. If you outgrow one server, Stacker supports multi-server deployments too. And you can always set up a simple status page to monitor your services. +

+ +

"What about backups?"

+

+ Stacker uses named Docker volumes for persistent data. You can back up your database with a simple cron job, or use stacker agent to manage remote operations. Don't rely on your hosting provider's backups as your only safety net - a 5-minute pg_dump cron job is enough for most startups. +

+ +

"What about security?"

+

+ Stacker handles SSL automatically (Let's Encrypt). It also configures firewall rules so only necessary ports are open. The stacker.yml format supports config_contract to declare which fields are secrets - Stacker generates strong values automatically and stores them securely. +

+ +

"I don't know Docker. Is this still for me?"

+

+ Yes. Stacker auto-detects your project type (Node, Python, Rust, Go, PHP, or static) and generates the Docker configuration for you. You never write a Dockerfile. The stacker.yml above is the entire configuration. +

+ +

What About AI-Generated Projects Specifically?

+

+ AI tools produce projects that follow standard conventions: package.json for Node, requirements.txt for Python, Cargo.toml for Rust. Stacker's auto-detection works perfectly with these. The same tools that generated your app in hours now deploy it in seconds. +

+

+ The workflow looks like this: +

+
    +
  1. Build with Cursor / v0 / Claude / ChatGPT (hours, not weeks)
  2. +
  3. Test locally on your laptop
  4. +
  5. Deploy with stacker deploy (seconds, not days)
  6. +
  7. Iterate - push changes with stacker deploy again
  8. +
+

+ Total infrastructure cost: under $10/month. Total time spent on operations: minutes. +

+ +

Getting Started

+

+ Ready to try it? Here's what you need: +

+
    +
  • A server - any VPS with 2+ GB RAM (~$5/month on Hetzner)
  • +
  • Stacker - install with one command: curl -fsSL https://get.stacker.my | sh
  • +
  • Your project - the one you already built with AI
  • +
+

+ Then add your stacker.yml, run stacker deploy, and you're live. +

+ +

The Bottom Line

+

+ AI lowered the cost of building software to near zero. Stacker lowers the cost of running it to near zero. Together, they let a solo founder or small team build and ship a real product for less than the price of a coffee subscription. +

+

+ The next time an AI tool gives you a working app in a weekend, don't pay $200/month to put it online. Get a $5 server, add a stacker.yml, and deploy. +

+ +
+

Ready to deploy?

+

Stacker is open source. Star it on GitHub and try it on your next project.

+ Get Stacker on GitHub +
+
+ + +
+
+
+ + + + + + diff --git a/website/src/blog/index.html b/website/src/blog/index.html new file mode 100644 index 00000000..d21d32d9 --- /dev/null +++ b/website/src/blog/index.html @@ -0,0 +1,87 @@ + + + + + + Blog - Stacker + + + + + + + + + + + +
+
+
+

Blog

+

Guides, tutorials, and insights on deploying applications with Stacker.

+
+ +
+ +
+
+
+ + + + + + diff --git a/website/src/index.html b/website/src/index.html index b018e524..f173f5ca 100644 --- a/website/src/index.html +++ b/website/src/index.html @@ -3,8 +3,8 @@ - Stacker v0.3.5 — AI Infrastructure CLI by TryDirect - + Stacker v0.3.5 - AI Infrastructure CLI by TryDirect + @@ -39,6 +39,7 @@ Examples Commands Providers + Blog

SSH Key Management

-

Generate, view, and upload SSH keys for your servers — all stored securely in HashiCorp Vault. No manual key juggling.

+

Generate, view, and upload SSH keys for your servers - all stored securely in HashiCorp Vault. No manual key juggling.

@@ -213,7 +214,7 @@

SSH Key Management

-

Stacker v0.3.5
— config sync, per-install secrets & safer marketplace snapshots.

+

Stacker v0.3.5
- config sync, per-install secrets & safer marketplace snapshots.

Releases v0.3.3 through v0.3.5 bring stacker sync for pushing configuration without a deploy, field policies that generate fresh secrets for every marketplace install, secret-free baked snapshots with author-declared volume policies, and cloud deploys that stop with an error instead of a warning when SSH access can't be verified.

@@ -225,7 +226,7 @@

stacker sync

Marketplace

Field policies & generated secrets

-

Mark each field in config_contract as fixed, editable, or generated. Generated values — hex, alphanumeric, uuid, derived_jwt — are stripped at publish and created fresh on every install, so no two buyers share a secret.

+

Mark each field in config_contract as fixed, editable, or generated. Generated values - hex, alphanumeric, uuid, derived_jwt - are stripped at publish and created fresh on every install, so no two buyers share a secret.

Bake @@ -240,7 +241,7 @@

Verified SSH access

Monitoring

stacker monitor

-

A built-in container-down alarm. Declare a monitoring.alerts block and get notified — terminal, webhook (ntfy/Slack), or pipe — the moment a container stops and when it recovers. Edge-triggered and cron-friendly with --once.

+

A built-in container-down alarm. Declare a monitoring.alerts block and get notified - terminal, webhook (ntfy/Slack), or pipe - the moment a container stops and when it recovers. Edge-triggered and cron-friendly with --once.

Pipes @@ -250,12 +251,12 @@

Declarative pipes (IaC)

Pipes

Manual endpoints & retries

-

Create pipes non-interactively with --source-endpoint / --target-endpoint — works for any HTTP API. Attach a retry policy and --on-failure / --on-success handlers.

+

Create pipes non-interactively with --source-endpoint / --target-endpoint - works for any HTTP API. Attach a retry policy and --on-failure / --on-success handlers.

Proxy

Reverse-proxy routing

-

Working routing for Traefik (labels), Caddy (Caddyfile), and Nginx Proxy Manager (proxy hosts), all driven by proxy.domains — platform-managed, so no double-deploy or port collisions.

+

Working routing for Traefik (labels), Caddy (Caddyfile), and Nginx Proxy Manager (proxy hosts), all driven by proxy.domains - platform-managed, so no double-deploy or port collisions.

Config @@ -287,7 +288,7 @@

Remote secret tools

Your infrastructure,
understood by AI.

-

Stacker's AI engine doesn't just guess — it deeply analyzes your project to generate the perfect deployment configuration.

+

Stacker's AI engine doesn't just guess - it deeply analyzes your project to generate the perfect deployment configuration.

@@ -518,7 +519,7 @@

35 top-level commands.
stacker init --with-ai

-

Scan your project and generate stacker.yml — with optional AI assistance.

+

Scan your project and generate stacker.yml - with optional AI assistance.

@@ -531,7 +532,7 @@

35 top-level commands.
stacker sync --verify

-

Push project and app configuration to Stacker without deploying — no server contact, no containers started.

+

Push project and app configuration to Stacker without deploying - no server contact, no containers started.

@@ -583,7 +584,7 @@

35 top-level commands.
stacker service add <name>

-

Add services from 20+ built-in templates — Postgres, Redis, WordPress, and more. Auto-adds dependencies.

+

Add services from 20+ built-in templates - Postgres, Redis, WordPress, and more. Auto-adds dependencies.

diff --git a/website/src/main.ts b/website/src/main.ts index ce6a42ef..09b2b2c1 100644 --- a/website/src/main.ts +++ b/website/src/main.ts @@ -1,5 +1,5 @@ // ============================================================ -// Stacker Website — TypeScript Interactions +// Stacker Website - TypeScript Interactions // Particle system, typing effect, scroll animations, counters // ============================================================ @@ -248,7 +248,7 @@ class ScrollAnimator { document.querySelectorAll('[data-animate]').forEach((el) => { const rect = (el as HTMLElement).getBoundingClientRect(); if (rect.top < vh) { - // Element is already in the viewport — show it immediately + // Element is already in the viewport - show it immediately const delay = parseInt((el as HTMLElement).dataset.delay || '0', 10); setTimeout(() => (el as HTMLElement).classList.add('is-visible'), delay); } else { diff --git a/website/src/styles.css b/website/src/styles.css index 3d40b46a..e8ad5f6f 100644 --- a/website/src/styles.css +++ b/website/src/styles.css @@ -1,5 +1,5 @@ /* ============================================================ - Stacker Website — Styles + Stacker Website - Styles TryDirect brand colors + modern visual effects ============================================================ */ @@ -1584,3 +1584,305 @@ code { grid-template-columns: 1fr; } } + +/* ============================================================ + Blog + ============================================================ */ + +.blog-page { + padding: calc(80px + var(--space-4xl)) 0 var(--space-4xl); + min-height: 80vh; +} + +.blog-header { + text-align: center; + margin-bottom: var(--space-4xl); +} + +.blog-header__title { + font-size: clamp(2.5rem, 5vw, 4rem); + font-weight: 800; + margin-bottom: var(--space-md); + background: linear-gradient(135deg, var(--color-text) 0%, var(--color-accent-light) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.blog-header__subtitle { + font-size: 1.125rem; + color: var(--color-text-secondary); + max-width: 600px; + margin: 0 auto; +} + +.blog-grid { + display: grid; + gap: var(--space-xl); + max-width: 800px; + margin: 0 auto; +} + +.blog-card { + background: var(--color-bg-card); + border: 1px solid var(--color-border); + border-radius: var(--radius-lg); + padding: var(--space-xl); + transition: border-color 0.3s var(--ease-out), transform 0.3s var(--ease-out); +} + +.blog-card:hover { + border-color: var(--color-accent); + transform: translateY(-2px); +} + +.blog-card__meta { + display: flex; + align-items: center; + gap: var(--space-md); + margin-bottom: var(--space-md); +} + +.blog-card__tag { + background: rgba(126, 87, 194, 0.15); + color: var(--color-accent-light); + padding: var(--space-xs) var(--space-sm); + border-radius: var(--radius-sm); + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.blog-card__date { + color: var(--color-text-dim); + font-size: 0.875rem; +} + +.blog-card__title { + font-size: 1.5rem; + font-weight: 700; + line-height: 1.3; + margin-bottom: var(--space-md); +} + +.blog-card__title a { + color: var(--color-text); + text-decoration: none; + transition: color 0.2s; +} + +.blog-card__title a:hover { + color: var(--color-accent-light); +} + +.blog-card__excerpt { + color: var(--color-text-secondary); + line-height: 1.7; + margin-bottom: var(--space-lg); +} + +.blog-card__link { + color: var(--color-accent-light); + text-decoration: none; + font-weight: 600; + transition: color 0.2s; +} + +.blog-card__link:hover { + color: var(--color-accent); +} + +/* --- Article Page --- */ + +.article-page { + padding: calc(80px + var(--space-3xl)) 0 var(--space-4xl); +} + +.container--narrow { + max-width: 760px; + margin: 0 auto; +} + +.article__header { + margin-bottom: var(--space-3xl); +} + +.article__meta { + display: flex; + align-items: center; + gap: var(--space-md); + margin-bottom: var(--space-lg); + flex-wrap: wrap; +} + +.article__tag { + background: rgba(126, 87, 194, 0.15); + color: var(--color-accent-light); + padding: var(--space-xs) var(--space-sm); + border-radius: var(--radius-sm); + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.article__meta time, +.article__read-time { + color: var(--color-text-dim); + font-size: 0.875rem; +} + +.article__title { + font-size: clamp(2rem, 4vw, 3rem); + font-weight: 800; + line-height: 1.2; + margin-bottom: var(--space-lg); + background: linear-gradient(135deg, var(--color-text) 0%, var(--color-accent-light) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.article__lead { + font-size: 1.25rem; + color: var(--color-text-secondary); + line-height: 1.7; +} + +.article__content h2 { + font-size: 1.75rem; + font-weight: 700; + margin-top: var(--space-3xl); + margin-bottom: var(--space-lg); + color: var(--color-text); +} + +.article__content h3 { + font-size: 1.25rem; + font-weight: 600; + margin-top: var(--space-2xl); + margin-bottom: var(--space-md); + color: var(--color-text); +} + +.article__content p { + color: var(--color-text-secondary); + line-height: 1.8; + margin-bottom: var(--space-lg); + font-size: 1.05rem; +} + +.article__content ul, +.article__content ol { + color: var(--color-text-secondary); + line-height: 1.8; + margin-bottom: var(--space-lg); + padding-left: var(--space-xl); + font-size: 1.05rem; +} + +.article__content li { + margin-bottom: var(--space-sm); +} + +.article__content code { + background: var(--color-bg-secondary); + padding: 2px 6px; + border-radius: var(--radius-sm); + font-family: var(--font-mono); + font-size: 0.9em; + color: var(--color-accent-light); +} + +.article__content pre { + background: var(--color-bg-secondary); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); + padding: var(--space-lg); + overflow-x: auto; + margin-bottom: var(--space-lg); +} + +.article__content pre code { + background: none; + padding: 0; + color: var(--color-text); + font-size: 0.875rem; + line-height: 1.7; +} + +.article__content table { + width: 100%; + border-collapse: collapse; + margin-bottom: var(--space-lg); + font-size: 0.95rem; +} + +.article__content th { + text-align: left; + padding: var(--space-md); + background: var(--color-bg-secondary); + color: var(--color-text); + font-weight: 600; + border-bottom: 2px solid var(--color-border); +} + +.article__content td { + padding: var(--space-md); + border-bottom: 1px solid var(--color-border); + color: var(--color-text-secondary); +} + +.article__callout { + background: rgba(126, 87, 194, 0.1); + border-left: 3px solid var(--color-accent); + border-radius: 0 var(--radius-md) var(--radius-md) 0; + padding: var(--space-lg); + margin-bottom: var(--space-lg); + color: var(--color-text); + font-size: 1.05rem; + line-height: 1.7; +} + +.article__cta { + background: var(--color-bg-card); + border: 1px solid var(--color-border); + border-radius: var(--radius-lg); + padding: var(--space-2xl); + text-align: center; + margin-top: var(--space-3xl); +} + +.article__cta h3 { + font-size: 1.5rem; + margin-bottom: var(--space-md); +} + +.article__cta p { + color: var(--color-text-secondary); + margin-bottom: var(--space-lg); +} + +.article__footer { + margin-top: var(--space-3xl); + padding-top: var(--space-xl); + border-top: 1px solid var(--color-border); +} + +.article__back { + color: var(--color-accent-light); + text-decoration: none; + font-weight: 600; + transition: color 0.2s; +} + +.article__back:hover { + color: var(--color-accent); +} + +/* --- Nav active state --- */ +.nav__link--active { + color: var(--color-accent-light) !important; +} +