Skip to content

Instantly share code, notes, and snippets.

@rbrisita
Created August 16, 2017 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rbrisita/5eb3efb0167a9c631e82cf0db06bc704 to your computer and use it in GitHub Desktop.
Save rbrisita/5eb3efb0167a9c631e82cf0db06bc704 to your computer and use it in GitHub Desktop.
A non-interactive installation script for a Nginx Laravel application using MySQL on Ubuntu 16.04 LTS.
#!/usr/bin/env bash
#
# Author: Robert Brisita <[first-initial][last name] at gmail dot com>
#
# A non-interactive installation script for a Nginx Laravel application using MySQL.
#
# Tested on Ubuntu 16.04 LTS
#####
# Project details
# Used in creating project and MySQL schema and credentials.
# The database credentials mirror the DotEnv file (.env) Laravel uses.
#####
PROJECT_NAME=my_project
DB_SCHEMA=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
DB_ROOT_PASSWORD=secret
# Turn off interactive prompt on server installs.
DF_NI="DEBIAN_FRONTEND=noninteractive"
#####
# Update and Upgrade
#####
echo -e "\n*****\n* Updating Apt Package List.\n*****\n"
sudo apt-get update
echo -e "\n*****\n* Upgrade System Packages.\n*****\n"
sudo "${DF_NI}" apt-get -y upgrade
# Add the ability to add Personal Package Archive (PPA) (add-apt-repository) for more current software.
sudo "${DF_NI}" apt-get -y install software-properties-common
#####
# NGINX
#####
echo -e "\n*****\n* Install Nginx.\n*****\n"
sudo "${DF_NI}" apt-get -y install nginx
#####
# PHP
#####
echo -e "\n*****\n* Install PHP 7.1 and required packages.\n*****\n"
# Add PPA to get PHP 7.1.
sudo add-apt-repository -y ppa:ondrej/php
sudo apt-get update
# Install PHP
# fpm - Installed first to satisfy PHP dependency request.
# curl - This script and Composer needs curl to get some packages.
# unzip/zip - Allows composer and Laravel to download and extract packages.
# xml - Manipulate the dom.
# mbstring - Handle multi-byte strings.
sudo "${DF_NI}" apt-get -y install unzip php7.1-fpm php7.1 php7.1-curl php7.1-zip php7.1-xml php7.1-mbstring
# Install Composer
curl --silent --show-error https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
#####
# NGINX and PHP
#####
# Modify Nginx default server block to use PHP for dynamic processing.
# Copy file and create a new one.
NGINX_PATH="/etc/nginx/sites-available/"
DEFAULT_FILE="default"
DATE=$(date +%Y-%m-%d:%H:%M:%S)
sudo cp "${NGINX_PATH}${DEFAULT_FILE}" "${NGINX_PATH}backup_${DEFAULT_FILE}_${DATE}"
# https://www.nginx.com/resources/wiki/start/topics/examples/phpfcgi/
HOST_NAME=$(hostname)
sudo bash -c "cat > ${NGINX_PATH}${DEFAULT_FILE}" << EOF
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name ${HOST_NAME}.eastus.cloudapp.azure.com;
location / {
try_files \$uri \$uri/ /index.php?\$query_string;
}
location ~ [^/]\.php(/|$) {
# Secure path parsing.
include snippets/fastcgi-php.conf;
# Mitigate https://httpoxy.org/ vulnerabilities.
fastcgi_param HTTP_PROXY "";
fastcgi_pass unix:/run/php/php7.1-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
EOF
echo -e "\n*****\n* Restarting Nginx.\n*****\n"
sudo systemctl restart nginx
#####
# MYSQL
#####
# Cleanly get script directory.
# -f, --canonicalize - Follow every symlink, all but the last component must exist.
SCRIPT_DIR=$(readlink --canonicalize "${BASH_SOURCE[0]}")
SCRIPT_DIR=$(dirname "${SCRIPT_DIR}")
echo -e "\n*****\n* Installing MySQL and PHP driver.\n*****\n"
sudo "${DF_NI}" apt-get -y install mysql-server php7.1-mysql
echo -e "\n*****\n* Setting Password Lifetime to forever.\n*****\n"
MYSQL_CNF=/etc/mysql/mysql.conf.d/mysqld.cnf
PASSWORD_LIFETIME='default_password_lifetime = 0'
# Look for the above line in it's own line.
# -F, --fixed-strings - Interpret patterns as a set of fixed strings.
# -q, --quiet, --silent - Suppress normal output; search until a match is found.
# -x, --line-regexp - Only input lines selected against an entire fixed string.
grep --fixed-strings --silent --line-regexp "${PASSWORD_LIFETIME}" "${MYSQL_CNF}"
if [ "$?" -eq "0" ]
then
echo -e "\n*****\n* Password Lifetime to forever already set.\n*****\n"
else
# Configure MySQL Password Lifetime to forever.
sudo bash -c "cat >> ${MYSQL_CNF}" << EOF
${PASSWORD_LIFETIME}
EOF
fi
# Securely setup MySQL.
echo -e "\n*****\n* Securing MySQL.\n*****\n"
sudo "${SCRIPT_DIR}/./ni-msi.sh" "${DB_ROOT_PASSWORD}"
# Setup up database the Homestead way and mirror Laravel's .env file.
echo -e "\n*****\n* Creating user and database schema.\n*****\n"
sudo mysql --defaults-extra-file="${SCRIPT_DIR}/mysql_credentials.cnf" -e "CREATE USER IF NOT EXISTS '${DB_USERNAME}'@'0.0.0.0' IDENTIFIED BY '${DB_PASSWORD}';"
sudo mysql --defaults-extra-file="${SCRIPT_DIR}/mysql_credentials.cnf" -e "GRANT ALL ON *.* TO '${DB_USERNAME}'@'0.0.0.0' IDENTIFIED BY '${DB_PASSWORD}' WITH GRANT OPTION;"
sudo mysql --defaults-extra-file="${SCRIPT_DIR}/mysql_credentials.cnf" -e "GRANT ALL ON *.* TO '${DB_USERNAME}'@'%' IDENTIFIED BY '${DB_PASSWORD}' WITH GRANT OPTION;"
sudo mysql --defaults-extra-file="${SCRIPT_DIR}/mysql_credentials.cnf" -e "FLUSH PRIVILEGES;"
sudo mysql --defaults-extra-file="${SCRIPT_DIR}/mysql_credentials.cnf" -e "CREATE DATABASE IF NOT EXISTS ${DB_SCHEMA} character set UTF8mb4 collate utf8mb4_bin;"
echo -e "\n*****\n* Restarting MySQL.\n*****\n"
sudo systemctl restart mysql
#####
# NODEJS
#####
echo -e "\n*****\n* Install Node JS.\n*****\n"
# Add PPA for NodeJS 6.x.
curl --silent --location https://deb.nodesource.com/setup_6.x | sudo -E bash -
# Install Node.
sudo "${DF_NI}" apt-get -y install nodejs
#####
# LARAVEL PROJECT SPECIFIC
# At this point one can inject there own project here.
# This script creates a new one for simplicity.
#####
echo -e "\n*****\n* Creating Laravel Project.\n*****\n"
composer create-project --prefer-dist laravel/laravel ${PROJECT_NAME}
PROJECT_PATH="${HOME}/${PROJECT_NAME}"
# Install PHP project dependencies.
echo -e "\n*****\n* Install PHP Project Dependencies.\n*****\n"
composer install --working-dir="${PROJECT_PATH}"
# Install Node dependencies.
echo -e "\n*****\n* Install Node Dependencies.\n*****\n"
npm install --prefix "${PROJECT_PATH}/"
# Create authentication tables and views.
# Migrate tables.
# Using --force to skip production warning
echo -e "\n*****\n* Create MySQL Tables.\n*****\n"
sudo php "${PROJECT_PATH}"/artisan make:auth --force
sudo php "${PROJECT_PATH}"/artisan migrate --force
# Change access permissions to Laravel's framework and log directories.
STORAGE_PATH="${PROJECT_PATH}/storage"
sudo chown -R www-data "${STORAGE_PATH}/framework"
sudo chgrp -R www-data "${STORAGE_PATH}/framework"
sudo chmod -R 0775 "${STORAGE_PATH}/framework"
sudo chown -R www-data "${STORAGE_PATH}/logs"
sudo chgrp -R www-data "${STORAGE_PATH}/logs"
sudo chmod -R 0775 "${STORAGE_PATH}/logs"
# Symlink project's public folder to /var/www/html.
sudo rm -rf /var/www/html
sudo ln -s "${HOME}/${PROJECT_NAME}/public" /var/www/html
# You should see Laravel rendering on port 80.
echo -e "\n*****\n* Open: http://${HOST_NAME}.eastus.cloudapp.azure.com in a broswer!\n*****\n"
# EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment