Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.slipway.sh/llms.txt

Use this file to discover all available pages before exploring further.

slipway resolves ${...} references inside services.*.env and services.*.build.args values at deploy time. Missing references fail the deploy with a clear error before any container starts.

Secrets vs variables

slipway has two stores:
  • Secrets — encrypted at rest with AES-256-GCM. Values are never returned by the API or visible in the UI after creation. Resolved into a per-deployment Kubernetes Secret (sl-env-<dep-id>-<service>) consumed via envFrom: secretRef, so values never appear in the pod spec or in etcd.
  • Variables — plaintext key/value. Readable by anyone with viewer role or above. Useful for non-sensitive config like feature flags, log levels, or registry hosts.
Both have repo scope and org scope. Bare references prefer repo → org; explicit scope references are strict (no fallback).

Substitution syntax

services:
  api:
    build:
      args:
        NPM_TOKEN: ${secret.NPM_TOKEN}               # secret in build.args
        REGISTRY:  ${var.org.REGISTRY}               # explicit org variable
    env:
      DATABASE_URL: ${secret.DATABASE_URL}            # secret: repo first, org fallback
      STRIPE_KEY:   ${secret.repo.STRIPE_KEY}         # explicit repo — strict, no fallback
      DATADOG_KEY:  ${secret.org.DATADOG_KEY}         # explicit org — strict, no fallback
      LOG_LEVEL:    ${var.LOG_LEVEL}                  # variable: repo first, org fallback
FormMeans
${secret.NAME}secret, repo store first, org store as fallback
${secret.repo.NAME}secret, repo store only — fails if missing
${secret.org.NAME}secret, org store only — fails if missing
${var.NAME}variable, repo store first, org store as fallback
${var.repo.NAME}variable, repo store only — fails if missing
${var.org.NAME}variable, org store only — fails if missing
${NAME}deprecated alias for ${secret.NAME}. Emits a warning at deploy time.
Names match ^[A-Z][A-Z0-9_]*$.

Where values land

For each service, slipway materializes:
  • env values → a Kubernetes Secret (sl-env-<dep-id>-<service>) mounted as envFrom: secretRef. Values never appear in the Deployment object, the pod spec, or etcd.
  • build.args values → a separate Secret (sl-buildargs-<dep-id>-<service>) in the build namespace. The buildctl invocation uses shell expansion (--opt=build-arg:K="$K") so values never appear in the build pod’s args.
build.args values that your Dockerfile then echoes (e.g. RUN echo $TOKEN > /etc/secret) will be baked into the resulting image layer. slipway can’t prevent that — keep credentials out of build args unless your Dockerfile consumes them in the same RUN step.

Resolution behavior

  • Both env and build.args resolve through the same syntax.
  • Names referenced but not present in either store fail the deploy at the secrets-resolved phase, before any tenant pod starts.
  • The deploy event log records every resolution. secrets_resolved events list {name, scope, source} per reference — never values. vars_resolved events do include value because variables aren’t secret.

Managing the stores

Both stores are managed through the UI, not the spec:
  • Repo secrets and variables/{slug}/repos/{id}/secrets, .../variables.
  • Org secrets and variables/{slug}/settings/secrets, .../variables.
See Secrets and Variables.