Skip to content

Instantly share code, notes, and snippets.

@tvd12
Last active April 9, 2026 09:54
Show Gist options
  • Select an option

  • Save tvd12/3b0672cd9f7e4f99af8e6ab999048b95 to your computer and use it in GitHub Desktop.

Select an option

Save tvd12/3b0672cd9f7e4f99af8e6ab999048b95 to your computer and use it in GitHub Desktop.
install-ezyplatform.sh
#!/usr/bin/env bash
set -euo pipefail
export LANG=C.UTF-8
export LC_ALL=C.UTF-8
usage() {
cat <<'EOF'
Usage:
bash install-ezyplatform.sh [mysql_root_password] [ezyplatform_download_url]
sudo bash install-ezyplatform.sh [mysql_root_password] [ezyplatform_download_url]
sudo MYSQL_ROOT_PASSWORD='RootPassword123!' bash install-ezyplatform.sh
sudo DB_PASSWORD='AppPassword123!' bash install-ezyplatform.sh
Example:
bash install-ezyplatform.sh
sudo bash install-ezyplatform.sh
sudo bash install-ezyplatform.sh 'RootPassword123!'
sudo bash install-ezyplatform.sh 'RootPassword123!' 'https://ezyplatform.com/api/v1/platforms/latest/download'
sudo bash install-ezyplatform.sh 'https://ezyplatform.com/api/v1/platforms/latest/download'
Environment variables:
DB_NAME Default: ezyplatform
DB_USER Default: ezyplatform
DB_PASSWORD Default: random 24-character password
MYSQL_ROOT_PASSWORD Default: argument 1 if provided, otherwise unchanged
EZYPLATFORM_DIR Default: current directory + /ezyplatform
EZYPLATFORM_ZIP Default: current directory + /ezyplatform.zip
EZYPLATFORM_URL Default: positional URL argument if provided, otherwise
https://ezyplatform.com/api/v1/platforms/latest/download
What this script does:
- Installs OpenJDK 8 (or OpenJDK 11 if 8 is unavailable), MySQL, Nginx, Certbot, unzip, wget
- Optionally configures MySQL root password if provided
- Creates MySQL database/user for EzyPlatform with a DB password from DB_PASSWORD or random_password()
- Downloads and extracts EzyPlatform
- Writes settings/setup.properties for MySQL
What this script does NOT do:
- Configure Nginx virtual host
- Run Certbot setup
- Complete the web-based EzyPlatform admin/web setup
EOF
}
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
usage
exit 0
fi
if [[ "${EUID}" -ne 0 ]]; then
if ! command -v sudo >/dev/null 2>&1; then
echo "This script needs root privileges and could not find sudo."
exit 1
fi
echo "Root privileges are required. Re-running with sudo..."
exec sudo -E bash "$0" "$@"
fi
random_password() {
local length="${1:-24}"
local password=""
while [[ "${#password}" -lt "${length}" ]]; do
password+="$(
tr -dc 'A-Za-z0-9' </dev/urandom | head -c "${length}" || true
)"
done
printf '%s' "${password:0:length}"
}
resolve_db_password() {
local setup_file="${EZYPLATFORM_DIR}/settings/setup.properties"
local existing_password=""
if [[ -f "${setup_file}" ]]; then
existing_password="$(
sed -n 's/^datasource\.password=//p' "${setup_file}" | head -n 1
)"
fi
if [[ -n "${existing_password}" && "${existing_password}" != "12345678" ]]; then
printf '%s' "${existing_password}"
return 0
fi
random_password
}
ARG1="${1:-}"
ARG2="${2:-}"
POSITIONAL_MYSQL_ROOT_PASSWORD=""
POSITIONAL_EZYPLATFORM_URL=""
if [[ -n "${ARG1}" && "${ARG1}" =~ ^https?:// ]]; then
POSITIONAL_EZYPLATFORM_URL="${ARG1}"
else
POSITIONAL_MYSQL_ROOT_PASSWORD="${ARG1}"
POSITIONAL_EZYPLATFORM_URL="${ARG2}"
fi
MYSQL_ROOT_PASSWORD="${MYSQL_ROOT_PASSWORD:-${POSITIONAL_MYSQL_ROOT_PASSWORD}}"
CURRENT_DIR="$(pwd -P)"
EZYPLATFORM_DIR="${EZYPLATFORM_DIR:-${CURRENT_DIR}/ezyplatform}"
EZYPLATFORM_ZIP="${EZYPLATFORM_ZIP:-${CURRENT_DIR}/ezyplatform.zip}"
DB_PASSWORD="${DB_PASSWORD:-$(resolve_db_password)}"
DB_NAME="${DB_NAME:-ezyplatform}"
DB_USER="${DB_USER:-ezyplatform}"
DEFAULT_EZYPLATFORM_URL="https://ezyplatform.com/api/v1/platforms/latest/download"
EZYPLATFORM_URL="${EZYPLATFORM_URL:-${POSITIONAL_EZYPLATFORM_URL:-$DEFAULT_EZYPLATFORM_URL}}"
JAVA_HOME_PATH=""
EZYPLATFORM_ALREADY_EXISTS=0
log() {
printf '\n[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
}
require_command() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "Missing required command: $1"
exit 1
fi
}
is_package_installed() {
dpkg -s "$1" >/dev/null 2>&1
}
is_package_available() {
apt-cache show "$1" >/dev/null 2>&1
}
has_working_java() {
command -v java >/dev/null 2>&1 && java -version >/dev/null 2>&1
}
is_port_9090_listening() {
ss -ltn 2>/dev/null | awk '{print $4}' | grep -Eq '(^|:)9090$'
}
wait_for_mysql() {
for _ in $(seq 1 30); do
if mysqladmin ping --silent >/dev/null 2>&1 || systemctl is-active --quiet mysql; then
return 0
fi
sleep 2
done
echo "MySQL did not become ready in time."
exit 1
}
mysql_exec_root_socket() {
mysql --protocol=socket -uroot -e "$1"
}
mysql_exec_root_password() {
if [[ -z "${MYSQL_ROOT_PASSWORD}" ]]; then
return 1
fi
mysql --protocol=socket -uroot -p"${MYSQL_ROOT_PASSWORD}" -e "$1"
}
mysql_exec_root_default() {
mysql -e "$1"
}
mysql_exec_root_auto() {
if mysql_exec_root_password "$1" >/dev/null 2>&1; then
mysql_exec_root_password "$1"
return 0
fi
if mysql_exec_root_socket "$1" >/dev/null 2>&1; then
mysql_exec_root_socket "$1"
return 0
fi
if mysql_exec_root_default "$1" >/dev/null 2>&1; then
mysql_exec_root_default "$1"
return 0
fi
return 1
}
configure_mysql_root_password() {
if mysql_exec_root_password "SELECT 1;" >/dev/null 2>&1; then
return 0
fi
if [[ -z "${MYSQL_ROOT_PASSWORD}" ]]; then
log "MySQL root password not provided, keeping current root authentication method"
return 0
fi
log "Configuring MySQL root password"
if mysql_exec_root_socket "SELECT 1;" >/dev/null 2>&1 || mysql_exec_root_default "SELECT 1;" >/dev/null 2>&1; then
if mysql_exec_root_auto "ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}'; FLUSH PRIVILEGES;" >/dev/null 2>&1; then
return 0
fi
log "Could not set MySQL root password automatically, continuing with current root authentication method"
return 0
fi
echo "Unable to connect to MySQL as root by socket or provided password."
exit 1
}
create_database_and_user() {
log "Creating MySQL database and user"
mysql_exec_root_auto "CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;"
mysql_exec_root_auto "CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';"
mysql_exec_root_auto "ALTER USER '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';"
mysql_exec_root_auto "GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '${DB_USER}'@'localhost'; FLUSH PRIVILEGES;"
}
install_packages() {
log "Updating apt package index"
apt-get update
local packages_to_install=()
local java_package=""
if has_working_java; then
log "Java is already installed, skipping"
else
if is_package_installed openjdk-8-jre-headless || is_package_installed openjdk-11-jre-headless; then
log "Java package appears installed but 'java' is not runnable; reinstalling Java"
fi
if is_package_available openjdk-8-jre-headless; then
java_package="openjdk-8-jre-headless"
elif is_package_available openjdk-11-jre-headless; then
java_package="openjdk-11-jre-headless"
else
echo "Could not find openjdk-8-jre-headless or openjdk-11-jre-headless in apt repositories."
exit 1
fi
log "Selected Java package: ${java_package}"
packages_to_install+=("${java_package}")
fi
if command -v mysql >/dev/null 2>&1 || is_package_installed mysql-server; then
log "MySQL is already installed, skipping"
else
packages_to_install+=(mysql-server)
fi
if command -v nginx >/dev/null 2>&1 || is_package_installed nginx; then
log "Nginx is already installed, skipping"
else
packages_to_install+=(nginx)
fi
if command -v certbot >/dev/null 2>&1 || is_package_installed certbot; then
log "Certbot is already installed, skipping"
else
packages_to_install+=(certbot)
fi
if is_package_installed python3-certbot-nginx; then
log "python3-certbot-nginx is already installed, skipping"
else
packages_to_install+=(python3-certbot-nginx)
fi
if ! command -v unzip >/dev/null 2>&1 && ! is_package_installed unzip; then
packages_to_install+=(unzip)
fi
if ! command -v wget >/dev/null 2>&1 && ! is_package_installed wget; then
packages_to_install+=(wget)
fi
if [[ ${#packages_to_install[@]} -eq 0 ]]; then
log "All required packages are already installed"
return 0
fi
log "Installing missing packages: ${packages_to_install[*]}"
DEBIAN_FRONTEND=noninteractive apt-get install -y "${packages_to_install[@]}"
}
configure_java_home() {
log "Configuring JAVA_HOME"
local java_bin=""
local candidate=""
if [[ -n "${JAVA_HOME:-}" && -x "${JAVA_HOME}/bin/java" ]]; then
JAVA_HOME_PATH="${JAVA_HOME}"
fi
if [[ -z "${JAVA_HOME_PATH}" ]]; then
java_bin="$(readlink -f "$(command -v java 2>/dev/null)" 2>/dev/null || true)"
if [[ -n "${java_bin}" ]]; then
candidate="$(dirname "$(dirname "${java_bin}")")"
if [[ -x "${candidate}/bin/java" ]]; then
JAVA_HOME_PATH="${candidate}"
elif [[ "$(basename "${candidate}")" == "jre" ]]; then
candidate="$(dirname "${candidate}")"
if [[ -x "${candidate}/bin/java" ]]; then
JAVA_HOME_PATH="${candidate}"
fi
fi
fi
fi
if [[ -z "${JAVA_HOME_PATH}" ]] && command -v update-alternatives >/dev/null 2>&1; then
java_bin="$(update-alternatives --list java 2>/dev/null | head -n 1 || true)"
if [[ -n "${java_bin}" ]]; then
candidate="$(dirname "$(dirname "${java_bin}")")"
if [[ -x "${candidate}/bin/java" ]]; then
JAVA_HOME_PATH="${candidate}"
elif [[ "$(basename "${candidate}")" == "jre" ]]; then
candidate="$(dirname "${candidate}")"
if [[ -x "${candidate}/bin/java" ]]; then
JAVA_HOME_PATH="${candidate}"
fi
fi
fi
fi
if [[ -z "${JAVA_HOME_PATH}" ]]; then
for candidate in /usr/lib/jvm/*; do
if [[ -x "${candidate}/bin/java" ]]; then
JAVA_HOME_PATH="${candidate}"
break
fi
done
fi
if [[ -z "${JAVA_HOME_PATH}" || ! -x "${JAVA_HOME_PATH}/bin/java" ]]; then
echo "Could not determine a valid JAVA_HOME. Please set JAVA_HOME before running this script."
exit 1
fi
cat >/etc/profile.d/ezyplatform-java.sh <<EOF
export JAVA_HOME=${JAVA_HOME_PATH}
export PATH=\$JAVA_HOME/bin:\$PATH
EOF
chmod 0644 /etc/profile.d/ezyplatform-java.sh
}
download_and_extract_ezyplatform() {
if [[ -f "${EZYPLATFORM_DIR}/settings/setup.properties" ]]; then
EZYPLATFORM_ALREADY_EXISTS=1
log "EzyPlatform directory already exists at ${EZYPLATFORM_DIR}, skipping download and extraction"
return 0
fi
log "Downloading EzyPlatform package"
rm -f "${EZYPLATFORM_ZIP}"
wget -O "${EZYPLATFORM_ZIP}" "${EZYPLATFORM_URL}"
log "Extracting EzyPlatform to ${EZYPLATFORM_DIR}"
rm -rf "${EZYPLATFORM_DIR}"
mkdir -p "${EZYPLATFORM_DIR}"
unzip -oq "${EZYPLATFORM_ZIP}" -d "${EZYPLATFORM_DIR}"
if [[ -d "${EZYPLATFORM_DIR}/ezyplatform" ]]; then
local extracted_dir
extracted_dir="${EZYPLATFORM_DIR}/ezyplatform"
find "${extracted_dir}" -mindepth 1 -maxdepth 1 -exec mv {} "${EZYPLATFORM_DIR}/" \;
rmdir "${extracted_dir}"
fi
if [[ ! -f "${EZYPLATFORM_DIR}/settings/setup.properties" ]]; then
echo "Could not find ${EZYPLATFORM_DIR}/settings/setup.properties after extraction."
exit 1
fi
}
write_setup_properties() {
if is_port_9090_listening; then
log "Port 9090 is already in use, assuming admin is already running"
fi
if [[ "${EZYPLATFORM_ALREADY_EXISTS}" -eq 1 ]]; then
log "Existing EzyPlatform setup detected, skipping setup.properties update"
return 0
fi
log "Writing EzyPlatform setup.properties"
cat >"${EZYPLATFORM_DIR}/settings/setup.properties" <<EOF
datasource.jdbc_url=jdbc:mysql://localhost:3306/${DB_NAME}
datasource.driver_class_name=com.mysql.cj.jdbc.Driver
datasource.username=${DB_USER}
datasource.password=${DB_PASSWORD}
tables.create_manually=false
EOF
}
enable_services() {
log "Enabling and starting services"
systemctl enable mysql || true
systemctl enable nginx || true
systemctl start mysql
systemctl start nginx || true
}
start_ezyplatform_admin() {
if is_port_9090_listening; then
log "Port 9090 is already in use, skipping automatic admin startup"
return 0
fi
if [[ ! -f "${EZYPLATFORM_DIR}/cli.sh" ]]; then
echo "Could not find ${EZYPLATFORM_DIR}/cli.sh to restart admin."
exit 1
fi
log "Starting EzyPlatform admin"
(
cd "${EZYPLATFORM_DIR}"
bash cli.sh "start admin"
)
}
print_summary() {
cat <<EOF
Installation completed.
Database:
name: ${DB_NAME}
user: ${DB_USER}
password: ${DB_PASSWORD}
EzyPlatform:
directory: ${EZYPLATFORM_DIR}
setup file: ${EZYPLATFORM_DIR}/settings/setup.properties
MySQL root:
password: ${MYSQL_ROOT_PASSWORD:-unchanged}
Next steps:
1. Open:
http://<server-ip>:9090/setup-admin
2. Complete admin setup in the browser.
3. If you want to inspect the log:
cd ${EZYPLATFORM_DIR}
tail -f logs/admin-server.log
Notes:
- Nginx and Certbot were installed only. No site or SSL configuration was created.
- Admin is started automatically at the end of the installation.
- Admin access is expected directly via IP:9090 as requested.
- If port 9090 is already listening, the script keeps the existing service and does not stop/restart it.
EOF
}
require_command apt-get
require_command systemctl
require_command wget
require_command unzip
require_command ss
install_packages
enable_services
wait_for_mysql
configure_mysql_root_password
create_database_and_user
configure_java_home
download_and_extract_ezyplatform
write_setup_properties
start_ezyplatform_admin
log "Java version"
java -version || true
print_summary
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment