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:
-
A Git repository. Connect it once, and every push to its
branch builds and releases the app. GitHub, GitLab, Gitea, Forgejo and
Bitbucket are built in; Other is for anything that can send an
authenticated web request, such as a
post-receivehook or a CI job. Private GitHub repositories work once your organization has given CloudJod access to GitHub under Settings. - A folder from your computer. Packed in your browser, uploaded and built. It waits for you on the Releases tab rather than going live by itself.
- An image somebody already built. Released as it is, pinned to its exact contents.
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.
- Variables are given to the app when its containers start, so a change reaches a running app at its next deploy, or when you press Restart.
- A connected database's connection string is added when the app deploys, and is not listed on this tab. See Databases.
- The app is always given
PORT, the port it should listen on.
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:
manual | Nothing moves: the app stays as you set it. |
|---|---|
cpu | The number of copies moves between a minimum and a maximum with how busy they are. |
clauder | With 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:
- On the app's Domains tab, add the hostname, such as
shop.example.com. -
At your DNS provider, publish the TXT record the tab shows, named
_cloudjod-challenge.shop.example.com. It proves the domain is yours. -
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. - 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:
| Public | Anyone on the internet. |
|---|---|
| Team only | Anyone 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. |
| Private | Not 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