Skip to content

Instantly share code, notes, and snippets.

@joseederangojr
Last active February 10, 2024 19:54
Show Gist options
  • Save joseederangojr/8c8eac6493cb1b8d3a7d6a5782e6eb54 to your computer and use it in GitHub Desktop.
Save joseederangojr/8c8eac6493cb1b8d3a7d6a5782e6eb54 to your computer and use it in GitHub Desktop.
Install LEMP, Redis, Certbot, and Supervisor
#!/usr/bin/env bash
set -e
: ${PHP_VERSION:="8.2"}
: ${NODE_VERSION:="20"}
: ${APP_REPO:="https://github.com/laravel/laravel.git"}
: ${MYSQL_ROOT_PASSWORD:=$(openssl rand -base64 32)}
: ${MYSQL_ICSP_USER:="icspdbadmin"}
: ${MYSQL_ICSP_DATABASE:="icspdb"}
: ${MYSQL_ICSP_PASSWORD:=$(openssl rand -base64 32)}
: ${CERTBOT_EMAIL:="m+$(date +%s)@gmail.com"}
read -p "Enter app domain: " APP_DOMAIN
if [[ -z "${APP_DOMAIN}" ]]; then
echo "app domain must be set"
exit 1;
fi
if [[ "$1" == "--local" ]];
then
NGINX_CONFIG_FILE="/etc/nginx/sites-available/default"
else
NGINX_CONFIG_FILE="/etc/nginx/sites-available/$APP_DOMAIN"
fi
apt-get update
apt-get upgrade -y
apt install wget ca-certificates lsb-release curl gpg build-essential software-properties-common curl zip unzip git gcc -y
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_VERSION.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
add-apt-repository ppa:ondrej/php -y
apt-get update
apt-get install git supervisor mysql-server ufw gnupg wget nginx certbot python3-certbot-nginx nodejs redis php${PHP_VERSION} php${PHP_VERSION}-fpm php${PHP_VERSION}-mbstring php${PHP_VERSION}-mysql php${PHP_VERSION}-mcrypt php${PHP_VERSION}-gd php${PHP_VERSION}-xml php${PHP_VERSION}-curl php${PHP_VERSION}-gettext php${PHP_VERSION}-zip php${PHP_VERSION}-bcmath php${PHP_VERSION}-soap php${PHP_VERSION}-redis -y
systemctl enable mysql
systemctl start mysql
systemctl enable nginx
systemctl start nginx
systemctl enable supervisor
systemctl start supervisor
systemctl enable redis-server
systemctl start redis-server
systemctl enable php${PHP_VERSION}-fpm
systemctl start php${PHP_VERSION}-fpm
curl -sS https://getcomposer.org/installer -o composer-setup.php
php composer-setup.php --install-dir=/usr/local/bin --filename=composer
mysql -e "
CREATE DATABASE IF NOT EXISTS ${MYSQL_ICSP_DATABASE} CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER IF NOT EXISTS '$MYSQL_ICSP_USER'@'%' IDENTIFIED WITH mysql_native_password BY '$MYSQL_ICSP_PASSWORD';
FLUSH PRIVILEGES;
GRANT ALL PRIVILEGES ON $MYSQL_ICSP_DATABASE.* TO '$MYSQL_ICSP_USER'@'%';
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '$MYSQL_ROOT_PASSWORD';
FLUSH PRIVILEGES;
"
ufw enable
ufw allow 'Nginx Full'
ufw reload
timedatectl set-timezone Africa/Johannesburg
locale-gen en_ZA.utf8
mkdir -p $HOME/apps
git clone $APP_REPO /var/www/$APP_DOMAIN
CURRENT_DIRECTORY=$(pwd)
cd /var/www/$APP_DOMAIN
export COMPOSER_ALLOW_SUPERUSER=1
composer install --no-dev
cp .env.example .env
sed -i "s|APP_ENV=.*|APP_ENV=production|g" .env
sed -i "s|APP_DEBUG=.*|APP_DEBUG=false|g" .env
sed -i "s|APP_URL=.*|APP_URL=https://$APP_DOMAIN|g" .env
sed -i "s|DB_DATABASE=.*|DB_DATABASE=$MYSQL_ICSP_DATABASE|g" .env
sed -i "s|DB_USERNAME=.*|DB_USERNAME=$MYSQL_ICSP_USER|g" .env
sed -i "s|DB_PASSWORD=.*|DB_PASSWORD='$MYSQL_ICSP_PASSWORD'|g" .env
sed -i "s|CACHE_DRIVER=.*|CACHE_DRIVER=redis|g" .env
sed -i "s|QUEUE_CONNECTION=.*|QUEUE_CONNECTION=redis|g" .env
sed -i "s|SESSION_DRIVER=.*|SESSION_DRIVER=redis|g" .env
php artisan key:generate
php artisan migrate
php artisan storage:link
cd $CURRENT_DIRECTORY
cat > $NGINX_CONFIG_FILE <<-EOF
server {
listen 80;
listen [::]:80;
server_name $APP_DOMAIN;
root /var/www/$APP_DOMAIN/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files \$uri \$uri/ /index.php?\$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
EOF
if [[ ! "$1" == "--local" ]];
then
ln -s /etc/nginx/sites-available/${APP_DOMAIN} /etc/nginx/sites-enabled/${APP_DOMAIN}
# Install certbot
certbot --agree-tos -n --nginx -d ${APP_DOMAIN} -m $CERTBOT_EMAIL
fi
nginx -t
systemctl restart nginx
mkdir -p $HOME/.logs/workers
touch $HOME/.logs/workers/worker.log
# Setup supervisor
cat > /etc/supervisor/conf.d/worker.conf <<-EOF
[program:worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/$APP_DOMAIN/artisan queue:work --sleep=3 --backoff=0 --queue=default --timeout=3600 --tries=1
autostart=1
autorestart=1
user=$USER
redirect_stderr=true
stdout_logfile=$HOME/.logs/workers/worker.log
stopwaitsecs=3600
EOF
supervisorctl reread
supervisorctl update
supervisorctl start worker:*
echo "* * * * * cd /var/www/$APP_DOMAIN && php artisan schedule:run >> /dev/null 2>&1" | sudo -u $USER crontab -
chown -R www-data:www-data /var/www/$APP_DOMAIN
systemctl restart nginx
echo "🎉 Congratulations!"
echo "✅ DB Name: ${MYSQL_ICSP_DATABASE}"
echo "✅ DB Username: ${MYSQL_ICSP_USER}"
echo "✅ DB Password: ${MYSQL_ICSP_PASSWORD}"
echo "✅ DB 'root' Password: ${MYSQL_ROOT_PASSWORD}"
echo "✅ URL: https://${APP_DOMAIN}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment