Перейти к содержимому

Поиск по документации

Поиск по документации Skiffly

Сеть

Generated and custom domains with automatic TLS, private networking between services by name, and public TCP proxies for databases.

Generated domains#

Any HTTP service can get a domain under skiffly.cloud with a certificate already issued:

Service → Settings → Networking → Generate domain. The domain looks like api-x1y2.skiffly.cloud and routes to the service port.

Domains are per environment: the same service has different domains in production and staging. Generating twice returns the existing domain. Each domain points at the port the service listens on; the first domain is exposed to the container as SKIFFLY_PUBLIC_DOMAIN.

Custom domains#

  1. Add the domain: Settings → Networking → Add custom domain, skiffly domain app.example.com or customDomainCreate.

  2. Create the two DNS records Skiffly prints:

    app.example.com.            CNAME  edge.skiffly.cloud.
    _skiffly.app.example.com.   TXT    "<verification token>"

    Apex domains (example.com) need a provider that supports ALIAS/ANAME or CNAME flattening; otherwise point an A record at the edge IP 65.109.28.161 (EU-Helsinki; it changes only with a data-plane move announced on the status page). The TXT record alone is enough for verification of an apex domain.

  3. Wait for verification — or press Check now. Skiffly checks the records automatically every 2 minutes during the first day and then hourly for 7 days (CustomDomainStatus.autoCheck: ACTIVE); after that the checks stop (STOPPED) until you press Check now in Settings → Networking, run skiffly domain status app.example.com or call customDomainVerify(id), which also restarts the schedule. DNS changes can take up to 48 hours to propagate. Once the TXT record (and the CNAME, unless the domain is an apex) resolves, the domain is routed, a Let's Encrypt certificate is issued within a few minutes and you get a notification. No redeploy is needed.

    Verified domains are re-checked every 6 hours; if the records disappear for three checks in a row the domain is unverified and you are notified.

skiffly domain app.example.com
skiffly domain status app.example.com     # prints the records and the verification state
skiffly domain delete app.example.com

Every domain is served on both http:// and https://; there is no forced redirect yet, so redirect in the app if you need it (X-Forwarded-Proto is set). Wildcard custom domains are not supported.

Private networking#

Services in the same project and environment share a private network. Each service is reachable at its slug (the lowercase service name; SKIFFLY_PRIVATE_DOMAIN) on its port, no domain needed:

http://api:8080
postgres://postgres:…@postgres:5432/app
redis://redis:6379
  • The private hostname works only inside the environment; production cannot reach staging.
  • Traffic between projects is denied by network policy; the internet is reachable outbound, except port 25.
  • Databases from templates listen on the private network only. ${{Postgres.DATABASE_URL}} already uses the private hostname.
  • Private hostnames resolve to the service's replicas; the port is the service's port, not PORT of the caller.
  • SKIFFLY_PRIVATE_DOMAIN is the full name (api.p-….svc.cluster.local). Use it where the short name is not enough — nginx with an explicit resolver does not search short names; point resolver at ${{SKIFFLY_DNS_RESOLVER}}.

TCP proxies#

Non-HTTP services (Postgres, MySQL, Redis, Mongo, a game server) can be exposed on a public host:port:

skiffly connect postgres          # creates a proxy after confirmation and opens psql
skiffly proxy add --port 5432     # edge.skiffly.cloud:2xxxx → container port 5432
skiffly proxy list
skiffly proxy delete 21543

The proxy is edge.skiffly.cloud:<port> with a unique port in 20000–29999, applied to a running service immediately (syncStatus: ACTIVE; CREATING until the first deployment). Traffic goes straight to the container without TLS, so the service must require a password. Up to five proxies per service and environment. A service with a TCP proxy cannot use App Sleeping.

Limits and Under Attack Mode#

Every request passes a per-client limit at the edge before it reaches your service: up to 100 requests per second from one IP (bursts up to 300) and 256 requests in flight; over the limit the client gets 429 Too Many Requests. One address can hold up to 256 connections and open 100 new ones per second; TCP proxies allow 64 connections and 20 new ones per second per address. A request body must finish uploading within 5 minutes, and an idle keep-alive connection is closed after 60 seconds. Your service sees the visitor's real address in X-Real-Ip and X-Forwarded-For. Generated *.skiffly.cloud domains are served through Cloudflare, which caps a request body at 100 MB and expects the response to start within 100 seconds; use a custom domain for bigger uploads or longer requests.

When a service is being flooded, turn on Under Attack Mode in Settings → Networking, or from the CLI:

skiffly waf under-attack enable --service web --duration 1h
skiffly waf under-attack status --service web
skiffly waf under-attack disable --service web

While it is on, every client of the service is limited to 5 requests per second and 10 in flight, and on its *.skiffly.cloud domains new visitors pass a browser check first — scripts, bots and API clients are turned away there. It applies within seconds, without a redeploy, and switches off by itself after 1, 3, 12 or 24 hours, or stays on until you turn it off. It is meant for an active incident: an API that must keep serving non-browser clients should rely on the per-IP limit alone. API: serviceInstanceUnderAttackEnable(serviceId, environmentId, duration), serviceInstanceUnderAttackDisable, ServiceInstance.underAttack.

Not yet#

Static outbound IPs, a CDN layer, wildcard custom domains and email forwarding do not exist. Outbound traffic leaves from the node's IP.