Skip to content

Deployment

This guide covers deploying your StackSolo project to Google Cloud Platform.

Terminal window
stacksolo deploy

That’s it. StackSolo handles everything else.

  1. Secrets Check - Missing secrets are detected and optionally created
  2. Validation - Config is validated
  3. Code Generation - CDKTF/Terraform code is generated
  4. Build - Container images are built (if any)
  5. Apply - Terraform applies the infrastructure
  6. Output - URLs and connection strings are displayed

See what would change without actually deploying:

Terminal window
stacksolo deploy --preview

If you’ve already built and pushed images:

Terminal window
stacksolo deploy --skip-build

Deploy with a specific container image tag:

Terminal window
stacksolo deploy --tag v1.2.3

Force delete and recreate resources that are stuck:

Terminal window
stacksolo deploy --force

StackSolo automatically handles secrets referenced with @secret/secret-name in your config.

Create a .env.production file with your secrets:

Terminal window
# .env.production (add to .gitignore!)
OPENAI_API_KEY=sk-...
STRIPE_SECRET_KEY=sk_live_...
DATABASE_URL=postgres://...

Reference them in your config:

{
"functions": [{
"name": "api",
"env": {
"OPENAI_API_KEY": "@secret/openai-api-key",
"STRIPE_SECRET_KEY": "@secret/stripe-secret-key"
}
}]
}

During deploy, StackSolo will:

  1. Check which secrets exist in GCP Secret Manager
  2. Offer to create missing secrets from .env.production
  3. Prompt for any secrets not found in .env.production
Terminal window
$ stacksolo deploy
[1/4] Checking secrets
database-url exists
openai-api-key missing
Found OPENAI_API_KEY in .env.production
? Use this value? (Y/n)
Creating secret: openai-api-key...
Created: openai-api-key

See the full Secrets Management Guide for more details.

StackSolo generates infrastructure code in .stacksolo/:

CDKTF Backend (GCP):

.stacksolo/
├── cdktf/
│ ├── main.ts # Infrastructure definition
│ ├── cdktf.json # CDKTF config
│ └── terraform/ # Generated Terraform
└── stacksolo.config.json

Kubernetes Backend with Helm:

.stacksolo/
├── helm-chart/
│ ├── Chart.yaml # Chart metadata
│ ├── values.yaml # Default values
│ └── templates/ # K8s manifests
└── stacksolo.config.json

You can inspect this code to see exactly what will be created.

For Kubernetes backend projects, use --helm to generate Helm charts:

Terminal window
stacksolo deploy --helm --preview

Helm charts enable:

  • Multi-environment deployments via values files (values-dev.yaml, values-prod.yaml)
  • GitOps workflows with ArgoCD or Flux
  • Rollbacks with helm rollback
  • Templated configuration with --set overrides

See Helm Plugin for full documentation.

If you want to manage the infrastructure yourself:

  1. The generated code in .stacksolo/cdktf/ is yours
  2. You can run cdktf deploy directly
  3. Or export to plain Terraform with cdktf synth

Terraform state is stored locally in .stacksolo/cdktf/terraform.tfstate.

For team environments, consider configuring remote state:

{
"project": {
"backend": "cdktf",
"stateBackend": {
"bucket": "my-terraform-state",
"prefix": "stacksolo"
}
}
}
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install StackSolo
run: npm install -g @stacksolo/cli
- name: Setup GCP Auth
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}
- name: Deploy
run: stacksolo deploy
Terminal window
stacksolo status
Terminal window
stacksolo output
Terminal window
stacksolo logs --since 1h

StackSolo logs every operation during deployment with millisecond precision. Use stacksolo events to view the event timeline:

Terminal window
# View latest deploy session
stacksolo events
# List all sessions
stacksolo events list
# Filter by category
stacksolo events show --category terraform

Example output:

+--------------+-----------------+------------+----------------------+---------------------+
| TIME | PROJECT | CATEGORY | EVENT | DETAILS |
+--------------+-----------------+------------+----------------------+---------------------+
| 19:55:54.294 | my-app | internal | session_start | deploy |
| 19:55:54.297 | my-app | internal | phase_start | phase=preflight |
| 19:56:24.356 | my-app | internal | phase_end | phase=preflight |
| 19:56:24.358 | my-app | internal | phase_start | phase=apply |
| 19:56:24.359 | my-app | terraform | apply_start | |
| 19:57:14.519 | my-app | terraform | apply_end | exit=0 |
+--------------+-----------------+------------+----------------------+---------------------+

Events are stored in ~/.stacksolo/registry.db and persisted across sessions.

StackSolo doesn’t have built-in rollback, but you can:

  1. Revert your config changes
  2. Run stacksolo deploy again
  3. Or use Terraform directly: cd .stacksolo/cdktf && terraform apply

Remove all deployed resources:

Terminal window
# With confirmation
stacksolo destroy
# Skip confirmation
stacksolo destroy --force

Warning: This permanently deletes all resources including databases.

Firebase Hosting for Apps with Firebase Auth

Section titled “Firebase Hosting for Apps with Firebase Auth”

If your app uses Firebase Authentication with social providers (Google, Apple, etc.), you should use Firebase Hosting instead of GCS buckets. This avoids cross-origin cookie issues that cause “missing initial state” errors.

  1. Set hosting: "firebase" in your UI config:
{
"networks": [{
"name": "main",
"uis": [{
"name": "web",
"hosting": "firebase",
"sourceDir": "apps/web"
}]
}]
}
  1. Create a firebase.json in your project root:
{
"hosting": {
"public": "apps/web/dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{ "source": "**", "destination": "/index.html" }
]
}
}
  1. Set authDomain to your Firebase Hosting domain in your app:
.env.production
VITE_FIREBASE_AUTH_DOMAIN=your-project.web.app
  1. Deploy:
Terminal window
stacksolo deploy

StackSolo will run firebase deploy --only hosting after the Terraform apply completes.

  • Firebase CLI installed: npm install -g firebase-tools
  • Logged in to Firebase: firebase login
  • Firebase project initialized: firebase init

Modern browsers block third-party cookies/storage. When your app is hosted on a different domain than Firebase’s authDomain, OAuth redirects fail with “missing initial state” errors. Firebase Hosting ensures same-origin hosting, avoiding these issues.


Make sure you’re authenticated:

Terminal window
gcloud auth login
gcloud auth application-default login

Enable required APIs:

Terminal window
gcloud services enable cloudfunctions.googleapis.com
gcloud services enable cloudbuild.googleapis.com
gcloud services enable run.googleapis.com
gcloud services enable compute.googleapis.com

The resource may have been created outside of StackSolo. Options:

  1. Import it: cd .stacksolo/cdktf && terraform import ...
  2. Delete it manually in GCP Console
  3. Use --force to recreate

Reset and reimport:

Terminal window
stacksolo reset
stacksolo deploy --refresh