Skip to content

Applications ​

An application runs from a container image or from a GitHub repository that Orbit builds on your server.

Deploying ​

  • A deployment waits up to 3 minutes for the application's health check and up to a minute for its certificate. Set ORBIT_HEALTH_TIMEOUT and ORBIT_CERTIFICATE_TIMEOUT (for example 5m) in orbit.service to change either.
  • An application that exits right after starting (a failed migration, a missing variable) fails saying that it stopped right after starting, with its exit code and its last lines, instead of as a health check that never answered.
  • Rollbacks put a previous deployment back, with the resources the application has now.

Addresses and domains ​

  • Generated addresses use sslip.io: <service>-<project>.<server-ip-with-dashes>.sslip.io in production, with the environment's name before the project's elsewhere. They work as soon as the server's ports 80 and 443 are reachable from the internet. Let's Encrypt issues their certificates over HTTP; until it does, the address answers over HTTP.

  • Custom domains need a DNS record at your provider:

    • an A record to the server's IPv4 for a root domain (example.com);
    • a CNAME to the generated address for anything under it (www.example.com).

    Orbit checks every 30 seconds and routes the domain once the record points to the server. Turn off proxying (Cloudflare's orange cloud) until the certificate is issued: Orbit compares the resolved address with the server's, and Let's Encrypt validates over HTTP.

Variables and secrets ​

Variables apply on the next deployment. Secrets are sealed at rest and never shown again after you save them. Connecting a database adds a reference such as DATABASE_URL, whose value Orbit fills in at deploy time.

Logs ​

An application's output appears under Logs within a couple of seconds. Orbit keeps the last 1,000 lines of each service. Values of secret variables and common credential patterns are replaced with •••••••• before anything is stored. Older output is still on the server, until Kubernetes rotates it away:

sh
sudo k3s kubectl -n orbit-<project>-<environment> logs deploy/<service>

Resources ​

An application's memory, CPU and instances change from its Settings, always after a preview.

  • The preview shows what the change reserves on the server against its capacity. It counts 1 GB and 250m CPU for the runtime and everything else placed there, warns when builds lose their room or the new limit is below what the application used in the last 24 hours, and says that several instances on one server are not high availability.
  • Applying: Orbit replaces the instances one at a time. When there is no room for a second instance, it stops the running one first, and the preview says so as downtime. If the new instances do not become ready, Orbit puts the previous values back.

Out of memory ​

An application killed for exceeding its memory limit twice within 30 minutes gets an incident and shows as degraded. The incident shows the restarts, the memory chart with the limit, the incoming traffic and the last deployment, each with its source, and keeps the possible causes apart from the facts. Raising the limit from there goes through the resource preview; Orbit then watches for 10 minutes and resolves the incident if no restart follows. Without a fix, an incident resolves after an hour without restarts.

Autoscaling ​

Scale automatically in the same Settings makes the instances follow CPU, between a minimum and a maximum.

  • Instances are added while their average CPU stays above the target share of the CPU limit, and removed once it has stayed below for 5 minutes.
  • The preview reserves memory and CPU for the maximum, so scaling up never runs out of room, and other changes on that server count the maximum too.
  • Deployments and resource changes keep the number of instances the autoscaler chose, within the new bounds.
  • The service's metrics show an Instances chart, and the timeline lists each time instances were added or removed with the CPU that led to it.
  • Limits: up to 10 instances, a target between 20% and 95%, and scheduled jobs cannot autoscale. All instances run on the application's server, so autoscaling handles load, not the loss of that server.

Under HTTP load on a test cluster, an application went from 1 to 3 instances in under 2 minutes and back to 1 within 10 minutes after the load stopped.

Servers ​

An application runs on one server by default. With more than one server, its Settings has a Servers section to move it to another server or spread its instances across several.

  • Spreading: instances are spread evenly, one per server where possible. Autoscaling keeps spreading the ones it adds.
  • When a server is lost: its instances start again on the other servers. On a three-server test cluster this took about a minute and a half, most of it Kubernetes waiting before it declares the server lost. The other instances keep serving meanwhile.
  • The preview shows how many instances each server would hold at the autoscaling maximum and what stays free, and refuses a server that is not ready, has no room or has another CPU architecture than a built image.
  • Surviving a loss: the preview also simulates losing each chosen server. The others must have room for the instances that would move to them, next to everything already there, including instances of other applications that would move too. If not, it names the server and the missing memory and refuses. Each server then keeps that room, so later changes on it (another application, a database, a resize) cannot take it away, and the Servers page shows how much it keeps.
  • Images: a built image is copied to every chosen server before an instance starts there. Images from a registry are pulled by each server.
  • What it does not cover:
    • with one instance, the application stops until that instance starts on another server, so use two or more;
    • traffic still enters through the main server, so losing the main server makes the application unreachable even while its instances run elsewhere;
    • moving instances needs the cluster's control plane, which runs only on the main server.

Workers and jobs ​

Add a worker or a job from an application's Overview, under Good company. It reuses the application's source and settings with its own name and start command, in the same environment.

  • A worker has no address. Its deployment fails if it restarts or exits within its first 10 seconds.
  • A job runs on its schedule in UTC, or now with Run now. When a run is still going at the next match, that match is skipped. Orbit keeps the last five successful and five failed runs with their output and exit code, and the job shows as degraded while its latest run failed. A new schedule applies on the next deployment.
sh
sudo k3s kubectl -n orbit-<project>-production get cronjobs,jobs,pods
sudo k3s kubectl -n orbit-<project>-production logs job/<run>

Builds ​

  • An application from a repository is built on the server for every deployment of a new commit. Redeploying the same commit with the same settings reuses its image.
  • The first build of each stack downloads its base images: expect a few minutes for Next.js or Nuxt and less than a minute for small Go, Python or static sites. Later builds of the same project are faster.
  • Builds run on the main server, next to your applications. A Next.js or Nuxt build can use 1.5 GB of memory for a minute or two, so a 2 GB server should not build while it is short on memory.
  • Each service keeps its ten most recent images, and the build cache trims itself as the disk fills.

Orbit by Cortex Labs