Skip to content

Search docs

Search the Skiffly documentation

Variables & references

Service variables, shared variables, `${{Service.VAR}}` references between services, and the SKIFFLY_* built-ins every container gets.

Variables are stored per environment, either for one service or shared by every service in the environment. Service variables win over shared ones with the same name. Values are encrypted at rest and injected into the container as environment variables at deploy time.

Service → Variables. Shared variables live under the environment's Shared variables. The raw editor accepts .env-style text for bulk edits.

References#

A value can point at another variable instead of repeating it:

SyntaxMeaning
${{Postgres.DATABASE_URL}}variable DATABASE_URL of the service named Postgres (name, slug or id all work)
${{shared.REGION}}shared variable REGION of the environment
${{Postgres.SKIFFLY_PRIVATE_DOMAIN}}a built-in of another service
https://${{self.SKIFFLY_PUBLIC_DOMAIN}}self: the service that owns the variable (also in templates and @skiffly/config)
https://${{SKIFFLY_PUBLIC_DOMAIN}}no scope: the same as self; an unknown name without a scope is left as literal text

References resolve at deploy time, recursively (a variable that references a variable that references a built-in works). Each service is rendered with its own environment, so the same reference gives the staging database in staging and the production one in production. Unresolvable references become an empty string and a warning in the deployment log.

skiffly variables set 'DATABASE_URL=${{Postgres.DATABASE_URL}}' 'REDIS_URL=${{Redis.REDIS_URL}}'

The templates for Postgres, MySQL, Redis and MongoDB already expose DATABASE_URL, MYSQL_URL, REDIS_URL and MONGO_URL built from their own credentials and private hostname, so an app usually needs one reference per database.

Built-in variables#

Every container gets these, and other services can reference them:

VariableValue
PORTthe port the service must listen on
SKIFFLY_PUBLIC_DOMAINfirst public domain of the service (api-x1y2.skiffly.cloud or a verified custom domain); unset without a domain
SKIFFLY_PRIVATE_DOMAINhostname on the private network (api)
SKIFFLY_SERVICE_NAME, SKIFFLY_SERVICE_IDservice name and id
SKIFFLY_PROJECT_IDproject id
SKIFFLY_ENVIRONMENT, SKIFFLY_ENVIRONMENT_IDenvironment slug (production, pr-42) and id
SKIFFLY_DEPLOYMENT_IDid of the running deployment
SKIFFLY_GIT_COMMIT_SHAcommit that was built (repository services)

SKIFFLY_DEPLOYMENT_ID and SKIFFLY_GIT_COMMIT_SHA exist only on the service itself. PORT and SKIFFLY_PUBLIC_DOMAIN can also be referenced from another service — ${{api.SKIFFLY_PUBLIC_DOMAIN}} resolves to the first public domain of api in the same environment (${{api.PORT}} to its port) at the time the referencing service is deployed; without a domain the reference resolves to an empty string and the deployment log warns about it. Adding a domain to api later does not update web until web is redeployed.

Secrets#

Variables are stored encrypted (AES-256-GCM) and shown in the dashboard only to workspace members. The CLI masks values in tables and prints them only with --kv/--json; the MCP server's list-variables returns names unless the agent asks for values. In config as code use preserve() and generate() so secrets never end up in the file.