630 lines
20 KiB
Bash
Executable File
630 lines
20 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
LOG_FILE="${LOG_FILE:-/tmp/ubuntu2404-laravel-base.log}"
|
|
|
|
PHP_VERSION="${PHP_VERSION:-8.3}"
|
|
NODE_MAJOR="${NODE_MAJOR:-20}"
|
|
LARAVEL_PROJECTS_DIR="${LARAVEL_PROJECTS_DIR:-/srv/laravel-projects}"
|
|
INSTALL_CORE=1
|
|
INSTALL_PHP=1
|
|
INSTALL_COMPOSER=1
|
|
INSTALL_NODE=1
|
|
INSTALL_XFCE=1
|
|
INSTALL_VSCODE=1
|
|
INSTALL_XRDP=1
|
|
CONFIGURE_FIREWALL=1
|
|
INTERACTIVE=1
|
|
|
|
declare -a INSTALLED_COMPONENTS=()
|
|
declare -a SKIPPED_COMPONENTS=()
|
|
|
|
if [[ -n "${SUDO_USER:-}" ]]; then
|
|
WORKSTATION_USER="$SUDO_USER"
|
|
else
|
|
WORKSTATION_USER="${USER}"
|
|
fi
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage: ubuntu2404-laravel-base.sh [options]
|
|
|
|
Options:
|
|
--php-version <version> PHP major.minor to install (default: 8.3)
|
|
--node-major <version> Node.js major release (default: 20)
|
|
--projects-dir <path> Root directory for Laravel projects (default: /srv/laravel-projects)
|
|
--without-core Skip core packages (nginx, mysql, redis, supervisor, tools)
|
|
--without-php Skip PHP installation and PHP tuning
|
|
--without-composer Skip Composer installation
|
|
--without-node Skip Node.js installation
|
|
--without-xfce Skip XFCE desktop packages
|
|
--without-vscode Skip Visual Studio Code installation
|
|
--without-xrdp Skip XRDP installation
|
|
--without-firewall Skip UFW configuration
|
|
--non-interactive Do not ask questions before installation
|
|
--workstation-user <user> User that will own desktop/workspace directories
|
|
--help Show this message
|
|
|
|
Example:
|
|
sudo bash scripts/install/ubuntu2404-laravel-base.sh --projects-dir /srv/laravel-projects
|
|
EOF
|
|
}
|
|
|
|
log() {
|
|
local level="$1"
|
|
shift
|
|
printf '[%s] %s\n' "$level" "$*" >&2
|
|
|
|
if [[ -n "${LOG_FILE:-}" ]]; then
|
|
printf '[%s] %s\n' "$level" "$*" >> "$LOG_FILE" 2>/dev/null || true
|
|
fi
|
|
}
|
|
|
|
info() { log INFO "$@"; }
|
|
warn() { log WARN "$@"; }
|
|
fail() { log ERROR "$@"; exit 1; }
|
|
|
|
on_error() {
|
|
local exit_code="$1"
|
|
local line_no="$2"
|
|
local command_text="$3"
|
|
|
|
log ERROR "Installer failed at line ${line_no}: ${command_text} (exit ${exit_code})"
|
|
log ERROR "See log file: ${LOG_FILE}"
|
|
exit "$exit_code"
|
|
}
|
|
|
|
trap 'on_error "$?" "$LINENO" "$BASH_COMMAND"' ERR
|
|
|
|
tty_available() {
|
|
[[ -r /dev/tty ]]
|
|
}
|
|
|
|
command_version() {
|
|
local command_name="$1"
|
|
shift || true
|
|
local output=''
|
|
|
|
if ! command -v "$command_name" >/dev/null 2>&1; then
|
|
printf 'missing'
|
|
return 0
|
|
fi
|
|
|
|
if [[ $# -gt 0 ]]; then
|
|
output="$({ "$@" 2>&1 || true; } | head -n 1)"
|
|
else
|
|
output="$({ "$command_name" --version 2>&1 || true; } | head -n 1)"
|
|
fi
|
|
|
|
if [[ -n "$output" ]]; then
|
|
printf '%s' "$output"
|
|
else
|
|
printf 'installed'
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
component_state() {
|
|
local value="$1"
|
|
|
|
if [[ "$value" == "missing" || -z "$value" ]]; then
|
|
printf 'missing'
|
|
else
|
|
printf 'present'
|
|
fi
|
|
}
|
|
|
|
print_component_line() {
|
|
local label="$1"
|
|
local state="$2"
|
|
local detail="$3"
|
|
|
|
printf ' - %-18s : %-8s %s\n' "$label" "$state" "$detail"
|
|
}
|
|
|
|
prompt_yes_no() {
|
|
local prompt_text="$1"
|
|
local default_value="$2"
|
|
local answer=''
|
|
local suffix='[Y/n]'
|
|
|
|
if [[ "$default_value" == 'n' ]]; then
|
|
suffix='[y/N]'
|
|
fi
|
|
|
|
if ! tty_available; then
|
|
[[ "$default_value" == 'y' ]]
|
|
return
|
|
fi
|
|
|
|
while true; do
|
|
printf '%s %s ' "$prompt_text" "$suffix" > /dev/tty
|
|
IFS= read -r answer < /dev/tty || answer=''
|
|
answer="${answer,,}"
|
|
|
|
if [[ -z "$answer" ]]; then
|
|
[[ "$default_value" == 'y' ]]
|
|
return
|
|
fi
|
|
|
|
case "$answer" in
|
|
y|yes)
|
|
return 0
|
|
;;
|
|
n|no)
|
|
return 1
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
record_component() {
|
|
local label="$1"
|
|
local status="$2"
|
|
|
|
if [[ "$status" == 'installed' ]]; then
|
|
INSTALLED_COMPONENTS+=("$label")
|
|
else
|
|
SKIPPED_COMPONENTS+=("$label")
|
|
fi
|
|
}
|
|
|
|
normalize_vscode_apt_source_conflicts() {
|
|
local source_file=''
|
|
local removed_any=0
|
|
|
|
while IFS= read -r source_file; do
|
|
[[ -n "$source_file" ]] || continue
|
|
run_root rm -f "$source_file"
|
|
removed_any=1
|
|
done < <(grep -l "packages.microsoft.com/repos/code" /etc/apt/sources.list.d/*.list 2>/dev/null || true)
|
|
|
|
if [[ $removed_any -eq 1 ]]; then
|
|
info 'Removed conflicting VS Code apt source entries'
|
|
fi
|
|
}
|
|
|
|
should_run_apt_work() {
|
|
[[ $INSTALL_CORE -eq 1 || \
|
|
$INSTALL_PHP -eq 1 || \
|
|
$INSTALL_COMPOSER -eq 1 || \
|
|
$INSTALL_NODE -eq 1 || \
|
|
$INSTALL_VSCODE -eq 1 || \
|
|
$INSTALL_XFCE -eq 1 || \
|
|
$INSTALL_XRDP -eq 1 ]]
|
|
}
|
|
|
|
run_root() {
|
|
if [[ ${EUID} -eq 0 ]]; then
|
|
"$@"
|
|
else
|
|
sudo "$@"
|
|
fi
|
|
}
|
|
|
|
run_root_env() {
|
|
if [[ ${EUID} -eq 0 ]]; then
|
|
env "$@"
|
|
else
|
|
sudo env "$@"
|
|
fi
|
|
}
|
|
|
|
run_as_user() {
|
|
local target_user="$1"
|
|
shift
|
|
|
|
if [[ ${EUID} -eq 0 ]]; then
|
|
runuser -u "$target_user" -- "$@"
|
|
else
|
|
sudo -u "$target_user" "$@"
|
|
fi
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--php-version)
|
|
PHP_VERSION="$2"
|
|
shift 2
|
|
;;
|
|
--node-major)
|
|
NODE_MAJOR="$2"
|
|
shift 2
|
|
;;
|
|
--projects-dir)
|
|
LARAVEL_PROJECTS_DIR="$2"
|
|
shift 2
|
|
;;
|
|
--without-core)
|
|
INSTALL_CORE=0
|
|
shift
|
|
;;
|
|
--without-php)
|
|
INSTALL_PHP=0
|
|
shift
|
|
;;
|
|
--without-composer)
|
|
INSTALL_COMPOSER=0
|
|
shift
|
|
;;
|
|
--without-node)
|
|
INSTALL_NODE=0
|
|
shift
|
|
;;
|
|
--without-xfce)
|
|
INSTALL_XFCE=0
|
|
shift
|
|
;;
|
|
--without-vscode)
|
|
INSTALL_VSCODE=0
|
|
shift
|
|
;;
|
|
--without-xrdp)
|
|
INSTALL_XRDP=0
|
|
shift
|
|
;;
|
|
--without-firewall)
|
|
CONFIGURE_FIREWALL=0
|
|
shift
|
|
;;
|
|
--non-interactive)
|
|
INTERACTIVE=0
|
|
shift
|
|
;;
|
|
--workstation-user)
|
|
WORKSTATION_USER="$2"
|
|
shift 2
|
|
;;
|
|
--help|-h)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
fail "Unknown option: $1"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
info "Starting Ubuntu 24.04 Laravel base installer"
|
|
info "Execution user: $(id -un)"
|
|
info "Log file: $LOG_FILE"
|
|
|
|
if [[ ! -f /etc/os-release ]]; then
|
|
fail "Cannot detect operating system"
|
|
fi
|
|
|
|
# shellcheck disable=SC1091
|
|
source /etc/os-release
|
|
if [[ "${ID:-}" != "ubuntu" || "${VERSION_ID:-}" != "24.04" ]]; then
|
|
fail "This script supports Ubuntu 24.04 only"
|
|
fi
|
|
|
|
if ! id -u "$WORKSTATION_USER" >/dev/null 2>&1; then
|
|
fail "User not found: $WORKSTATION_USER"
|
|
fi
|
|
|
|
PHP_PACKAGES=(
|
|
"php${PHP_VERSION}"
|
|
"php${PHP_VERSION}-fpm"
|
|
"php${PHP_VERSION}-cli"
|
|
"php${PHP_VERSION}-common"
|
|
"php${PHP_VERSION}-curl"
|
|
"php${PHP_VERSION}-mbstring"
|
|
"php${PHP_VERSION}-xml"
|
|
"php${PHP_VERSION}-zip"
|
|
"php${PHP_VERSION}-mysql"
|
|
"php${PHP_VERSION}-sqlite3"
|
|
"php${PHP_VERSION}-bcmath"
|
|
"php${PHP_VERSION}-intl"
|
|
"php${PHP_VERSION}-gd"
|
|
"php${PHP_VERSION}-imagick"
|
|
"php${PHP_VERSION}-redis"
|
|
"php${PHP_VERSION}-opcache"
|
|
)
|
|
|
|
BASE_PACKAGES=(
|
|
acl
|
|
apt-transport-https
|
|
ca-certificates
|
|
curl
|
|
ffmpeg
|
|
git
|
|
gnupg
|
|
htop
|
|
imagemagick
|
|
jq
|
|
lsb-release
|
|
net-tools
|
|
nginx
|
|
redis-server
|
|
software-properties-common
|
|
supervisor
|
|
tree
|
|
unzip
|
|
ufw
|
|
vim
|
|
wget
|
|
mysql-server
|
|
)
|
|
|
|
show_preflight_screen() {
|
|
local os_label="${PRETTY_NAME:-Ubuntu 24.04}"
|
|
local php_detail
|
|
local composer_detail
|
|
local node_detail
|
|
local npm_detail
|
|
local mysql_detail
|
|
local nginx_detail
|
|
local redis_detail
|
|
local code_detail
|
|
local xfce_detail
|
|
local xrdp_detail
|
|
|
|
php_detail=$(command_version php php -v)
|
|
composer_detail=$(command_version composer composer --version)
|
|
node_detail=$(command_version node node --version)
|
|
npm_detail=$(command_version npm npm --version)
|
|
mysql_detail=$(command_version mysql mysql --version)
|
|
nginx_detail=$(command_version nginx nginx -v)
|
|
redis_detail=$(command_version redis-server redis-server --version)
|
|
code_detail=$(if dpkg -s code >/dev/null 2>&1; then dpkg-query -W -f='VS Code package ${Version}' code 2>/dev/null || printf 'VS Code installed'; else printf 'missing'; fi)
|
|
xfce_detail=$(if dpkg -s xfce4 >/dev/null 2>&1; then printf 'xfce4 installed'; else printf 'missing'; fi)
|
|
xrdp_detail=$(if dpkg -s xrdp >/dev/null 2>&1; then printf 'xrdp installed'; else printf 'missing'; fi)
|
|
|
|
printf '\n'
|
|
printf '============================================================\n'
|
|
printf ' Laravel Base Installer - Preflight\n'
|
|
printf '============================================================\n'
|
|
printf ' Machine : %s\n' "$(hostname)"
|
|
printf ' System : %s\n' "$os_label"
|
|
printf ' User : %s\n' "$WORKSTATION_USER"
|
|
printf ' Projects dir : %s\n' "$LARAVEL_PROJECTS_DIR"
|
|
printf '\n'
|
|
printf 'Current status:\n'
|
|
print_component_line 'PHP' "$(component_state "$php_detail")" "$php_detail"
|
|
print_component_line 'Composer' "$(component_state "$composer_detail")" "$composer_detail"
|
|
print_component_line 'Node.js' "$(component_state "$node_detail")" "$node_detail"
|
|
print_component_line 'npm' "$(component_state "$npm_detail")" "$npm_detail"
|
|
print_component_line 'MySQL' "$(component_state "$mysql_detail")" "$mysql_detail"
|
|
print_component_line 'Nginx' "$(component_state "$nginx_detail")" "$nginx_detail"
|
|
print_component_line 'Redis' "$(component_state "$redis_detail")" "$redis_detail"
|
|
print_component_line 'VS Code' "$(component_state "$code_detail")" "$code_detail"
|
|
print_component_line 'XFCE' "$(component_state "$xfce_detail")" "$xfce_detail"
|
|
print_component_line 'XRDP' "$(component_state "$xrdp_detail")" "$xrdp_detail"
|
|
printf '\n'
|
|
printf 'Planned install set:\n'
|
|
print_component_line 'Core stack' "$([[ $INSTALL_CORE -eq 1 ]] && printf enabled || printf skipped)" 'nginx, mysql, redis, supervisor, common tools'
|
|
print_component_line 'PHP stack' "$([[ $INSTALL_PHP -eq 1 ]] && printf enabled || printf skipped)" "php${PHP_VERSION} and extensions"
|
|
print_component_line 'Composer' "$([[ $INSTALL_COMPOSER -eq 1 ]] && printf enabled || printf skipped)" 'global composer binary'
|
|
print_component_line 'Node.js' "$([[ $INSTALL_NODE -eq 1 ]] && printf enabled || printf skipped)" "Node ${NODE_MAJOR}.x"
|
|
print_component_line 'VS Code' "$([[ $INSTALL_VSCODE -eq 1 ]] && printf enabled || printf skipped)" 'desktop IDE'
|
|
print_component_line 'XFCE' "$([[ $INSTALL_XFCE -eq 1 ]] && printf enabled || printf skipped)" 'light desktop environment'
|
|
print_component_line 'XRDP' "$([[ $INSTALL_XRDP -eq 1 ]] && printf enabled || printf skipped)" 'remote desktop service'
|
|
print_component_line 'Firewall' "$([[ $CONFIGURE_FIREWALL -eq 1 ]] && printf enabled || printf skipped)" 'OpenSSH, HTTP, HTTPS, XRDP'
|
|
printf '\n'
|
|
}
|
|
|
|
run_interactive_preflight() {
|
|
if [[ $INTERACTIVE -ne 1 ]]; then
|
|
return
|
|
fi
|
|
|
|
if ! tty_available; then
|
|
warn 'No tty available: proceeding with current flags without prompts.'
|
|
return
|
|
fi
|
|
|
|
show_preflight_screen
|
|
|
|
prompt_yes_no 'Install core stack and common tools?' 'y' && INSTALL_CORE=1 || INSTALL_CORE=0
|
|
prompt_yes_no "Install PHP ${PHP_VERSION} stack?" 'y' && INSTALL_PHP=1 || INSTALL_PHP=0
|
|
prompt_yes_no 'Install Composer?' 'y' && INSTALL_COMPOSER=1 || INSTALL_COMPOSER=0
|
|
prompt_yes_no "Install Node.js ${NODE_MAJOR}.x?" 'y' && INSTALL_NODE=1 || INSTALL_NODE=0
|
|
prompt_yes_no 'Install Visual Studio Code?' "$([[ $INSTALL_VSCODE -eq 1 ]] && printf y || printf n)" && INSTALL_VSCODE=1 || INSTALL_VSCODE=0
|
|
prompt_yes_no 'Install XFCE desktop?' "$([[ $INSTALL_XFCE -eq 1 ]] && printf y || printf n)" && INSTALL_XFCE=1 || INSTALL_XFCE=0
|
|
prompt_yes_no 'Install XRDP remote desktop?' "$([[ $INSTALL_XRDP -eq 1 ]] && printf y || printf n)" && INSTALL_XRDP=1 || INSTALL_XRDP=0
|
|
prompt_yes_no 'Configure firewall rules?' "$([[ $CONFIGURE_FIREWALL -eq 1 ]] && printf y || printf n)" && CONFIGURE_FIREWALL=1 || CONFIGURE_FIREWALL=0
|
|
|
|
printf '\nSelection summary:\n'
|
|
print_component_line 'Core stack' "$([[ $INSTALL_CORE -eq 1 ]] && printf install || printf skip)" ''
|
|
print_component_line 'PHP stack' "$([[ $INSTALL_PHP -eq 1 ]] && printf install || printf skip)" ''
|
|
print_component_line 'Composer' "$([[ $INSTALL_COMPOSER -eq 1 ]] && printf install || printf skip)" ''
|
|
print_component_line 'Node.js' "$([[ $INSTALL_NODE -eq 1 ]] && printf install || printf skip)" ''
|
|
print_component_line 'VS Code' "$([[ $INSTALL_VSCODE -eq 1 ]] && printf install || printf skip)" ''
|
|
print_component_line 'XFCE' "$([[ $INSTALL_XFCE -eq 1 ]] && printf install || printf skip)" ''
|
|
print_component_line 'XRDP' "$([[ $INSTALL_XRDP -eq 1 ]] && printf install || printf skip)" ''
|
|
print_component_line 'Firewall' "$([[ $CONFIGURE_FIREWALL -eq 1 ]] && printf configure || printf skip)" ''
|
|
printf '\n'
|
|
|
|
if ! prompt_yes_no 'Proceed with installation?' 'y'; then
|
|
fail 'Installation aborted by user'
|
|
fi
|
|
}
|
|
|
|
run_interactive_preflight
|
|
|
|
if should_run_apt_work; then
|
|
normalize_vscode_apt_source_conflicts
|
|
info "Updating apt metadata"
|
|
run_root apt-get update
|
|
run_root_env DEBIAN_FRONTEND=noninteractive apt-get -y upgrade
|
|
else
|
|
info "No package installation selected: skipping apt metadata refresh"
|
|
fi
|
|
|
|
if [[ $INSTALL_CORE -eq 1 ]]; then
|
|
info "Installing base packages"
|
|
run_root_env DEBIAN_FRONTEND=noninteractive apt-get install -y "${BASE_PACKAGES[@]}"
|
|
record_component 'Core stack' 'installed'
|
|
else
|
|
record_component 'Core stack' 'skipped'
|
|
fi
|
|
|
|
if [[ $INSTALL_PHP -eq 1 ]]; then
|
|
info "Installing PHP ${PHP_VERSION} stack"
|
|
run_root_env DEBIAN_FRONTEND=noninteractive apt-get install -y "${PHP_PACKAGES[@]}"
|
|
record_component "PHP ${PHP_VERSION} stack" 'installed'
|
|
else
|
|
record_component "PHP ${PHP_VERSION} stack" 'skipped'
|
|
fi
|
|
|
|
if [[ $INSTALL_PHP -eq 1 ]]; then
|
|
info "Configuring PHP"
|
|
run_root mkdir -p "/etc/php/${PHP_VERSION}/fpm/conf.d" "/etc/php/${PHP_VERSION}/cli/conf.d"
|
|
run_root tee "/etc/php/${PHP_VERSION}/fpm/conf.d/99-laravel-base.ini" >/dev/null <<EOF
|
|
memory_limit=512M
|
|
upload_max_filesize=64M
|
|
post_max_size=64M
|
|
max_execution_time=300
|
|
max_input_vars=3000
|
|
opcache.enable=1
|
|
opcache.memory_consumption=192
|
|
opcache.interned_strings_buffer=16
|
|
opcache.max_accelerated_files=20000
|
|
opcache.validate_timestamps=1
|
|
opcache.revalidate_freq=2
|
|
realpath_cache_size=4096K
|
|
realpath_cache_ttl=600
|
|
EOF
|
|
run_root cp "/etc/php/${PHP_VERSION}/fpm/conf.d/99-laravel-base.ini" "/etc/php/${PHP_VERSION}/cli/conf.d/99-laravel-base.ini"
|
|
fi
|
|
|
|
TMP_COMPOSER_DIR="$(mktemp -d)"
|
|
trap 'rm -rf "$TMP_COMPOSER_DIR"' EXIT
|
|
|
|
if [[ $INSTALL_COMPOSER -eq 1 ]]; then
|
|
info "Installing Composer"
|
|
curl -fsSL https://getcomposer.org/installer -o "$TMP_COMPOSER_DIR/composer-setup.php"
|
|
php "$TMP_COMPOSER_DIR/composer-setup.php" --install-dir="$TMP_COMPOSER_DIR" --filename=composer >/dev/null
|
|
run_root install -m 0755 "$TMP_COMPOSER_DIR/composer" /usr/local/bin/composer
|
|
record_component 'Composer' 'installed'
|
|
else
|
|
record_component 'Composer' 'skipped'
|
|
fi
|
|
|
|
if [[ $INSTALL_NODE -eq 1 ]]; then
|
|
info "Installing Node.js ${NODE_MAJOR}.x"
|
|
curl -fsSL "https://deb.nodesource.com/setup_${NODE_MAJOR}.x" | run_root bash
|
|
run_root_env DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs
|
|
record_component "Node.js ${NODE_MAJOR}.x" 'installed'
|
|
else
|
|
record_component "Node.js ${NODE_MAJOR}.x" 'skipped'
|
|
fi
|
|
|
|
if [[ $INSTALL_VSCODE -eq 1 ]]; then
|
|
info "Installing Visual Studio Code"
|
|
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > "$TMP_COMPOSER_DIR/packages.microsoft.gpg"
|
|
run_root install -D -o root -g root -m 0644 "$TMP_COMPOSER_DIR/packages.microsoft.gpg" /usr/share/keyrings/packages.microsoft.gpg
|
|
|
|
normalize_vscode_apt_source_conflicts
|
|
|
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" \
|
|
| run_root tee /etc/apt/sources.list.d/vscode.list >/dev/null
|
|
run_root apt-get update
|
|
run_root_env DEBIAN_FRONTEND=noninteractive apt-get install -y code
|
|
record_component 'VS Code' 'installed'
|
|
else
|
|
record_component 'VS Code' 'skipped'
|
|
fi
|
|
|
|
if [[ $INSTALL_XFCE -eq 1 ]]; then
|
|
info "Installing XFCE desktop"
|
|
run_root_env DEBIAN_FRONTEND=noninteractive apt-get install -y xfce4 xfce4-goodies xorg dbus-x11
|
|
run_as_user "$WORKSTATION_USER" mkdir -p "/home/$WORKSTATION_USER"
|
|
run_as_user "$WORKSTATION_USER" bash -lc "printf 'xfce4-session\n' > ~/.xsession"
|
|
record_component 'XFCE desktop' 'installed'
|
|
else
|
|
record_component 'XFCE desktop' 'skipped'
|
|
fi
|
|
|
|
if [[ $INSTALL_XRDP -eq 1 ]]; then
|
|
info "Installing XRDP"
|
|
run_root_env DEBIAN_FRONTEND=noninteractive apt-get install -y xrdp
|
|
run_root systemctl enable xrdp
|
|
run_root systemctl restart xrdp
|
|
record_component 'XRDP' 'installed'
|
|
else
|
|
record_component 'XRDP' 'skipped'
|
|
fi
|
|
|
|
info "Creating Laravel workspace directories"
|
|
run_root mkdir -p "$LARAVEL_PROJECTS_DIR" "$LARAVEL_PROJECTS_DIR/shared" "$LARAVEL_PROJECTS_DIR/backups"
|
|
run_root chown -R "$WORKSTATION_USER":www-data "$LARAVEL_PROJECTS_DIR"
|
|
run_root chmod -R 2775 "$LARAVEL_PROJECTS_DIR"
|
|
|
|
info "Configuring services"
|
|
SERVICE_NAMES=()
|
|
if [[ $INSTALL_PHP -eq 1 ]]; then
|
|
SERVICE_NAMES+=("php${PHP_VERSION}-fpm")
|
|
fi
|
|
if [[ $INSTALL_CORE -eq 1 ]]; then
|
|
SERVICE_NAMES+=(nginx mysql redis-server supervisor)
|
|
fi
|
|
if [[ ${#SERVICE_NAMES[@]} -gt 0 ]]; then
|
|
run_root systemctl enable "${SERVICE_NAMES[@]}"
|
|
run_root systemctl restart "${SERVICE_NAMES[@]}"
|
|
fi
|
|
|
|
if [[ $CONFIGURE_FIREWALL -eq 1 ]]; then
|
|
info "Configuring firewall"
|
|
run_root ufw allow OpenSSH
|
|
run_root ufw allow 80/tcp
|
|
run_root ufw allow 443/tcp
|
|
if [[ $INSTALL_XRDP -eq 1 ]]; then
|
|
run_root ufw allow 3389/tcp
|
|
fi
|
|
run_root ufw --force enable
|
|
record_component 'Firewall rules' 'installed'
|
|
else
|
|
record_component 'Firewall rules' 'skipped'
|
|
fi
|
|
|
|
SUMMARY_FILE="/home/$WORKSTATION_USER/laravel-base-setup-summary.txt"
|
|
info "Writing summary to $SUMMARY_FILE"
|
|
SUMMARY_PHP="$(command_version php php -v)"
|
|
SUMMARY_COMPOSER="$(command_version composer composer --version)"
|
|
SUMMARY_NODE="$(command_version node node --version)"
|
|
SUMMARY_NPM="$(command_version npm npm --version)"
|
|
SUMMARY_MYSQL="$(command_version mysql mysql --version)"
|
|
SUMMARY_NGINX="$(command_version nginx nginx -v)"
|
|
SUMMARY_REDIS="$(command_version redis-server redis-server --version)"
|
|
cat > "$TMP_COMPOSER_DIR/summary.txt" <<EOF
|
|
Laravel Base Setup Summary
|
|
Date: $(date -Is)
|
|
Host: $(hostname)
|
|
Ubuntu: ${VERSION:-Ubuntu 24.04}
|
|
PHP: $SUMMARY_PHP
|
|
Composer: $SUMMARY_COMPOSER
|
|
Node: $SUMMARY_NODE
|
|
NPM: $SUMMARY_NPM
|
|
MySQL: $SUMMARY_MYSQL
|
|
Nginx: $SUMMARY_NGINX
|
|
Redis: $SUMMARY_REDIS
|
|
Projects dir: $LARAVEL_PROJECTS_DIR
|
|
Workstation user: $WORKSTATION_USER
|
|
XFCE installed: $INSTALL_XFCE
|
|
VS Code installed: $INSTALL_VSCODE
|
|
XRDP installed: $INSTALL_XRDP
|
|
Firewall configured: $CONFIGURE_FIREWALL
|
|
Installed components: ${INSTALLED_COMPONENTS[*]:-none}
|
|
Skipped components: ${SKIPPED_COMPONENTS[*]:-none}
|
|
EOF
|
|
run_root install -o "$WORKSTATION_USER" -g "$WORKSTATION_USER" -m 0644 "$TMP_COMPOSER_DIR/summary.txt" "$SUMMARY_FILE"
|
|
|
|
info "Base machine ready"
|
|
printf '\nInstalled components:\n'
|
|
for component in "${INSTALLED_COMPONENTS[@]}"; do
|
|
printf ' - %s\n' "$component"
|
|
done
|
|
|
|
printf '\nSkipped components:\n'
|
|
for component in "${SKIPPED_COMPONENTS[@]}"; do
|
|
printf ' - %s\n' "$component"
|
|
done
|
|
|
|
printf '\nNext steps:\n'
|
|
printf ' 1. Copy or clone your Laravel project under %s\n' "$LARAVEL_PROJECTS_DIR"
|
|
printf ' 2. Configure Nginx site and database for the specific project\n'
|
|
printf ' 3. For NetGescon, run scripts/install/netgescon-node-bootstrap.sh\n'
|