☁ CloudJod

Apps

Deploying from Git, a folder or an image, and everything an app's page does: builds, releases, settings, scaling, commands, domains and who can open it.

An app is one program that runs: a website, an API, a background worker. Its page in the dashboard has a tab for each part of running it. This guide goes through them in the order you are likely to need them.

Getting code in

The Deploy tab has three ways, and you can switch between them at any time:

Builds

A repository with a Dockerfile is built from it. Without one, CloudJod looks at what is there and writes one for you: Go, Ruby, Python, Node, or a static site, tried in that order. The build log starts by saying which it chose and what it assumed (for example, that there was no lockfile, so dependency versions were resolved at build time). If it guesses wrong, choose the right one under How it is built on the Deploy tab; a Dockerfile still wins over both.

Builds run in a sandbox of their own, and their full output is on the Builds tab. A build that fails changes nothing that is running. How many builds can run at once depends on your plan.

Releases and rolling back

Every deploy makes a numbered release. New copies of the app are started and must pass the health check before they get traffic, and only then are the old ones stopped, so a deploy does not take the app down. The Releases tab lists them all; Roll back to this returns to an earlier release in one step.

Settings and secrets

The Environment tab holds the variables your app reads: API_KEY, FEATURE_FLAGS, and so on. Each value can be sealed, and new values are sealed unless you untick the box. A sealed value is encrypted and cannot be read back by anybody, including you, through the dashboard or the API: to change it, set it again.

Several processes from one app

An app is often more than the part that answers web requests. A Procfile in your repository declares the rest:

web: bundle exec puma -C config/puma.rb
worker: bundle exec sidekiq
release: bundle exec rake db:migrate

web is the process that gets traffic. release runs before each release goes live (below). Every other line is a process of its own, scaled separately on the Processes tab. Each line is run by /bin/sh, so the image needs a shell; buildpack builds always have one.

The Containers tab adds containers inside each copy of the app: an init container that runs to completion before the app starts, or a sidecar that runs beside it.

Scaling

On the Scaling tab, Size and count sets how many copies run and how much CPU and memory each may use. The Policy above it decides whether the platform moves them for you:

manualNothing moves: the app stays as you set it.
cpuThe number of copies moves between a minimum and a maximum with how busy they are.
clauderWith the requests the app is answering, the size of each copy moves first, then the number of copies, between the bounds you set. The sizes are xs (0.25 CPU, 256 MiB), s (0.5, 512 MiB), m (1, 1 GiB), l (2, 2 GiB) and xl (4, 4 GiB).

Resizing restarts the app's copies one by one. Everything an app uses counts against your plan while it runs. The same tab chooses where it runs.

One-off commands and the release command

The Commands tab runs a command once, in a container made from the app's current release, with its variables, its databases and its network: a migration, a backfill, creating the first admin. Its output and exit status are kept, so you can see later whether it worked.

A release command runs before every release goes live. If it fails, the new release is not promoted and the previous one keeps serving. That is the safe place for database migrations: the new code never meets the old schema.

Scheduled commands

The Cron tab runs a command on a schedule, written as the usual five fields (0 3 * * * is three in the morning), in the time zone you choose. Each run works like a one-off command, with its output kept. Run now runs one immediately without changing its timetable.

Logs and usage

The Logs tab shows what every copy prints, live. To see how much each copy is using, and whether any were stopped for running out of memory, use cloudjod usage APP. A copy that sits near 100% CPU is being held to its size and would go faster with more.

Your own domain

Every app has its address under cloudjod.com. To serve it at your own as well:

  1. On the app's Domains tab, add the hostname, such as shop.example.com.
  2. At your DNS provider, publish the TXT record the tab shows, named _cloudjod-challenge.shop.example.com. It proves the domain is yours.
  3. Point the hostname at your app: a CNAME record to the app's own address (<app>.<organization>.cloudjod.com), or, for the bare root of a domain, which cannot have a CNAME, an A record to the IP address that name resolves to.
  4. Press Check DNS. Once it shows verified, a certificate is issued for the hostname and it is served over HTTPS.

How many domains you can add depends on your plan.

Who can open it

The HTTP tab decides who reaches the app:

PublicAnyone on the internet.
Team onlyAnyone can reach the sign-in page, but only people in your organization who sign in get through. Use it for internal tools instead of a shared password.
PrivateNot on the internet at all. Your other apps reach it as <app>.internal, and your team's VPN devices reach it at its usual address.

The same tab can put a password (HTTP basic authentication) in front of the app, add response headers, and limit the size of request bodies. These apply to every hostname the app serves, your own domains included.

Files and storage

Files an app writes inside its container are lost when the container is replaced, which happens at every deploy, restart and resize. Keep data in a database. Software that needs a disk of its own, such as WordPress, gets one from its one-click template: the disk outlives every deploy, belongs to one copy of the app, and counts against your plan's storage even while the app is stopped.

Preview environments

When you connect a repository, you can tick Build a preview environment for each pull request. Each pull request then gets its own copy of the app at its own address, built from the proposed branch and updated with each push, and closing the pull request removes it. A pull request from a fork never gets one, because the copy would run somebody else's code with your app's settings and secrets.

Stopping, restarting and deleting

The buttons at the top of the app's page stop it (nothing runs and nothing is used, apart from storage), start it again, restart every copy, and delete it. Deleting removes its containers and their disks.

Next: Databases