Skip to content

Files, console and cron

SFTP

The File Access tab shows the host, the port and your username. The password is shown once, right after you set it, and never again.

FieldValue
Hostsftp.itsh.dev
Port2222
UsernameShown on the tab, one per site
AuthenticationPassword only

Port 2222, not 22. Most clients default to 22, and that port answers on this host with a different service, so you get a host-key warning or a rejected login rather than a timeout. A password that is refused with the port left at 22 is a port problem, not a password problem.

Any SFTP client works. FileZilla, Cyberduck and WinSCP are the usual ones, and from a terminal:

bash
sftp -P 2222 <your-username>@sftp.itsh.dev

There are no SSH keys, and no shell

The account authenticates with a password. There is nowhere to upload a public key, and ssh to the same host gives you nothing: the account has no shell. One-off commands go through the console below.

Set or replace the password with Reset password on the same tab. It warns you first:

text
This will terminate any active SFTP sessions. Continue?

A long upload can be interrupted without you doing anything

The SFTP endpoint restarts whenever credentials change, which takes a couple of seconds and drops connections that are open at that moment. Your own password reset is one cause, but not the only one, so a multi-gigabyte upload can die part-way through for no reason visible to you.

Use a client that resumes rather than one that starts over, and check the upload finished before you assume it did.

Where your files go

After connecting you are at the top of your own area. Inside it:

text
site/
  public_html/      <- everything here is served on the web

Only public_html is served. A file you place next to it, not inside it, is kept and is readable by your code, which is where configuration, libraries and anything else that must not be downloadable belong.

An empty site serves a placeholder page reading Your site is ready. Seeing it means the site works and the document root is empty, not that something failed.

Some paths never reach your files

/healthz is reserved on every site and always answers ok. Any path beginning with a dot, such as /.env or /.git/config, is refused with 403 on nginx.

Console

The Console tab runs a single command against your site and streams the output back. It is not a shell session: each run is independent, nothing is remembered between runs, and there is no working directory that persists.

bash
composer install --no-dev
wp core update
php artisan migrate

A dropdown offers ready-made commands for WordPress, Laravel, Flarum, Drupal and Composer.

Available: php, composer, wp (WP-CLI), git, unzip, bash. Anything your project installs itself under vendor/bin works too. The PHP extensions are the same set the website runs with.

LimitValue
Commands at once, per site1
Command length4096 characters
Run time10 minutes, then the command is stopped
Output retainedAbout 1 hour

Start a second command while one is running and you get:

text
a command is already running for this site

Either wait, or use Stop.

Commands run in /app/public_html, which is the same as public_html over SFTP. Set Working directory to run somewhere below it. The field will not take anything else:

text
invalid working directory: working_dir must be /app/public_html or a subdirectory

The console runs beside your site, not inside it

Each command gets its own short-lived container with your files and your database credentials attached. Your website keeps serving while it runs, and a command that crashes does not take the site down. Equally, a command cannot restart your site: for that use Restart site under Actions.

The database credentials are in the environment, so you can use them without typing them:

bash
php -r 'echo getenv("DB_NAME"), PHP_EOL;'

Cron

The Cron tab schedules recurring commands. Same environment as the console, same files, same tools.

Schedules are five fields, in UTC

text
minute hour day-of-month month day-of-week

*/15 * * * * and 30 4 * * 1 are fine. Anything else is not:

  • No seconds field. Six-field expressions are rejected.
  • No shorthand. @daily, @hourly and the rest are rejected.
  • UTC, always. 0 3 * * * runs at 03:00 UTC, which is 04:00 or 05:00 in Germany depending on the time of year. It is unaffected by the site's PHP timezone.

A schedule the parser cannot read is refused when you save:

text
Invalid schedule

Limits

LimitValue
Cron jobs per site5
Cron jobs per account30
Timeout300 seconds by default, 10 to 3600 allowed
Run history3 successful and 3 failed runs, kept 24 hours
text
Maximum 5 cron jobs per site.
Maximum 30 cron jobs per account reached.

The name is a short slug, and it cannot be changed once the job exists:

text
Name must start with a lowercase letter and contain only lowercase letters, digits and hyphens (max 31 characters).

What happens on a run

Each run appears under Runs with its exit code, and Output shows what it printed. Nothing is emailed anywhere.

  • A failed run is not retried. The next scheduled run is the retry, so a job that runs daily and fails has lost a day.
  • Overlapping runs are skipped by default. With the default Forbid, a run starting while the previous one is still going is dropped, not queued. Allow lets them overlap, Replace kills the previous one.
  • A missed window is not made up. If nothing could be started within 30 seconds of the scheduled time, that run is skipped entirely.
  • Output disappears after 24 hours. Anything you need to keep, write to a file under your own directory.

What's next