Skip to main content

Deployment System

The deployment system is the main feature in DOM Cloud. It let's you to perform automatic configuration all by convenience of a single script. It's also can be used as a CI (Continous Integration) tool that perform some tasks inside your website.

The deployment system is accessible through Deploy tab in the website menu.

For common script deployments, there's existing recipes from the deployment page or recipe repository.

We try to make it as simple as possible to understand. We also make our backend processing open sourced so you take a better view of how it works if you want that.

The script runner is in YAML format. Here's a simple overview:

source: # Source URL from internet to replace all files in "public_html"
features: # List of features to be enabled or configured or disabled
nginx: # NGINX configuration to be set for current website
commands: # List of terminal commands that will be executed inside "public_html"

Each of these keys are explained in details below.


Source URL from internet to replace all files in ~/public_html. Common examples:

# Clones to  "~/public_html"
# Download latest WordPress and extracts it from "wordpress" folder
directory: wordpress
# Removes all files and directories in "~/public_html"
source: clear

Type: string or object. If it a string, it will be the url.

If this value is set, it will download contents inside the host. The content can be either a ZIP file or a Git repository (to perform clone), or clear to simply clears the content.


This option is useful if your files is already in a public repository such as GitHub. If you need to upload the files from your local device use Webmin File Manager.


This option will always overwrite all contents inside the host. Use with caution.


The zip (or clone) URL to download. Required.


To extract a ZIP file or clone a repo. If omitted, it autodetects whether it is a or URL and perform clone instead of extract.

directory (type: extract only)

Specify the folder name to move out of ZIP file after extraction. This also can be specified from url's hash. If omitted, no move operation performed.

For legacy reason, a directory in root config will works too, it will be converted as

branch (type: clone only)

Specify the clone branch to get checked out. This also can be specified from directory or url's hash. If omitted, the default branch is checked out.

shallow (type: clone only)

Do shallow clone? Default to true. It is recommended to leave it that way to keep .git internal size low.

submodules (type: clone only)

Do Recursive clone of submodules? Default to false.


Enable, configure or disable one or more features in the website. Common examples:

# Enable MySQL and PostgreSQL
- mysql
- postgresql
# Install latest Node.js and Python in the server
- node
- python
# Ask for a new TLS certificate from let's encrypt
- ssl

Type: Array of string or object. If one item is a string, it will be converted to object (.e.g. mysql on become { mysql: on }).

This configures all features available for the host in DOM Cloud.


Configure MariaDB (MySQL) Database Server.

  • mysql or mysql on Enable MariaDB and create default DB.
  • mysql create <dbname> Create a new database with <dbname>.
  • mysql drop <dbname> Drop a database with <dbname>.
  • mysql off. Disables mysql feature. Caution: Also drop all DB permanently.


Configure PostgreSQL Database Server.

  • postgresql or postgresql on Enable PostgreSQL and create default DB.
  • postgresql create <dbname> Create a new database with <dbname>.
  • postgresql drop <dbname> Drop a database with <dbname>.
  • postgresql off. Disables postgresql feature. Caution: Also drop all DB permanently.


Configure BIND DNS Server.

  • dns or dns on Enable DNS server.
  • dns add <type> <value> Add a record.
  • dns rem <type> <value> Deletes a record.
  • dns off. Disables dns feature. Caution: Also clears all DNS records.

You can add multiple records with lists. For example:

- dns:
- add a sub-a
- add aaaa sub-a 2001:1:2:3:4:5:6:7
- add cname sub-b
- add cname sub-c

DNS records for child server is handled automatically.


When applying CNAME, looks out for the trailing dot (.) at the end of CNAME values.

It is required to specify the root domain, otherwise it will be appended with the parent domain.


DNS records is also configurable via Webmin DNS.


Configure Whitelist Firewall.

  • firewall on or firewall Enable firewall.
  • firewall off Disable firewall.

Firewall is an additional protection to make sure the host won't send any outgoing request not defined in the whitelist.

It's intended for use of hosts with low security measures. It's recommended for any host who doesn't use any third-party API.


Please note due to obvious PHP weakness in security, it's advised to turn on this feature for WordPress or any weakly protected PHP server.


Configure SSL or Attempt to renew SSL certificate with Let's Encrypt.

  • ssl or ssl letsencrypt, renew SSL certificate with Let's Encrypt.
  • ssl always Always redirect HTTP to HTTPS
  • ssl on Enable both HTTP to HTTPS
  • ssl off Disable HTTPS access (not recommended)


Configure HTTP version for HTTPS.

  • http 1 use HTTP version 1
  • http 2 use HTTP version 2


Set directory root path. This also changes the root directive in NGINX config.


root is configurable both in features: and nginx:. The following is equivalent:

- root: public_html/public
root: public_html/public


Set PHP (FastCGI) version. Available options:

  • php 7.4
  • php 8.0
  • php 8.1
  • php 8.2
  • php latest (default)

Remember that php 8.x is an active release.

This also sets the php (and composer) to the right version in CLI/SSH.

PHP files that served through NginX are served with php-fpm (FastCGI Process Manager).


Install specific NodeJS version. Available options:

  • node or node latest
  • node lts
  • node beta
  • node x.y.z
  • node off

By default it's Node 16.x provided from system.

This also sets the node (and npm, yarn, etc.) to the right version in CLI/SSH. This installation is powered by webi.


Install specific Python version. Available options:

  • python or python latest
  • python lts or python stable
  • python x.y
  • python x.y.z
  • python off

By default it's Python 3.9 provided from system.

This also sets the python (and pip) to the right version in CLI/SSH. This installation is powered by pyenv.


Install specific Ruby version. Available options:

  • ruby or ruby latest
  • ruby lts or ruby stable
  • ruby x.y.z
  • ruby off

By default it's Ruby 3.0 provided from system. This installation is powered by rvm.


Install specific Deno version. Available options:

  • deno or deno latest
  • deno beta
  • deno x.y.z
  • deno off

There's no default Deno version provided from system.

This installation is powered by webi.


Install specific Go version. Available options:

  • go or go latest
  • go x.y.z
  • go off

There's no default Go version provided from system.

This installation is powered by webi.


Install specific Rust version. Available options:

  • rust or rust latest
  • rust x.y.z
  • rust off

There's no default Rust version provided from system.

This installation is powered by rustup.


Configures NGINX for a given website. Common examples:

# Standard NGINX setup for PHP framework 
root: public_html/public
fastcgi: on
- match: /
try_files: $uri $uri/ /index.php$is_args$args
# Standard NGINX setup for Node.js via GLS
root: public_html/public
enabled: on
app_start_command: env PORT=$PORT node server.js
# Standard NGINX setup for Python through WSGI
root: public_html/public
enabled: on
python: .pyenv/shims/python
- python # This install python to .pyenv/shims/python
- echo "from app import app as application" >

All configurations below are not preserved at each config update. It's recommended to use the NGINX tab in the dashboard to reconfigure NGINX.


Whether to enable or not enable PHP file execution: on, always or off. If omitted, off is the default.


Read more about fastcgi option in Deployment for PHP.


List of error pages command. It's particularly useful for static websites. Read on the NGINX docs.

  • 404 /404.html: Show 404 error page as 404.html.
  • 404 =200 /200.html: Assume 404 error as 200 OK and show 200.html (SPA).
  • 500 502 503 504 /50x.html: Show 50x error as 50x.html.


If you want to run Non-PHP apps, you need to setup with Passenger Phusion. Passenger is an additional layer on top of NGINX to run any non-PHP apps.

To enable non-PHP apps, at minimum you need these configuration:

root: public_html/public
enabled: on
app_start_command: node server.js --port=$PORT

The configuration above will execute node server.js --port=$PORT in the parent of root folder (in this case, ~/public_html). Note that you always need to pass the $PORT and use that as the port where your app is listening to. If your app accept port from environment instead you can use env like env PORT=$PORT node server.js.

For custom environment values you can leverage app_env and env_var_list.

To restart a non-PHP apps you can execute passenger-config restart-app / in CLI/SSH. You can also make it always restart if you have to.

Available options:

  • enabled: on or off (default)
  • app_env: environment setup. Either production (default) or development.
  • env_var_list: array of environment values in the format of KEY=VALUE.
  • app_start_command: Passenger GLS command to start the app with $PORT as the port where your app is listening to.
  • friendly_error_pages: on (default) or off
  • base_uri: base URL for the app (default is /).
  • sticky_sessions: on or off (default). Enable this for websocket support.
  • document_root: path to public document root (default is root). This value is relative to the user $HOME folder.
  • app_root: path to app root (default is parent of root). This value is relative to the user $HOME folder.

For non-GLS (an alternative way if not using app_start_command) these options are available too:


Read more about passenger option for general app in NGINX and App daemon.


Array objects which one or more of:

  • match: Matching URL location (required)
  • root: Root path (relative to $HOME)
  • alias: Alias path (relative to $HOME)
  • rewrite: Rewrite URL directive
  • try_files: Try files URL directive
  • return: Return code directive
  • fastcgi: (same as above)
  • passenger: (same as above)

Please read NGINX Location directive for more information.


proxy_pass, although it's popular, it's not allowed because it's not a good practice to use it in a shared servers. You must use passenger instead.


Type: array of string.

List of SSH commands in sequence. The starting directory is always ~/public_html. If any exit code detected to be not zero, the execution chain stop.

This is where all the terminal commands written, for example to install depedencies, compiling binaries or injecting database credential.

The list of commands is always executed after the source and features and before nginx.

Builtin envar for commands

Aside with the usual SSH commands, it does have an additional envar to help with scripting:

  • $USERNAME: The username.
  • $DATABASE: The database name (usually ${USERNAME}_db but can be changed if new database name is supplied before).
  • $PASSWORD: The user login password.
  • $DOMAIN: The domain name.

These envars also will be set:

  • CI=true
  • DEBIAN_FRONTEND=noninteractive
  • LANG=en_US.UTF-8
  • LC_ALL=en_US.UTF-8

Builtin Git Credentials

If you have logged in with GitHub with repo access, an envar $GITHUB_TOKEN will be available for you to use. Together with Git Credentials API, it will grant the access to your private repos along with all git commands run from the Runner.

This is useful for cloning or pulling private repos after a webhook is received, for example.


This does have security implication and we have taken some security measures to prevent leaks. For example, since it's provided within envar, you git commands will break if run within SSH. That's because its doesn't saved anywhere in the server.

We doesn't prevent you, for example to run echo $GITHUB_TOKEN in the commands list and use it as the token used for SSH session. But we do recommend you to not do that.

Time limit

The time limit for overall script in single run is 10 minutes. If it's exceeded, the execution chain will automatically stop by signaling both SIGTERM and SIGKILL.

subdomains and subdomain

subdomains is used to run specific commands for a given subdomain name. It's an array of objects with subdomain, some of the features and commands keys.

When subdomains are used, some definitions such as source, nginx, features and commands is adjusted to apply for a given subdomain name, including changing the root exection to ~/domains/<subdomain_name>/public_html instead of ~/public_html.