Skip to main content

Sprintsail Developer Guide

Everything your team needs to ship production workloads on Sprintsail — from first push to scaled production. This guide covers authentication, deployment, services, domains, scaling, monitoring, CI/CD, and team management.

Audience: Engineers, DevOps, Platform Engineers, Technical Leads


1. Platform Overview

Sprintsail is a fully managed application PaaS. You push source code — we handle the build, deploy, TLS, DNS, scaling, and monitoring. Your code runs in your cloud account. We orchestrate it.

What you get:

  • Source-to-production in under 60 seconds (ss push)
  • 8 runtime support: Node.js, Python, Go, Rust, Java, .NET, Ruby, static sites
  • Managed PostgreSQL, Redis, and S3 via service marketplace
  • Automatic TLS certificates (Let's Encrypt)
  • Custom domain mapping with DNS automation
  • Horizontal and vertical autoscaling
  • Integrated logging, metrics, and dashboards
  • GitHub Actions / GitLab CI integration
  • Team-based RBAC (organizations, spaces, roles)

What you don't manage:

  • Kubernetes clusters, node groups, or control plane
  • Load balancers, ingress controllers, or DNS records
  • Certificate provisioning or renewal
  • Container image registries or build pipelines
  • Network policies, security groups, or WAF rules

2. Prerequisites

Install the CLI

npm install -g @sprintsail/cli

Verify installation:

ss version

Authenticate

ss login

This opens your browser for PKCE-based OAuth authentication via Cognito. The CLI starts a local callback server on localhost:9876, receives the authorization code, and exchanges it for tokens. Tokens are stored locally and refresh automatically.

# Verify your identity
ss whoami

Output:

Email:  engineer@company.com
Org: acme-corp
Role: admin

Logout

ss logout

3. Organizations and Spaces

Organizations

An organization is your top-level account. All apps, services, and team members belong to an org.

# Create an org
ss org create acme-corp

# List your orgs
ss orgs

# Switch active org
ss org set acme-corp

Org approval: New organizations require admin approval before they can deploy workloads. You'll receive an email once approved.

Spaces

Spaces isolate workloads within an org. Use them for environments (production, staging, dev) or team boundaries.

# Create a space
ss space create production
ss space create staging

# List spaces
ss spaces

# Set active space
ss space set production

Each space maps to a Kubernetes namespace (sprintsail-{org}-{space}) with its own resource quotas and network policies.

Team Roles

RolePermissions
ownerFull control. Billing, member management, delete org.
adminManage apps, services, spaces, members. Cannot delete org or manage billing.
memberDeploy apps, bind services, view logs. Cannot manage team or spaces.

Org owners and admins implicitly have space-level manager access.


4. Deploying Applications

Push your source code directly. Sprintsail detects the runtime and builds with Cloud Native Buildpacks (Paketo).

# Navigate to your project root
cd my-app

# Create the app
ss create my-api

# Deploy
ss push

What happens on ss push:

  1. Upload — Source code is packaged and uploaded to S3 (encrypted at rest, 30-day lifecycle)
  2. Detect — Paketo buildpacks detect the runtime (Node.js, Python, Go, etc.)
  3. Build — CodeBuild compiles a production OCI image using the detected buildpack
  4. Push — Image is pushed to your org's ECR repository
  5. Deploy — A Kubernetes Deployment is created with health checks, resource limits, and a ClusterIP Service
  6. Route — An Ingress rule is configured with TLS termination and DNS record
  7. Live — Your app is reachable at {app-name}.sprintsail.com

Supported runtimes:

RuntimeDetectionBuild
Node.jspackage.jsonnpm/yarn install, production prune
Pythonrequirements.txt or Pipfilepip install, gunicorn
Gogo.modgo build, static binary
RustCargo.tomlcargo build --release
Javapom.xml or build.gradleMaven/Gradle build, JVM optimization
.NET*.csproj or *.slndotnet publish
RubyGemfilebundle install, puma
Static Sitesindex.html or build outputNGINX serve

Method 2: Dockerfile

If your app has a Dockerfile in the root, Sprintsail uses it instead of buildpacks.

FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
USER 1000:1000
EXPOSE 8080
CMD ["node", "server.js"]

Requirements:

  • Must expose a port (default: 8080, configurable via ss env set PORT=3000)
  • Must run as non-root user (enforced by admission policy)
  • Image must not use :latest tag (enforced by OPA Gatekeeper)

Method 3: Pre-built Image

Deploy an existing container image from any approved registry:

ss create my-app --image {account}.dkr.ecr.{region}.amazonaws.com/my-app:v1.2.3

Approved registries:

  • Your account's ECR ({account}.dkr.ecr.{region}.amazonaws.com/)
  • Paketo buildpack images (paketobuildpacks/, gcr.io/paketo-buildpacks/)

Other registries are blocked by admission policy.

Application Lifecycle

# List all apps in the current space
ss apps

# Get detailed info
ss info my-api

# Stop an app (scale to 0)
ss stop my-api

# Start a stopped app
ss start my-api

# Restart (rolling restart, no downtime)
ss restart my-api

# Delete an app and all its resources
ss delete my-api

5. Environment Variables

Setting Variables

# Set a single variable
ss env set my-api DATABASE_URL=postgres://...

# Set multiple variables
ss env set my-api NODE_ENV=production LOG_LEVEL=info

# View current variables
ss env my-api

Environment variables are injected into the container at runtime via Kubernetes ConfigMaps. Changes trigger a rolling restart.

Secrets

For sensitive values (API keys, passwords, connection strings), use the secrets command:

# Set a secret (stored in Kubernetes Secrets, not ConfigMaps)
ss env set my-api --secret STRIPE_KEY=sk_live_xxxxxxxxxxxx

# Secrets are masked in output
ss env my-api
# STRIPE_KEY=****

Secrets are encrypted at rest via Kubernetes secrets encryption (AWS KMS backed).

Reserved Variables

These are set automatically by Sprintsail:

VariableValue
PORTThe port your app should listen on (default: 8080)
SPRINTSAIL_APPYour app name
SPRINTSAIL_SPACECurrent space name
SPRINTSAIL_ORGCurrent org slug

6. Service Marketplace

Sprintsail provisions managed infrastructure services and injects connection details into your app automatically.

Available Services

ServiceBackingPlans
PostgreSQLAWS RDS PostgreSQL 16micro (t4g.micro, 20GB), small (t4g.small, 50GB)
RedisAWS ElastiCache Redis 7.1micro (t4g.micro)
Object StorageAWS S3standard (versioning optional)
# Browse the marketplace
ss marketplace

Create a Service Instance

# Provision a PostgreSQL database
ss create-service postgresql micro my-db

# Provision Redis
ss create-service redis micro my-cache

# Provision S3 storage
ss create-service storage standard my-bucket

Service provisioning is asynchronous — Crossplane creates the underlying AWS resource. Typical provisioning time:

  • PostgreSQL: 3-5 minutes
  • Redis: 2-3 minutes
  • S3: 30 seconds

Bind a Service to an App

ss bind-service my-api my-db

Binding injects connection details as environment variables:

PostgreSQL binding:

DATABASE_HOST=<auto-generated-endpoint>
DATABASE_PORT=5432
DATABASE_NAME=app_db
DATABASE_USER=app_user
DATABASE_PASSWORD=<auto-generated>
DATABASE_URL=postgres://app_user:****@host:5432/app_db?sslmode=require

Redis binding:

REDIS_HOST=<auto-generated-endpoint>
REDIS_PORT=6379
REDIS_URL=redis://host:6379

S3 binding:

S3_BUCKET=<auto-generated-bucket>
S3_REGION=<your-region>
AWS_ACCESS_KEY_ID=<scoped credentials>
AWS_SECRET_ACCESS_KEY=<scoped credentials>

View and Unbind Services

# List services in current space
ss services

# Unbind a service from an app
ss unbind-service my-api my-db

Unbinding removes the environment variables and triggers a rolling restart. It does not delete the service instance or its data.


7. Custom Domains

Map a Domain

ss map-domain my-api app.company.com

Sprintsail automatically:

  1. Creates a DNS CNAME record pointing to the ingress load balancer
  2. Provisions a TLS certificate via Let's Encrypt (DNS-01 challenge)
  3. Configures the ingress rule for host-based routing

DNS Configuration

Add a CNAME record at your DNS provider:

app.company.com  CNAME  ingress.sprintsail.com

For apex domains (e.g., company.com), use an ALIAS or ANAME record if your provider supports it.

Verify Domain Status

ss domains my-api

Output:

DOMAIN              STATUS     TLS
my-api.sprintsail.com active valid (expires 2026-07-18)
app.company.com active valid (expires 2026-07-18)

Remove a Domain

ss unmap-domain my-api app.company.com

8. Scaling

Manual Scaling

# Scale to 3 instances
ss scale my-api --instances 3

# Scale resources
ss scale my-api --memory 512Mi --cpu 500m

Autoscaling

# Enable autoscaling (2 to 10 instances, target 70% CPU)
ss autoscale my-api --min 2 --max 10 --cpu-target 70

Autoscaling creates a Kubernetes HorizontalPodAutoscaler. Your app scales based on CPU utilization, with a 60-second stabilization window.

Default resource allocations:

SizeCPU RequestCPU LimitMemory RequestMemory Limit
micro100m250m128Mi256Mi
small250m500m256Mi512Mi
medium500m1000m512Mi1Gi
large1000m2000m1Gi2Gi

Zero-Downtime Deployments

All deployments use Kubernetes rolling updates:

  • maxUnavailable: 0 — no downtime during deploys
  • maxSurge: 25% — temporary extra capacity during rollout
  • Health checks gate traffic — new pods only receive traffic after passing readiness probes

9. Deployments and Rollbacks

View Deployment History

ss deployments my-api

Output:

VERSION  STATUS    IMAGE                    CREATED
v5 active my-api:abc123 2 hours ago
v4 inactive my-api:def456 1 day ago
v3 inactive my-api:ghi789 3 days ago

Rollback

# Rollback to the previous version
ss rollback my-api

# Rollback to a specific version
ss rollback my-api --version v3

Rollbacks are instant — they repoint the Deployment to a previous image digest. No rebuild required.


10. Logs and Monitoring

Application Logs

# Stream live logs
ss logs my-api

# View recent logs (last 100 lines)
ss logs my-api --recent

# Follow logs from all instances
ss logs my-api --follow

Logs are collected via Loki and retained for 15 days. They're also shipped to CloudWatch Logs under /sprintsail/apps/{org}/{space}/{app}.

Metrics and Dashboards

Every app automatically exposes:

  • CPU utilization — per-pod and aggregate
  • Memory usage — working set vs limits
  • Request rate — requests per second at the ingress
  • Response latency — p50, p95, p99 at the ingress
  • Error rate — 4xx and 5xx responses

Access Grafana dashboards at your org's monitoring endpoint (provided after org approval).

Health Checks

Sprintsail configures health checks automatically:

ProbePathIntervalThreshold
ReadinessGET / (or custom)10s3 failures → stop traffic
LivenessGET / (or custom)30s3 failures → restart pod

Customize health check paths:

ss env set my-api HEALTH_CHECK_PATH=/healthz

11. CI/CD Integration

GitHub Actions

name: Deploy to Sprintsail
on:
push:
branches: [main]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Sprintsail CLI
run: npm install -g @sprintsail/cli

- name: Authenticate
run: ss login --token ${{ secrets.SPRINTSAIL_TOKEN }}

- name: Set target
run: |
ss org set ${{ vars.SS_ORG }}
ss space set production

- name: Deploy
run: ss push

GitLab CI

deploy:
stage: deploy
image: node:22
script:
- npm install -g @sprintsail/cli
- ss login --token $SPRINTSAIL_TOKEN
- ss org set $SS_ORG
- ss space set production
- ss push
only:
- main

Webhook Deployments

Sprintsail exposes a webhook endpoint for custom CI systems:

curl -X POST https://api.sprintsail.com/api/v1/webhooks/deploy \
-H "Authorization: Bearer $SPRINTSAIL_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"app": "my-api",
"org": "acme-corp",
"space": "production",
"image": "{account}.dkr.ecr.{region}.amazonaws.com/my-api:v1.2.3"
}'

12. CLI Reference (Quick)

CommandDescription
ss loginAuthenticate via browser (PKCE flow)
ss logoutClear stored tokens
ss whoamiShow current identity and org
ss orgsList organizations
ss org create <name>Create a new organization
ss org set <name>Switch active organization
ss spacesList spaces in current org
ss space create <name>Create a space
ss space set <name>Switch active space
ss create <app>Create a new application
ss pushBuild and deploy current directory
ss appsList apps in current space
ss info <app>Show app details
ss logs <app>Stream application logs
ss scale <app>Scale instances or resources
ss autoscale <app>Configure horizontal autoscaling
ss env <app>List environment variables
ss env set <app> KEY=VALSet environment variable
ss marketplaceBrowse available services
ss create-service <type> <plan> <name>Provision a service
ss bind-service <app> <svc>Bind service to app
ss servicesList service instances
ss domains <app>List mapped domains
ss map-domain <app> <domain>Map custom domain
ss deployments <app>View deployment history
ss rollback <app>Rollback to previous version
ss stop <app>Scale to zero
ss start <app>Resume a stopped app
ss restart <app>Rolling restart
ss delete <app>Delete app and resources

For the full CLI reference, see CLI Reference.


13. API Reference (Quick)

All API endpoints are available at https://api.sprintsail.com/api/v1/.

Authentication: Authorization: Bearer <id_token>

MethodEndpointDescription
GET/orgsList your organizations
POST/orgsCreate organization
GET/orgs/:slug/spacesList spaces
POST/orgs/:slug/spacesCreate space
GET/orgs/:slug/spaces/:name/appsList apps
POST/orgs/:slug/spaces/:name/appsCreate app
POST/orgs/:slug/spaces/:name/apps/:app/deployDeploy app
GET/orgs/:slug/spaces/:name/apps/:app/logsStream logs (WebSocket)
PUT/orgs/:slug/spaces/:name/apps/:app/scaleScale app
GET/orgs/:slug/spaces/:name/servicesList services
POST/orgs/:slug/spaces/:name/servicesCreate service
POST/orgs/:slug/spaces/:name/services/:svc/bindBind to app

For the full API reference, see API Reference.


14. Troubleshooting

Build Failures

"No buildpack detected"

  • Ensure your project has the correct detection file (package.json, requirements.txt, go.mod, etc.) in the root directory
  • If using a monorepo, set the build context: ss env set my-api BUILD_PATH=./services/api

"Build timed out"

  • Default build timeout is 15 minutes
  • Large dependency installs (Java, .NET) may need more time — contact support

Deployment Failures

"CrashLoopBackOff"

  • Your app is crashing on startup. Check logs: ss logs my-api --recent
  • Common causes: missing environment variables, incorrect PORT, database not reachable

"ImagePullBackOff"

  • The container image couldn't be pulled. Verify the image exists and the registry is approved

"OOMKilled"

  • Your app exceeded its memory limit. Scale up: ss scale my-api --memory 512Mi

Service Binding Failures

"Service not ready"

  • Database provisioning takes 3-5 minutes. Wait and retry: ss services to check status
  • If stuck in "provisioning" for more than 10 minutes, contact support

DNS/TLS Issues

"Certificate pending"

  • DNS propagation can take up to 5 minutes. Verify your CNAME record is correct
  • If using Cloudflare, ensure proxy is disabled (DNS-only mode) for the CNAME

15. Limits and Quotas

ResourceDefault LimitAdjustable
Apps per space25Yes
Instances per app10Yes
CPU per instance2 vCPUYes
Memory per instance2 GiBYes
Service instances per space10Yes
Custom domains per app5Yes
Build timeout15 minutesNo
Source upload size500 MBNo
Environment variables per app100No
Log retention15 daysNo

Limits are enforced via Kubernetes ResourceQuotas and LimitRanges at the namespace level.


Next Steps