Skip to content

Commit

Permalink
🔨 improve installation script
Browse files Browse the repository at this point in the history
  • Loading branch information
MrKrisKrisu committed Jan 1, 2025
1 parent 4b17875 commit 7a5e7ee
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 25 deletions.
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,16 @@ public/uploads/avatars/*
# vendor-views
!resources/views/vendor

# Laravel 4 specific
# Laravel specific
bootstrap/compiled.php
app/storage/

# Laravel 5 & Lumen specific
public/storage
public/hot
storage/*.key
.env*
Homestead.yaml
Homestead.json
storage/framework/maintenance.php

# Rocketeer PHP task runner and deployment package. https://github.com/rocketeers/rocketeer
.rocketeer/
Expand Down
209 changes: 187 additions & 22 deletions scripts/install.sh
Original file line number Diff line number Diff line change
@@ -1,40 +1,205 @@
#!/usr/bin/env bash

set -e
set -o pipefail

pre_run() {
php artisan down
git pull
composer install --no-interaction --no-dev --prefer-dist
ASCII_ART="\
_______ _ _ _
|__ __| | | (_)
| |_ __ __ _ _____ _____| | |_ _ __ __ _
| | '__/ _\` \|/ _ \ \ /\ / / _ \ | | | '_ \ / _\` |
| | | | (_| | __/\ V V / __/ | | | | | | (_| |
|_|_| \__,_|\___| \_/\_/ \___|_|_|_|_| |_|\__, |
__/ |
|___/
"

USER=${1:-www-data} # Default user is www-data
REPO_ROOT=$(git rev-parse --show-toplevel)

# Colors for fancy output
GREEN="\033[1;32m"
CYAN="\033[1;36m"
YELLOW="\033[1;33m"
RED="\033[1;31m"
RESET="\033[0m"
TRWL_RED="\033[38;2;255;0;0m"

ask_to_install_service() {
service_name="$1"

source_file="${REPO_ROOT}/scripts/services/${service_name}.service"
destination_file="/etc/systemd/system/${service_name}.service"

if [ -f "$destination_file" ]; then
echo -e "${YELLOW}Service ${service_name} is already installed.${RESET}"
return 1
fi

echo -e "${YELLOW}Service ${service_name} is not installed.${RESET}"
echo -e "${YELLOW}Do you want to install? Sudo may ask for your password.${RESET}"
echo -e "${YELLOW}[Y/n] (default: yes): ${RESET}"

read -r answer

case "$answer" in
y|Y|yes|Yes|"")
echo -e "${YELLOW}Installing ${service_name} service to ${destination_file}...${RESET}"
sudo cp "$source_file" "$destination_file"

sudo sed -i "s|REPLACE_ROOT_PATH|${REPO_ROOT}|g" "$destination_file"
sudo sed -i "s|REPLACE_USER|${USER}|g" "$destination_file"

sudo systemctl enable "$service_name"
sudo systemctl start "$service_name"

echo -e "${GREEN}${service_name} service installed successfully!${RESET}"
return 0
;;
n|N|no|No)
echo -e "${YELLOW}Skipping ${service_name} service installation...${RESET}"
return 1
;;
*)
echo -e "${RED}Invalid answer. Please answer with 'y' or 'n'.${RESET}"
ask_to_install_service "$service_name"
;;
esac
}

update_ui() {
npm ci --no-audit --no-progress && npm run build
welcome_message() {
echo -e "${TRWL_RED}${ASCII_ART}${RESET}"
echo -e "${CYAN}This script will install / update Träwelling to the latest develop version.${RESET}\n"
echo -e "${YELLOW}Running as: ${GREEN}${USER}${RESET}\n"

echo -e "${YELLOW}Continue installation in ${GREEN}${REPO_ROOT}${YELLOW} directory?\n[Y/n] (default: yes): ${RESET}"
read -r answer

case "$answer" in
y|Y|yes|Yes|"")
echo -e "${GREEN}Okay, let's go!${RESET}"
cd "$REPO_ROOT"
echo -e "${YELLOW}Starting installation at $(date --iso-8601=seconds)${RESET}\n\n\n"
;;
n|N|no|No)
echo -e "${YELLOW}Bye.${RESET}"
exit 1
;;
*)
echo -e "${RED}Invalid answer. Please answer with 'y' or 'n'.${RESET}"
welcome_message
;;
esac
}

check_dependencies() {
if [ "$USER" != "$(whoami)" ]; then
echo -e "${RED}Please run this script as ${USER} user.${RESET}"
exit 1
fi

if ! command -v php &> /dev/null; then
echo -e "${RED}PHP is not installed. Please install PHP and try again.${RESET}"
exit 1
fi

if ! command -v composer &> /dev/null; then
echo -e "${RED}Composer is not installed. Please install Composer and try again.${RESET}"
exit 1
fi

if ! command -v npm &> /dev/null; then
echo -e "${RED}NPM is not installed. Please install NPM and try again.${RESET}"
exit 1
fi

if ! command -v git &> /dev/null; then
echo -e "${RED}Git is not installed. Please install Git and try again.${RESET}"
exit 1
fi
}

activate_maintenance_mode() {
echo -e "${YELLOW}Enabling maintenance mode...${RESET}"
php artisan down
}

pull_latest_changes() {
echo -e "${YELLOW}Pulling latest changes...${RESET}"
git pull
}

install_composer_dependencies() {
echo -e "${YELLOW}Installing composer dependencies...${RESET}"
composer install --no-interaction --no-dev --prefer-dist --optimize-autoloader
}

install_npm_dependencies() {
echo -e "${YELLOW}Installing npm dependencies...${RESET}"
npm ci --no-audit --no-progress
npm run build
}

run_migrations() {
php artisan migrate --force
echo -e "${YELLOW}Running migrations...${RESET}"
php artisan migrate --force
}

post_run() {
php artisan optimize
finish_application() {
echo -e "${YELLOW}Optimizing application...${RESET}"
php artisan optimize

echo -e "${YELLOW}Seeding constants to database...${RESET}"
php artisan db:seed --class=Database\\Seeders\\Constants\\PermissionSeeder --force

php artisan db:seed --class=Database\\Seeders\\Constants\\PermissionSeeder --force
php artisan up
echo -e "${YELLOW}Disabling maintenance mode...${RESET}"
php artisan up
}

restart_queue() {
if [ -f /etc/systemd/system/traewelling-queue.service ]; then
sudo systemctl restart traewelling-queue
fi
restart_services() {
if ! command -v systemctl &> /dev/null; then
echo -e "${RED}Systemd is not available on this system. Skipping service restart.${RESET}"
return
fi

echo -e "\n\n${CYAN}Restarting services...${RESET}"
echo -e "${YELLOW}You may be asked to enter your password here if you're not running as root.${RESET}\n\n"

if [ -f /etc/systemd/system/traewelling-queue-webhook.service ]; then
sudo systemctl restart traewelling-queue-webhook
services=(
"traewelling-queue"
"traewelling-queue-webhook"
"traewelling-queue-export"
)

for service in "${services[@]}"; do
service_path="/etc/systemd/system/${service}.service"
if [ -f "$service_path" ]; then
echo -e "${YELLOW}Restarting ${service} service...${RESET}"
sudo systemctl restart "$service"
echo -e "${GREEN}${service} service restarted successfully!${RESET}"
else
ask_to_install_service "$service"
fi
done
}

run_installation() {
welcome_message
check_dependencies | sed "s/^/[DependencyCheck] /"
activate_maintenance_mode | sed "s/^/[PreInstall] /"
pull_latest_changes | sed "s/^/[git] /"
install_composer_dependencies | sed "s/^/[composer] /"
install_npm_dependencies | sed "s/^/[npm] /"
run_migrations | sed "s/^/[Migration] /"
finish_application | sed "s/^/[PostInstall] /"
restart_services | sed "s/^/[ServiceManager] /"

echo -e "\n\n${GREEN}Application updated successfully at $(date --iso-8601=seconds)!${RESET}"
}

pre_run
run_migrations
update_ui
post_run
restart_queue
run_installation 2>&1 | tee -a "${REPO_ROOT}/storage/logs/install-$(date --iso-8601=seconds).log"
4 changes: 4 additions & 0 deletions scripts/services/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Services for systemd

This directory contains systemd service files for the various services that are part of Träwelling.
These files are installed to `/etc/systemd/system` by the `install.sh` script.
13 changes: 13 additions & 0 deletions scripts/services/traewelling-queue-export.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=Traewelling Export Queue worker

[Service]
Type=simple
User=REPLACE_USER
Restart=always
RuntimeMaxSec=3600
WorkingDirectory=REPLACE_ROOT_PATH
ExecStart=php artisan queue:work --max-time=600 --tries=3 --queue=export

[Install]
WantedBy=multi-user.target
13 changes: 13 additions & 0 deletions scripts/services/traewelling-queue-webhook.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=Traewelling Webhook Queue worker

[Service]
Type=simple
User=REPLACE_USER
Restart=always
RuntimeMaxSec=3600
WorkingDirectory=REPLACE_ROOT_PATH
ExecStart=php artisan queue:work --max-time=600 --tries=3 --queue=webhook

[Install]
WantedBy=multi-user.target
13 changes: 13 additions & 0 deletions scripts/services/traewelling-queue.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Unit]
Description=Traewelling Queue worker

[Service]
Type=simple
User=REPLACE_USER
Restart=always
RuntimeMaxSec=3600
WorkingDirectory=REPLACE_ROOT_PATH
ExecStart=php artisan queue:work --max-time=600 --tries=3

[Install]
WantedBy=multi-user.target
9 changes: 9 additions & 0 deletions scripts/services/traewelling-scheduler.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[Unit]
Description=Traewelling Scheduler

[Service]
Type=oneshot
User=REPLACE_USER
Restart=on-failure
WorkingDirectory=REPLACE_ROOT_PATH
ExecStart=php artisan schedule:run
8 changes: 8 additions & 0 deletions scripts/services/traewelling-scheduler.timer
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[Unit]
Description=Traewelling Scheduler

[Timer]
OnCalendar=minutely

[Install]
WantedBy=timers.target

0 comments on commit 7a5e7ee

Please sign in to comment.