gws up
Deploy services to a Kubernetes cluster.
Usageβ
gws up [options]
Output:
π Deploying GetWebstack...
β Validating dependencies...
β Docker: 24.0.0
β Git: 2.40.0
β mkcert: 1.4.4
β Creating k3d cluster 'myapp'... (15s)
β Generating TLS certificates...
β Created: *.myapp.acme.getwebstack.dev
β Building Docker images...
β api: localhost:5000/myapp-api:latest (25s)
β app: localhost:5000/myapp-app:latest (30s)
β Deploying to namespace 'myapp'...
β Created namespace
β Deployed 2 services
β Pods running (2/2)
β Configuring Gateway API...
β Created HTTPRoutes
β Port-forward active (8080, 9443)
β Starting file sync...
β api: active (0.5s latency)
β app: active (0.6s latency)
β Activating auto-rebuild watchers...
β Watching Dockerfiles
Deployment successful! π
Services available at:
π API: https://api.myapp.acme.getwebstack.dev
π App: https://app.myapp.acme.getwebstack.dev
File sync active:
π File sync: β (0.5s latency)
π Auto-rebuild: β (Dockerfile changes)
Next steps:
- Edit code locally (changes sync automatically)
- View status: gws status
- View logs: gws logs
- Stop: gws down
Note: This command must be run from within your project directory.
Optionsβ
| Option | Description | Default |
|---|---|---|
-w, --worktree <name> | Worktree name to deploy | Main project deployment |
-p, --project <name> | Project name to deploy from | Auto-detected from current directory |
-y, --yes | Skip confirmation prompts | false |
Examples:
# Deploy from a specific project, a specific worktree
gws up -p myapp -w feature-auth
# Deploy specific worktree for current directory project.
gws up -w feature-auth
# Deploy from a specific project. Deploys the main project, not a worktree.
gws up -p myapp
# Skip prompts
gws up -y
# deploy project from current dorectory
gws up
Accessing your services (unified URLs)β
After gws up, each HTTP service is reachable locally at a unified URL that is identical to the one a visitor uses when you gws share it:
https://<service>.<project>.<org>.getwebstack.dev
The same URL works whether you run the app locally or share it β no perβenvironment config, no CORS surprises when you flip between the two. gws up prints these URLs when your deployment is registered with an organization.
- Port
:443(no port in the URL). On k3d,gws upmaps the cluster gateway onto host443so the URL is portless, exactly like the shared origin. This is bound to127.0.0.1only (not exposed to your LAN). - Fallback to
:9443. If host443/80is already in use, Docker runs rootless, or you use a nonβk3d provider,gws upprints the URL with:9443and tells you why. Free port443(k3d) for full sameβport parity. .localURLs are gone. The CLI no longer emitslocal.getwebstack.devhosts β the unified{service}.{projectSlug}.{orgSlug}.getwebstack.devhost is the only one. (The static*.localDNS record is kept only so deployments from oldergwsversions keep resolving.)
Calling one service from another in the browserβ
The unified host is shared across your services (the gws-namespace cookie selects the deployment), so a crossβsubdomain call from client.* to server.* must send that cookie. Configure your app accordingly:
- Client: send credentials on crossβorigin requests β e.g.
fetch(url, { credentials: "include" })or AxioswithCredentials: true. - Server: set CORS
credentials: trueand allow the portless unified origin (https://client.<project>.<org>.getwebstack.dev) β not the:9443form.
Multirepo Behaviorβ
When running gws up in a multirepo setup, the command deploys all services from each repository to a single Kubernetes namespace.
Project Structureβ
myapp/ # Parent directory
βββ .worktrees/ # Shared worktrees folder (at parent level)
β βββ feature-auth/ # One folder per worktree name
β βββ api/ # Worktree for api repo
β β βββ src/
β βββ app/ # Worktree for app repo
β βββ src/
βββ api/ # Git repo 1
β βββ .git/
β βββ src/
βββ app/ # Git repo 2
βββ .git/
βββ src/
Deploying Main Workspaceβ
cd myapp
gws up
What happens:
- Detects all repositories in
myapp/(api, app) - Builds Docker image for each service
- Deploys all services to namespace
myapp - Sets up routing for all services
Result:
Services available at:
π API: https://api.myapp.acme.getwebstack.dev
π App: https://app.myapp.acme.getwebstack.dev
Deploying Worktreeβ
cd myapp
gws up -w feature-auth
What happens:
- Detects all repositories in
myapp/ - Finds worktree
feature-authunder.worktrees/ - Builds Docker images from worktree directories
- Deploys all services to namespace
myapp-feature-auth - Sets up routing for all services
Result:
Services available at (same hostnames as the default deployment;
the `gws-namespace` cookie selects this fork):
π API: https://api.myapp.acme.getwebstack.dev
π App: https://app.myapp.acme.getwebstack.dev
π Picker: https://myapp.acme.getwebstack.dev (choose deployment)
Key Points:
- All services from different repos deploy to the same namespace
- Each worktree gets its own isolated namespace
- File sync is active for all services in the deployment
Troubleshootingβ
Docker Not Runningβ
# Start Docker Desktop (macOS/Windows)
open -a Docker
# Or start Docker daemon (Linux)
sudo systemctl start docker
# Verify
docker ps
# Try again
gws up
Port Already in Useβ
# Find process using port
sudo lsof -ti:8080
# Kill process
sudo lsof -ti:8080 | xargs kill -9
# Try again
gws up
Build Failedβ
# Ensure Dockerfile exists
ls api/Dockerfile
# Check pod logs
gws logs api
DNS Not Resolvingβ
# Test DNS
nslookup api.myapp.acme.getwebstack.dev
# Should return: 127.0.0.1
# Flush DNS cache:
# macOS: sudo dscacheutil -flushcache
# Linux: sudo systemd-resolve --flush-caches
# Windows: ipconfig /flushdns
See Alsoβ
- gws down - Stop deployment
- gws status - View deployment status
- gws logs - View service logs
- gws fork - Create worktree before deploying
- gws cluster up - Provision cluster + shared infra without deploying a project