Skip to main content

Deployments · When a deploy won't start

When a deploy won't start

Your build passed, but the app stopped while starting. The console reads what your app printed and names the settings it lacked, so you can add them and redeploy without hunting through logs.

What you see​

When a start fails and the cause is a missing setting, the deploy page shows a card with:

  • A sentence naming what the app lacked, like "It stopped while starting: MONGO_URI isn't set."
  • Where your code reads it, as a file and line, when your app's own error says so.
  • For each missing setting, where its value can come from: a value you type, a secret, a data service in the project, or a key ComputeSphere can generate.
  • Other names your repository reads that nothing sets yet.

Two buttons sit on the card: Add missing variables and Show the lines. Show the lines opens the part of the runtime log the cause was read from.

The same sentence is in the failure notice and its email. See Notice and email.

If your app didn't say which settings it lacked, the card stays as it was: the failure reason and a pointer to the logs.

Add the missing variables​

  1. On the deploy page, click Add missing variables.
  2. The service's variables editor opens with the names already filled in. It opens on the Secrets tab when any of the names is a secret.
  3. Type a value for each name. For SECRET_KEY, FERNET_KEY and APP_KEY, the editor makes a value for you, in the right format, and shows it only to you.
  4. Save, then redeploy. See Applying a change.

A name that's already saved on the service isn't added twice. A viewer doesn't get the editor.

How it finds the cause​

When a start fails with no cause of its own, ComputeSphere reads that start's runtime log once. It reads up to 200 lines, from when the attempt began, so lines from an earlier attempt don't mix in. It looks for the way your framework reports a missing setting. If it finds one, it records the names.

It keeps names only. It never stores or shows a value.

These are recognized:

LanguageReports it reads
Pythonpython-decouple, django-environ, os.environ["NAME"], pydantic-settings
Nodeenvalid, env-var, NestJS with Joi, a hand-written "NAME is required" message
Gocaarlos0/env, envconfig
RubyENV.fetch
JavaSpring's "Could not resolve placeholder"
.NET"Environment variable 'NAME' is not set" and similar
ElixirSystem.fetch_env!
Rust"NAME must be set"
Laravela missing APP_KEY

It takes upper-case names, plus .NET's Section__Key names such as ConnectionStrings__Default, at most 20 per failure. When your pydantic-settings class uses an env_prefix, the card names the prefixed variable, such as APP_DATABASE_URL, when the repository scan finds it.

The other names on the card come from reading your repository's files, through the same Git connection the service deploys from. Files that look like they hold secrets aren't opened.

A service that keeps restarting​

A spherelet whose process stops and comes back every few minutes reads Restarting when all of these hold:

  • Its process is running now and nothing more specific applies, such as a crash loop or out of memory.
  • It has restarted at least three times.
  • The last restart was within the last 15 minutes.

The card on the service's Overview shows Restarting with a warning tone and this message: "This spherelet keeps restarting: its process stopped and restarted several times in the last 15 minutes. Check its logs to see why it stops." The status of the service reads unhealthy with the same reason. Over the API, the spherelet's reason_code is restarting.

One or two restarts, or old ones, never warn.

The deploy log doesn't list every restart. A loop of Restarting repeatedly and Unhealthy rows for one build and version is one entry that counts the restarts, like Restarting repeatedly · 41 times since 10:02. The first and last restart bound it. A different version, a gap longer than 10 minutes or any other event in between starts a new entry.

Notice and email​

When a start fails, you get a bell notification and, if you've turned on failure email in your notification settings, one email. Once ComputeSphere knows the cause, the notice names it:

CaseTitleBody
The version that serves keeps crashingapi keeps crashing: MONGO_URI isn't set.Add it in Variables, then redeploy.
A new version didn't start, the previous one still runsapi: the new version didn't start: MONGO_URI isn't set.Your previous version is still running. Add it in Variables, then redeploy.

With more than one name, the body reads Add them in Variables, then redeploy. The title lists up to three names, then and N more, like A, B, C and 2 more aren't set.

The notice and the email link to the deploy page. The email's button reads Open the deploy page.

The cause takes a moment to read. The email waits up to two minutes for it, so the email you get carries the cause. If the cause isn't known by then, the email goes out as it is. It's one email either way. If the service runs again inside the wait, no failure email is sent.

New service: names the app can't start without​

When you create a service from a repository you picked through a Git connection, What your app needs reads the repository before the first deploy. Some reads can't work without a value: the app stops if the variable isn't set.

For those names, the page shows Your app needs these before it can start: with one box per name, labeled like STRIPE_SECRET_KEY (read in app/billing.py). A secret's box hides what you type, with Show value and Hide value. What you type goes into the service's variables.

Deploy waits while any of these boxes is empty. Its reason names the first one: Fill in STRIPE_SECRET_KEY to deploy. Click it to jump to the box.

If you'd rather deploy without them, click Deploy anyway. The line next to it reads The app will likely stop at start without these settings.

A secret that's linked to a secret manager counts as set. It shows its link and can't be edited here.

A name counts as required only when it's sure:

LanguageRequiredNot required
Pythonos.environ["X"], a decouple config("X") with no default, django-environ env("X"), a pydantic-settings field with no default.get, getenv, anything with a default
RubyENV.fetch("X")ENV.fetch("X", value), ENV["X"]
ElixirSystem.fetch_env!System.get_env
Goenv:"X,required", required:"true" on an envconfig tagother tags
Rustenv::var("X").unwrap() or .expect(…)the rest
Node, PHP and othersnever: a missing read returns emptyall

Every other name the code reads is listed as your code reads it, and doesn't block Deploy.

Honest limits​

  • It reads what your app printed. If your app stops without naming the setting, the card falls back to the failure reason and the logs.
  • One read per attempt. It doesn't re-read the log later.
  • Laravel reports a missing APP_KEY on the first request, not at start. The cause shows once a request has been logged.
  • The new-service check needs a repository picked through a Git connection. A pasted public URL isn't scanned yet.

What's next​