Menu
Platform
AI
App store purchases
Database
Flags
Jobs and cron
Localization
Monitoring
Notifications
Payments
Queues
Sandboxes
Webhooks
Getting Started
Authentication
KV Store
Deploy & Infrastructure
Reference
Configuration
The spec of a Service, field by field, and the two ways to change it.
Today this runs on the management API
A service's variables are changed on the management API: GET, POST ({"key","value"}), PATCH and DELETE (?key=) on /v1/projects/{id}/services/{name}/env. Its size and port are PATCH /v1/projects/{id}/services/{name} (for example {"instanceType":"nano"}). The sylphx hosting services update commands below show the resource-model spelling of the same settings. The Hosting quickstart has the full sequence.
Everything a Service is, is its spec. This page is the spec, field by field, with the reason to touch each one.
#Environment variables
Two fields, and the difference between them is where the value lives:
| Field | Type | What it is |
|---|---|---|
env | map<string, string> | Plain environment variables, in the spec and readable by anyone who can read the Service. For a URL, a feature flag, a log level. |
secret_env | map<string, string> | Variable name to Secret name. The platform resolves the value at instance start; the value never enters the spec. |
A secret is created once, and named from as many Services as need it:
sylphx secrets secrets create --parent orgs/acme/projects/shop/envs/production \
--meta.display-name SHOP_DATABASE_URL shop-database-url
sylphx secrets secret-versions create \
--parent orgs/acme/projects/shop/envs/production/secrets/shop-database-url \
--payload "$DATABASE_URI"sylphx hosting services update orgs/acme/projects/shop/envs/production/services/shop \
--spec.secret-env DATABASE_URL=shop-database-urlcurl -X PATCH "https://api.sylphx.com/v1/orgs/acme/projects/shop/envs/production/services/shop" \
-H "Authorization: Bearer $SYLPHX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"service": {"name": "orgs/acme/projects/shop/envs/production/services/shop", "spec": {"secret_env": {"DATABASE_URL": "shop-database-url"}}}}'A secret never goes in env
env is stored in the spec and read back by anyone with hosting:read — it
is the wrong place for a password, a token or a connection string with
credentials in it. If the value would be embarrassing in a screenshot, it is
a Secret.
Rotating a secret is a new version of the Secret; the Services bound to it pick it up on their next instance start. Nothing about it is copied into the spec, so there is nothing to update twice.
#Where the code comes from
| Field | Type | What it is |
|---|---|---|
source.source_link | string | Build from this SourceLink’s repository on every push to branch. |
source.image | string | Run an Artifact by digest: registry.sylphx.net/<path>@sha256:<hex>. No build, and branch is ignored. |
source.branch | string | The branch that ships to this Service. The SourceLink’s production branch by default. |
source.build.root_directory | string | The directory inside the repository to build; the root by default. |
source.build.dockerfile | string | A Dockerfile path relative to root_directory. Unset lets the zero-config frontend detect the stack. |
source.build.build_class | string | The Build class, sylphx-<os>-<size>; sylphx-linux-standard by default. |
command | string | Overrides the image’s command — a worker runs its process here rather than on a port. |
Everything about the build that is not in the spec is in the repository. A Service does not carry its own manifest: what it runs is what the source says, and re-declaring the build in two places is how they drift apart.
#How it is exposed
| Field | Type | What it is |
|---|---|---|
port | int32 | The port the application listens on. The public edge stays 443. |
exposure | ServiceExposure | public (default) puts the Service behind the edge; internal keeps it reachable only from inside the environment. |
regions | string[] | Regions to run in; the project’s home region by default. |
An internal Service is how a backend is reached: it has no public host, and a
Route cannot point at it from the edge. Data stays near its users by putting
the Service where they are — the Region you choose for a database and the
regions you choose for the Service that reads it are the same decision made
twice, so make them match.
#Size and scaling
| Field | Type | What it is |
|---|---|---|
size | InstanceSize | nano, micro, small, standard, large, xlarge or xxlarge. The plan’s default when unset. |
scaling.min_instances | int32 | Instances kept running with no traffic. 0 idles to zero and wakes on request. |
scaling.max_instances | int32 | Instances at most. 0 means the plan’s limit. |
sylphx hosting services update orgs/acme/projects/shop/envs/production/services/shop \
--spec.size small \
--spec.scaling.min-instances 0 \
--spec.scaling.max-instances 10Start at zero and raise min_instances only if the cold start is worth
paying for: an instance kept idle serves the first request faster and costs
the same as a busy one.
#Probing
| Field | Type | What it is |
|---|---|---|
health.protocol | HealthProtocol | http or tcp. Required. |
health.path | string | The HTTP path to probe when the protocol is HTTP. |
health.startup_timeout | duration | How long a new instance may take to pass its first probe. |
A tcp probe only asks whether something is listening, which is right for a
worker that has no HTTP surface. An http probe is the one that can tell a
finished boot from a listening socket.
Health checks has the rest.
#Changing a Service
Every field above changes through update, and a change to the spec is a new
generation: the platform builds it, and it ships the way anything else does —
by rolling out. Writing the spec is not the deploy; the rollout is.