Deployment Guide for Infrastructure Providers Using EzyPlatform

Updated at 1784275063000
Cloud and VPS providers that want to offer EzyPlatform as a one-click application need a repeatable way to provision it: install the right runtime and database, wire up credentials, start the admin service, and keep it running without a human watching a terminal. This guide walks through a deployment script for Ubuntu/Debian hosts that automates all of that, and explains the auto-restart mechanism it sets up so the admin service recovers on its own if it ever stops responding.

Deployment flow

The script is idempotent: each step checks whether its target is already installed or running before acting, so re-running it on a host that already has EzyPlatform is safe.
flowchart TD
    A[Run install script] --> B[Install OpenJDK, MySQL, Nginx, Certbot]
    B --> C[Start MySQL and Nginx services]
    C --> D[Create EzyPlatform database and user]
    D --> E[Download and extract EzyPlatform]
    E --> F[Write MySQL connection into setup.properties]
    F --> G[Start EzyPlatform admin and web]
    G --> H[Install auto-restart watchdog for admin]
    H --> I[Configure Nginx + TLS for provided domains]
    I --> J[Store admin_url / web_url / websocket_url in the database]
    J --> K[Print database credentials and next steps]

What gets installed

  • OpenJDK 8, falling back to OpenJDK 11 if 8 isn't available in the package repositories
  • MySQL server
  • Nginx and Certbot, so a provider can add a virtual host and TLS afterward
  • unzip and wget, used to fetch and extract the EzyPlatform package
Each package is only installed if it's missing, and Java is skipped entirely if a working `java` binary is already on the `PATH`.

Database provisioning

The script creates a dedicated database and a MySQL user scoped to 'user'@'localhost' — never '%' — so the application account cannot be reached over the network, only from the host itself. The default MySQL package configuration also only listens on the loopback interface, and the script doesn't change that, so MySQL isn't exposed to the internet unless something outside the script (a custom image, a firewall rule) opens it up.
The database password is generated from /dev/urandom, filtered down to alphanumeric characters, at 24 characters long. On a re-run, it reuses whatever password is already sitting in setup.properties instead of rotating it — unless that password is still the packaged default placeholder, in which case it's replaced with a random one. The MySQL root password is only touched if you explicitly pass one in; otherwise the script leaves root's existing authentication method alone.

Starting the admin and web services, and keeping admin up

Once the database and files are in place, the script starts both the EzyPlatform admin and web processes (each skipped if its port is already listening), then installs a watchdog that keeps admin alive going forward.
flowchart TD
    A[systemd starts the watchdog service] --> B[Check script polls the admin port every 120s]
    B --> C{Port responding?}
    C -->|Yes| B
    C -->|No| D[Log the failure with a timestamp]
    D --> E[Restart admin via cli.sh]
    E --> B
The watchdog itself is two small pieces:
  • A polling script that checks the admin port (via /dev/tcp, falling back to ss or curl depending on what's available) every 120 seconds, and restarts the admin process through EzyPlatform's own cli.sh if the check fails. Failures are logged with a timestamp to /var/log/check-ezyplatform-status.log.
  • A systemd unit with Restart=always and RestartSec=10 wrapping that script, so the checker itself comes back if it ever dies, and starts automatically on boot.
This is the same check-script-plus-systemd-unit approach used by EzySupport's own auto-restart feature, an official EzyPlatform admin plugin. Using the same mechanism and naming convention means a provider can hand a server to EzySupport later — from the admin UI — and it will recognize the watchdog this script installed instead of creating a duplicate one.

Custom domains and TLS

By default, admin and web are only reachable by IP and port. If you pass ADMIN_DOMAIN and/or WEB_DOMAIN, the script goes further for each domain provided:
flowchart TD
    A[Domain provided] --> B[Write an Nginx reverse-proxy site for the domain]
    B --> C[Reload Nginx]
    C --> D[Request a certificate with Certbot's Nginx plugin]
    D --> E[Certbot adds the HTTPS block and HTTP-to-HTTPS redirect]
    E --> F[Write the matching *_url setting into the database]
Each domain's DNS A record has to point at the server before the script runs, since Certbot validates ownership over plain HTTP before it will issue a certificate. Once a domain is live, its URL is written straight into the `ezy_settings` table — `admin_url` for `ADMIN_DOMAIN`, and `web_url` plus `websocket_url` for `WEB_DOMAIN` — using an `INSERT ... ON DUPLICATE KEY UPDATE`, so re-running the script with the same domain just refreshes the value instead of erroring out. Those writes go through the same database user created earlier, scoped to `localhost`, using a temporary credentials file rather than a command-line password, so the password doesn't end up visible to other local users in the process list.
The generated Nginx site follows [EzyPlatform's official Ubuntu deployment guide](https://youngmonkeys.org/ezyplatform/guides/deploy-ezyplatform-on-ubuntu): the same proxy headers, a `client_max_body_size`, and, for the admin domain only, a dedicated `/api/v1/media/add` location with buffering disabled so large media uploads stream straight through instead of being held in memory by Nginx first.
The script writes websocket_url for WEB_DOMAIN into the database along with web_url, but it doesn't start or configure the socket service itself — that's intentionally out of scope here.

Configuration

Every value the script needs can be overridden with an environment variable, or for the root password and download URL, with positional arguments:
VariableDefault
DB_NAMEezyplatform
DB_USERezyplatform
DB_PASSWORDrandom 24-character password
MYSQL_ROOT_PASSWORDunchanged, unless passed as the first argument
EZYPLATFORM_DIR<current directory>/ezyplatform
EZYPLATFORM_URLlatest EzyPlatform release, or the second argument
EZYPLATFORM_ADMIN_PORT9090
EZYPLATFORM_WEB_PORT8080
ADMIN_DOMAINunset — falls back to IP:port
WEB_DOMAINunset — falls back to IP:port
CERTBOT_EMAILunset — Certbot registers without a contact email
sudo bash install-ezyplatform.sh
sudo bash install-ezyplatform.sh 'RootPassword123!'
sudo DB_PASSWORD='AppPassword123!' EZYPLATFORM_ADMIN_PORT=9091 bash install-ezyplatform.sh
sudo ADMIN_DOMAIN='admin.example.com' WEB_DOMAIN='www.example.com' CERTBOT_EMAIL='ops@example.com' bash install-ezyplatform.sh

What this script does not do

  • Configure Nginx or request a TLS certificate for domains that aren't passed via `ADMIN_DOMAIN`/`WEB_DOMAIN`
  • Complete the web-based EzyPlatform admin setup wizard — you still open the admin URL once to finish that

Download the script

The full script is provided as a plain-text download rather than inline in this article, so shell syntax like [[ ... ]] or doesn't get mangled by HTML rendering along the way:
Read through it before running it against production infrastructure, and run bash install-ezyplatform.sh --help first to see the current usage, arguments, and environment variables in one place.

Table Of Contents