2024-04-08 04:50:36 +00:00
|
|
|
#!/bin/bash
|
2024-04-09 01:35:02 +00:00
|
|
|
|
2024-08-06 02:31:47 +00:00
|
|
|
# TODO: Add Crowsnest Support
|
|
|
|
# TODO: Avoid duplicate printer names
|
2024-08-06 17:48:45 +00:00
|
|
|
# TODO: Dry run
|
|
|
|
# TODO: Printer Directory Page in NGINX
|
|
|
|
# TODO: Fix PolicyKit issues "klippy_uds_address"
|
2024-04-09 01:35:02 +00:00
|
|
|
|
2024-08-06 17:48:45 +00:00
|
|
|
# Handle arguments
|
|
|
|
ARG_HELP=0
|
|
|
|
ARG_SKIP_APT=0
|
|
|
|
ARG_NAME=0
|
|
|
|
ARG_CONFIG=0
|
|
|
|
ARG_PORT=0
|
|
|
|
while [[ "$#" -gt 0 ]]; do
|
|
|
|
case $1 in
|
|
|
|
-h|--help) ARG_HELP=1 ;;
|
|
|
|
-a|--skip-apt) ARG_SKIP_APT=1 ;;
|
|
|
|
-n|--name) ARG_NAME="$2" ; shift ;;
|
|
|
|
-c|--config) ARG_CONFIG="$2" ; shift ;;
|
|
|
|
-p|--port) ARG_PORT="$2" ; shift ;;
|
|
|
|
*) echo "Unknown Parameter"; exit 3 ;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
|
|
|
|
# Prepare global variables
|
2024-07-30 01:18:31 +00:00
|
|
|
SOURCE=${BASH_SOURCE[0]}
|
|
|
|
while [ -L "$SOURCE" ]; do
|
|
|
|
TARGET=$(readlink "$SOURCE")
|
|
|
|
if [[ $TARGET == /* ]]; then
|
|
|
|
SOURCE=$TARGET
|
|
|
|
else
|
|
|
|
DIR=$( dirname "$SOURCE" )
|
|
|
|
SOURCE=$DIR/$TARGET
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
RDIR=$( dirname "$SOURCE" )
|
|
|
|
ROOT_DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
|
2024-04-08 04:50:36 +00:00
|
|
|
cd $ROOT_DIR
|
|
|
|
|
2024-08-06 00:47:48 +00:00
|
|
|
source ./ColorEchoForShell/dist/ColorEcho.bash
|
|
|
|
|
2024-08-06 17:48:45 +00:00
|
|
|
if [[ "$ARG_HELP" == 1 ]]; then
|
|
|
|
echo.Cyan "HacDC Printewr Setup Script Usage"
|
|
|
|
echo.Yellow "./setup.sh [options]"
|
|
|
|
echo ""
|
|
|
|
echo.BoldPurple "Option Description"
|
|
|
|
echo.Rainbow "-h/--help Display this help msg"
|
|
|
|
echo.Rainbow "-a/--skip-apt Skip installing apt packages"
|
|
|
|
echo.Rainbow "-n/--name Specify printer name (skips popup)"
|
|
|
|
echo.Rainbow "-c/--config Specify printer config (skips popup)"
|
|
|
|
echo.Rainbow "-p/--port Specify printer port (skips popup)"
|
|
|
|
exit 0
|
|
|
|
fi
|
2024-04-08 04:50:36 +00:00
|
|
|
# Pull Klipper
|
|
|
|
git submodule update --init --recursive
|
|
|
|
|
2024-08-06 02:15:04 +00:00
|
|
|
# Install packages
|
2024-08-06 17:48:45 +00:00
|
|
|
if [[ "$ARG_SKIP_APT" == 1 ]]; then
|
|
|
|
echo.ICyan "Apt packagees skipped"
|
|
|
|
else
|
|
|
|
echo.Cyan "Installing required packageas"
|
|
|
|
for PACKAGE in `cat $ROOT_DIR/config/apt-packages`; do
|
|
|
|
sudo apt install -y $PACKAGE
|
|
|
|
done
|
|
|
|
fi
|
2024-08-06 00:31:28 +00:00
|
|
|
|
|
|
|
# Name Printer
|
2024-08-06 17:48:45 +00:00
|
|
|
PRINTER_NAME=""
|
|
|
|
if [[ "$ARG_NAME" == 0 ]]; then
|
|
|
|
NAME_NOT_VALID=true
|
|
|
|
while $NAME_NOT_VALID ; do
|
|
|
|
PRINTER_NAME=$(dialog --backtitle 'drwho@hackers.town' --inputbox 'Name This Printer' 8 40 "${PRINTER_NAME}" 3>&1 1>&2 2>&3)
|
|
|
|
if [[ $PRINTER_NAME =~ ^[a-zA-Z0-9_-]+$ ]]; then
|
|
|
|
NAME_NOT_VALID=false
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
else
|
|
|
|
echo.ICyan "Using passed printer name: $ARG_NAME"
|
|
|
|
PRINTER_NAME="$ARG_NAME"
|
|
|
|
fi
|
2024-08-06 00:31:28 +00:00
|
|
|
|
|
|
|
cp -r $ROOT_DIR/dirs $ROOT_DIR/$PRINTER_NAME
|
|
|
|
|
2024-04-08 04:50:36 +00:00
|
|
|
# Select Klipper Config
|
2024-08-06 00:31:28 +00:00
|
|
|
cd $ROOT_DIR/$PRINTER_NAME/klipper
|
2024-04-08 04:50:36 +00:00
|
|
|
make menuconfig
|
2024-08-06 17:48:45 +00:00
|
|
|
CONFIG_FILE=""
|
|
|
|
if [[ "$ARG_CONFIG" == 0 ]]; then
|
|
|
|
CONFIG_FILES=(`ls config`)
|
|
|
|
CONFIG_FILES+=("Enter_Manually")
|
|
|
|
let i=0
|
|
|
|
C=()
|
|
|
|
for f in ${CONFIG_FILES[@]}; do
|
|
|
|
C+=($i $f)
|
|
|
|
let i+=1
|
2024-04-30 00:37:05 +00:00
|
|
|
done
|
2024-08-06 17:48:45 +00:00
|
|
|
CONFIG_INDEX=$(dialog --backtitle "drwho@hackers.town" --title "Printer Selection" --menu "Select Printer Config" --output-fd 1 40 0 1 ${C[@]})
|
|
|
|
CONFIG_FILE=${CONFIG_FILES[$CONFIG_INDEX]}
|
|
|
|
if [[ $CONFIG_FILE == "Enter_Manually" ]]; then
|
|
|
|
MANUAL_FILE=""
|
|
|
|
while [ ! -f "${MANUAL_FILE}" ]; do
|
|
|
|
MANUAL_FILE=$(dialog --backtitle "drwho@hackers.town" --title "Manual Config Selection" --inputbox "Enter Full Config File Path" 8 40 "${MANUAL_FILE}" 3>&1 1>&2 2>&3)
|
|
|
|
done
|
|
|
|
CONFIG_FILE=$MANUAL_FILE
|
|
|
|
else
|
|
|
|
# TODO: maybe replace this with the full path?
|
|
|
|
CONFIG_FILE="./config/$CONFIG_FILE"
|
|
|
|
fi
|
2024-04-30 00:37:05 +00:00
|
|
|
else
|
2024-08-06 17:48:45 +00:00
|
|
|
echo.ICyan "Using passed config file"
|
|
|
|
CONFIG_FILE="$ARG_CONFIG"
|
2024-04-30 00:37:05 +00:00
|
|
|
fi
|
2024-04-08 04:50:36 +00:00
|
|
|
|
|
|
|
# Select Serial Device
|
2024-08-06 17:48:45 +00:00
|
|
|
DEVICE=""
|
|
|
|
if [[ "$ARG_PORT" == 0 ]]; then
|
|
|
|
DEVICES=(`ls /dev/serial/by-id/`)
|
|
|
|
DEVICES+=("Enter_Manually")
|
|
|
|
let i=0
|
|
|
|
C=()
|
|
|
|
for f in ${DEVICES[@]}; do
|
|
|
|
C+=($i $f)
|
|
|
|
let i+=1
|
2024-04-30 00:37:05 +00:00
|
|
|
done
|
2024-08-06 17:48:45 +00:00
|
|
|
DEVICE_INDEX=$(dialog --backtitle "drwho@hackers.town" --title "USB Device Selection" --menu "Select USB Device" --output-fd 1 40 0 1 ${C[@]})
|
|
|
|
DEVICE=${DEVICES[$DEVICE_INDEX]}
|
|
|
|
|
|
|
|
if [[ $DEVICE == "Enter_Manually" ]]; then
|
|
|
|
MANUAL_FILE=""
|
|
|
|
while [ ! -f "${MANUAL_FILE}" ]; do
|
|
|
|
MANUAL_FILE=$(dialog --backtitle "drwho@hackers.town" --title "Manual Device Selection" --inputbox "Enter Full Device File Path" 8 40 "${MANUAL_FILE}" 3>&1 1>&2 2>&3)
|
|
|
|
done
|
|
|
|
DEVICE="/dev/serial/by-id/$MANUAL_FILE"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
echo.ICyan "Using passed serial port"
|
|
|
|
DEVICE="$ARG_PORT"
|
2024-04-30 00:37:05 +00:00
|
|
|
fi
|
|
|
|
|
2024-04-08 04:50:36 +00:00
|
|
|
# Build Klipper
|
2024-08-06 17:48:45 +00:00
|
|
|
echo.Cyan "Compile Klipper Firmware"
|
2024-08-06 00:31:28 +00:00
|
|
|
cp $CONFIG_FILE $ROOT_DIR/$PRINTER_NAME/klipper/printer.cfg
|
2024-08-06 17:48:45 +00:00
|
|
|
sed -i -e "s/^serial: .\+$/LINEHERE/g" "$ROOT_DIR/$PRINTER_NAME/klipper/printer.cfg"
|
|
|
|
cat $ROOT_DIR/$PRINTER_NAME/klipper/printer.cfg | replace "LINEHERE" "serial: $DEVICE" > $ROOT_DIR/$PRINTER_NAME/klipper/tmp.cfg
|
|
|
|
rm $ROOT_DIR/$PRINTER_NAME/klipper/printer.cfg
|
|
|
|
mv $ROOT_DIR/$PRINTER_NAME/klipper/tmp.cfg $ROOT_DIR/$PRINTER_NAME/klipper/printer.cfg
|
2024-04-08 04:50:36 +00:00
|
|
|
make -j$(nproc)
|
|
|
|
|
|
|
|
# Flash Firmware
|
2024-08-06 17:48:45 +00:00
|
|
|
echo.Cyan "Flash Device"
|
|
|
|
make flash FLASH_DEVICE=$DEVICE
|
2024-04-08 04:50:36 +00:00
|
|
|
|
|
|
|
# Copy over printer config file
|
2024-08-06 00:47:48 +00:00
|
|
|
echo.Cyan "Setup printer.cfg"
|
2024-08-06 00:31:28 +00:00
|
|
|
cd $ROOT_DIR/$PRINTER_NAME
|
2024-04-09 01:22:35 +00:00
|
|
|
cat $ROOT_DIR/config/macros.gcode >> printer.cfg.tmp
|
|
|
|
cat klipper/printer.cfg >> printer.cfg.tmp
|
|
|
|
mv printer.cfg.tmp printer_data/config/printer.cfg
|
2024-04-08 04:50:36 +00:00
|
|
|
|
|
|
|
# Apply Edits to Configs
|
2024-08-06 00:56:06 +00:00
|
|
|
echo.Cyan "Setup Moonraker"
|
2024-08-06 00:31:28 +00:00
|
|
|
cd $ROOT_DIR/$PRINTER_NAME/printer_data/config
|
2024-07-30 01:18:31 +00:00
|
|
|
sed -i -e "s/PRINTERNAME/$PRINTER_NAME/g" "moonraker.conf"
|
2024-08-06 00:31:28 +00:00
|
|
|
sed -i -e "s/pi/$USER/g" "moonraker.conf"
|
2024-08-06 02:39:32 +00:00
|
|
|
cat "moonraker.conf" | replace "~/" "$HOME/" > m.tmp
|
|
|
|
rm moonraker.conf
|
|
|
|
mv m.tmp moonraker.conf
|
|
|
|
NUM_OF_PRIOR_INSTALLS=`ls /etc/systemd/system/*-klipper.service | wc -l`
|
|
|
|
NEW_PORT=$((NUM_OF_PRIOR_INSTALLS + 7125))
|
|
|
|
echo.ICyan "Using port ${NEW_PORT} for Moonraker"
|
|
|
|
sed -i -e "s/PORT/$NEW_PORT/g" "moonraker.conf"
|
2024-08-06 01:07:52 +00:00
|
|
|
|
2024-08-06 00:47:48 +00:00
|
|
|
echo.Cyan "Setup Mainsail Config"
|
2024-08-06 00:31:28 +00:00
|
|
|
cd $ROOT_DIR/$PRINTER_NAME/mainsail-config
|
2024-08-06 01:24:18 +00:00
|
|
|
cat "client.cfg" | replace "~/printer_data" "$HOME/$PRINTER_NAME/printer_data" > tmp.client.cfg
|
|
|
|
rm client.cfg
|
|
|
|
mv tmp.client.cfg client.cfg
|
2024-08-06 00:31:28 +00:00
|
|
|
sed -i -e "s/pi/$USER/g" "client.cfg"
|
2024-04-09 01:22:35 +00:00
|
|
|
|
2024-04-09 00:31:37 +00:00
|
|
|
# Download Mainsail
|
|
|
|
cd $ROOT_DIR
|
2024-08-06 00:47:48 +00:00
|
|
|
echo.Cyan "Downloading Mainsail"
|
2024-04-09 00:31:37 +00:00
|
|
|
wget -q -O mainsail.zip https://github.com/mainsail-crew/mainsail/releases/latest/download/mainsail.zip
|
2024-08-06 00:31:28 +00:00
|
|
|
unzip -o mainsail.zip -d $PRINTER_NAME/mainsail
|
|
|
|
rm mainsail.zip
|
2024-08-06 17:48:45 +00:00
|
|
|
|
|
|
|
echo.ICyan "Installing base nginx configs"
|
|
|
|
if [ ! -f /etc/nginx/conf.d/upstreams.conf ]; then
|
|
|
|
sudo cp $ROOT_DIR/config/nginx/upstreams.conf /etc/nginx/conf.d/upstreams.conf
|
|
|
|
sudo chown root:root /etc/nginx/conf.d/upstreams.conf
|
|
|
|
else
|
|
|
|
echo.ICyan "upstreams.conf already exists"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ! -f /etc/nginx/sites-available/site.conf ]; then
|
|
|
|
sudo cp $ROOT_DIR/config/nginx/site.conf /etc/nginx/sites-available/site.conf
|
|
|
|
sudo chown root:root /etc/nginx/sites-available/site.conf
|
|
|
|
else
|
|
|
|
echo.ICyan "site.conf already exists"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ! -f /etc/nginx/conf.d/common_vars.conf ]; then
|
|
|
|
sudo cp $ROOT_DIR/config/nginx/common_vars.conf /etc/nginx/conf.d/common_vars.conf
|
|
|
|
sudo chown root:root /etc/nginx/conf.d/common_vars.conf
|
|
|
|
else
|
|
|
|
echo.ICyan "common_vars.conf already exists"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ! -d /etc/nginx/mainsail/sites ]; then
|
|
|
|
sudo mkdir -p /etc/nginx/mainsail/sites
|
|
|
|
fi
|
|
|
|
if [ ! -d /etc/nginx/mainsail/upstream ]; then
|
|
|
|
sudo mkdir -p /etc/nginx/mainsail/upstream
|
|
|
|
fi
|
|
|
|
if [ ! -d /etc/nginx/mainsail/proxy ]; then
|
|
|
|
sudo mkdir -p /etc/nginx/mainsail/proxy
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo.Cyan "Generate and Install $PRINTER_NAME nginx configs"
|
|
|
|
cat $ROOT_DIR/config/nginx/mainsail-upstream.conf | replace "PRINTERNAMELC" "${PRINTER_NAME,,}" | replace "PORT" "$NEW_PORT" > $ROOT_DIR/$PRINTER_NAME/upstream.conf
|
|
|
|
PROXY_PORT=$((NEW_PORT - 7000 + 8000))
|
|
|
|
cat $ROOT_DIR/config/nginx/mainsail-site.conf | replace "PRINTERNAMELC" "${PRINTER_NAME,,}" | replace "/home/pi" "$HOME" | replace "PRINTERNAME" "$PRINTER_NAME" | replace "PORT" "$PROXY_PORT" > $ROOT_DIR/$PRINTER_NAME/site.conf
|
|
|
|
cat $ROOT_DIR/config/nginx/mainsail-proxy.conf | replace "PRINTERNAMELC" "${PRINTER_NAME,,}" | replace "PORT" "$PROXY_PORT" > $ROOT_DIR/$PRINTER_NAME/proxy.conf
|
|
|
|
# add proxy
|
|
|
|
sudo cp $ROOT_DIR/$PRINTER_NAME/upstream.conf /etc/nginx/mainsail/upstream/$PRINTER_NAME.conf
|
|
|
|
sudo cp $ROOT_DIR/$PRINTER_NAME/site.conf /etc/nginx/sites-available/$PRINTER_NAME.conf
|
|
|
|
sudo cp $ROOT_DIR/$PRINTER_NAME/proxy.conf /etc/nginx/mainsail/proxy/$PRINTER_NAME.conf
|
|
|
|
sudo ln -s /etc/nginx/sites-available/$PRINTER_NAME.conf /etc/nginx/sites-enabled/$PRINTER_NAME.conf
|
|
|
|
|
|
|
|
sudo chown -R root:root /etc/nginx/mainsail
|
|
|
|
if [ -f /etc/nginx/sites-enabled/site.conf ]; then
|
|
|
|
echo.ICyan "Restart nginx if the site is already enabled"
|
|
|
|
sudo systemctl stop nginx
|
|
|
|
fi
|
2024-04-09 00:47:55 +00:00
|
|
|
|
2024-08-06 14:17:33 +00:00
|
|
|
# Setup klipper python env
|
|
|
|
echo.Cyan "Setup Klipper Python Virtual Environment"
|
2024-08-06 02:15:04 +00:00
|
|
|
cd $ROOT_DIR/$PRINTER_NAME
|
|
|
|
/usr/bin/virtualenv klippy-env
|
|
|
|
$ROOT_DIR/$PRINTER_NAME/klippy-env/bin/pip install -r $ROOT_DIR/$PRINTER_NAME/klipper/scripts/klippy-requirements.txt
|
2024-08-08 13:15:53 +00:00
|
|
|
touch $ROOT_DIR/$PRINTER_NAME/printer_data/comms/klippy.sock
|
2024-08-06 02:15:04 +00:00
|
|
|
|
2024-08-06 14:17:33 +00:00
|
|
|
# Setup moonraker python env
|
|
|
|
echo.Cyan "Setup Moonraker Python Virtual Environment"
|
|
|
|
cd $ROOT_DIR/$PRINTER_NAME
|
|
|
|
/usr/bin/virtualenv moonraker-env
|
|
|
|
$ROOT_DIR/$PRINTER_NAME/moonraker-env/bin/pip install -r $ROOT_DIR/$PRINTER_NAME/moonraker/scripts/moonraker-requirements.txt
|
|
|
|
|
2024-08-06 02:15:04 +00:00
|
|
|
# Configure Systemd Environment Files
|
|
|
|
echo.Cyan "Config Systemd Envs"
|
|
|
|
cd $ROOT_DIR/$PRINTER_NAME/printer_data/systemd
|
|
|
|
for ENV in *.env; do
|
|
|
|
cat "$ENV" | replace "/home/pi" "$HOME" | replace "PRINTERNAME" "$PRINTER_NAME" | replace "PRINTERDATA" "$PRINTER_NAME"> "$ENV.tmp"
|
|
|
|
rm "$ENV"
|
|
|
|
mv "$ENV.tmp" "$ENV"
|
|
|
|
done
|
|
|
|
|
2024-04-09 01:22:35 +00:00
|
|
|
# Copy To Final Location
|
2024-08-06 00:47:48 +00:00
|
|
|
echo.Cyan "Run Copy"
|
2024-08-06 00:31:28 +00:00
|
|
|
mkdir -p $HOME/$PRINTER_NAME
|
2024-08-06 02:15:04 +00:00
|
|
|
cp -r $ROOT_DIR/$PRINTER_NAME/* $HOME/$PRINTER_NAME
|
2024-04-09 01:22:35 +00:00
|
|
|
|
2024-08-06 00:56:06 +00:00
|
|
|
# Create Empty dirs
|
2024-08-06 02:31:47 +00:00
|
|
|
dirs=(logs gcodes certs backup)
|
2024-08-06 00:56:06 +00:00
|
|
|
for d in ${dirs[@]}; do
|
2024-08-06 02:31:47 +00:00
|
|
|
D="$HOME/$PRINTER_NAME/printer_data/$d"
|
|
|
|
echo.ICyan "make $D"
|
|
|
|
mkdir -p $D
|
2024-04-09 01:22:35 +00:00
|
|
|
done
|
|
|
|
|
2024-08-06 02:31:47 +00:00
|
|
|
touch $HOME/$PRINTER_NAME/printer_data/logs/klippy.log
|
|
|
|
|
2024-04-09 01:22:35 +00:00
|
|
|
# Configure System Services
|
|
|
|
cd $ROOT_DIR/config/services
|
|
|
|
SERVICES=()
|
|
|
|
for f in *.service; do
|
2024-08-06 00:47:48 +00:00
|
|
|
echo.Cyan "Setup ${f}"
|
2024-04-09 01:22:35 +00:00
|
|
|
SERVICES+=($f)
|
2024-08-06 00:31:28 +00:00
|
|
|
cp "${f}" "${ROOT_DIR}/${PRINTER_NAME}/${PRINTER_NAME}-${f}"
|
|
|
|
sed -i -e "s/PRINTERNAME/$PRINTER_NAME/g" "${ROOT_DIR}/${PRINTER_NAME}/${PRINTER_NAME}-${f}"
|
2024-08-06 00:56:06 +00:00
|
|
|
sed -i -e "s/pi/$USER/g" "${ROOT_DIR}/${PRINTER_NAME}/${PRINTER_NAME}-${f}"
|
2024-04-09 01:22:35 +00:00
|
|
|
done
|
|
|
|
|
2024-04-09 00:47:55 +00:00
|
|
|
# Install System Services
|
2024-08-06 00:47:48 +00:00
|
|
|
echo.Cyan "Install Services"
|
2024-08-06 00:31:28 +00:00
|
|
|
sudo cp $ROOT_DIR/$PRINTER_NAME/*.service /etc/systemd/system/
|
2024-04-09 01:22:35 +00:00
|
|
|
sudo systemctl daemon-reload
|
|
|
|
for svc in ${SERVICES[@]}; do
|
|
|
|
sudo systemctl enable $PRINTER_NAME-$svc
|
|
|
|
sudo systemctl start $PRINTER_NAME-$svc
|
|
|
|
done
|
2024-07-30 01:18:31 +00:00
|
|
|
|
|
|
|
# Cleanup
|
2024-08-06 17:51:18 +00:00
|
|
|
$HOME/$PRINTER_NAME/moonraker/scripts/set-policykit-rules.sh -z
|
2024-08-08 13:15:53 +00:00
|
|
|
ln -s $HOME/$PRINTER_NAME/mainsail-config/client.cfg $HOME/$PRINTER_NAME/printer_data/config/mainsail.cfg
|
|
|
|
sudo systemctl restart $PRINTER_NAME-klipper.service
|
2024-08-06 17:51:18 +00:00
|
|
|
sudo systemctl restart $PRINTER_NAME-moonraker.service
|
2024-08-06 17:48:45 +00:00
|
|
|
echo.BoldCyan "${PRINTER_NAME} is setup with moonraker on port ${NEW_PORT}"
|
|
|
|
sudo nginx -t
|
|
|
|
if [ ! -f /etc/nginx/sites-enabled/site.conf ]; then
|
|
|
|
echo.Red "NGINX config not enabled, don't forget to symlink the site.conf file from sites-available to sites-enabled"
|
|
|
|
else
|
|
|
|
sudo systemctl start nginx
|
|
|
|
fi
|