Skip to content

Instantly share code, notes, and snippets.

@austenc
Created September 23, 2014 23:10
Show Gist options
  • Save austenc/71d4c7cf4110aca87b09 to your computer and use it in GitHub Desktop.
Save austenc/71d4c7cf4110aca87b09 to your computer and use it in GitHub Desktop.
Linode stackscript - LEMP box
#!/bin/bash
# This block defines the variables the user of the script needs to input
# when deploying using this script.
#
#<UDF name="HOSTNAME" label="The hostname for the new Linode">
#<UDF name="FQDN" label="The new Linode's Fully Qualified Domain Name">
#<UDF name="USER" label="Main (non-root) username">
#<UDF name="USER_PASS" label="Main (non-root) user's password">
#<UDF name="INSTALL_MYSQL" label="Install MySQL?" oneOf="Yes,No">
#<UDF name="MYSQL_ROOT_PW" label="MySQL root user password">
#<UDF name="MYSQL_USER" label="Other MySQL user (a database will also be created with this name)">
#<UDF name="MYSQL_USER_PW" label="Other MySQL user's password">
#<UDF name="INSTALL_NODE" label="Install Node, Grunt and Bower?" oneOf="Yes,No">
#<UDF name="INSTALL_ENVOY" label="Install Laravel's Envoy?" oneOf="Yes,No">
#<UDF name="PHP_MEMORY_LIMIT" label="PHP's memory limit (default 128M)" default="128">
# Include some helpful linode scripts.
source <ssinclude StackScriptID=1>
# This sets the variable $IPADDR to the IP address the new Linode receives.
IPADDR=$(/sbin/ifconfig eth0 | awk '/inet / { print $2 }' | sed 's/addr://')
# -----------------------------------------------------------------------------
# Update System
# -----------------------------------------------------------------------------
system_update
# Install Some PPAs
# -----------------------------------------------------------------------------
sudo apt-get install -y software-properties-common
sudo apt-add-repository ppa:nginx/stable -y
sudo apt-add-repository ppa:rwky/redis -y
sudo apt-add-repository ppa:chris-lea/node.js -y
sudo apt-add-repository ppa:ondrej/php5 -y
# Update package list
# -----------------------------------------------------------------------------
sudo apt-get update
# Add main user
# -----------------------------------------------------------------------------
sudo apt-get install -y sudo
sudo adduser $USER --gecos "" --disabled-password --force-badname
echo "$USER:$USER_PASS" | sudo chpasswd
sudo usermod -aG sudo $USER
# Set the hostname
# -----------------------------------------------------------------------------
echo $HOSTNAME > /etc/hostname
hostname -F /etc/hostname
# Set Fully Qualified Domain Name (FQDN) in the hosts file
# -----------------------------------------------------------------------------
echo $IPADDR $FQDN $HOSTNAME >> /etc/hosts
# Install Some Basic Packages
# -----------------------------------------------------------------------------
sudo apt-get install -y build-essential curl dos2unix gcc git libmcrypt4 libpcre3-dev \
make python2.7-dev python-pip re2c supervisor unattended-upgrades whois vim
# Install A Few Helpful Python Packages
# -----------------------------------------------------------------------------
sudo pip install httpie
sudo pip install fabric
sudo pip install python-simple-hipchat
# Set Timezone
# -----------------------------------------------------------------------------
sudo ln -sf /usr/share/zoneinfo/UTC /etc/localtime
# Install PHP / Extensions
# -----------------------------------------------------------------------------
sudo apt-get install -y php5-cli php5-dev php-pear \
php5-mysqlnd php5-pgsql php5-sqlite \
php5-apcu php5-json php5-curl php5-gd \
php5-gmp php5-imap php5-mcrypt php5-xdebug \
php5-memcached php5-redis --force-yes
# Make MCrypt Available
sudo ln -s /etc/php5/conf.d/mcrypt.ini /etc/php5/mods-available
sudo php5enmod mcrypt
# Install Mailparse PECL Extension
sudo pecl install mailparse || true
sudo echo "extension=mailparse.so" > /etc/php5/mods-available/mailparse.ini
sudo ln -s /etc/php5/mods-available/mailparse.ini /etc/php5/cli/conf.d/20-mailparse.ini
# Install Composer
# -----------------------------------------------------------------------------
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
# Add Composer Global Bin To Path
printf "\nPATH=\"home/$USER/.composer/vendor/bin:\$PATH\"\n" | tee -a /home/$USER/.profile
# Install Laravel Envoy
# -----------------------------------------------------------------------------
if [ "$INSTALL_ENVOY" == "Yes" ]
then
sudo su $USER << 'EOF'
/usr/local/bin/composer global require "laravel/envoy=~1.0"
EOF
fi
# Set Some PHP CLI Settings
# -----------------------------------------------------------------------------
sudo sed -i "s/error_reporting = .*/error_reporting = E_ALL/" /etc/php5/cli/php.ini
sudo sed -i "s/display_errors = .*/display_errors = On/" /etc/php5/cli/php.ini
sudo sed -i "s/memory_limit = .*/memory_limit = ${PHP_MEMORY_LIMIT}M/" /etc/php5/cli/php.ini
sudo sed -i "s/;date.timezone.*/date.timezone = UTC/" /etc/php5/cli/php.ini
# Install Nginx & PHP-FPM
# -----------------------------------------------------------------------------
sudo apt-get -y --force-yes install nginx php5-fpm
sudo rm /etc/nginx/sites-enabled/default
sudo rm /etc/nginx/sites-available/default
sudo service nginx restart
# Setup Some PHP-FPM Options
sudo ln -s /etc/php5/mods-available/mailparse.ini /etc/php5/fpm/conf.d/20-mailparse.ini
sudo sed -i "s/error_reporting = .*/error_reporting = E_ALL|E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR/" /etc/php5/fpm/php.ini
sudo sed -i "s/display_errors = .*/display_errors = Off/" /etc/php5/fpm/php.ini
sudo sed -i "s/log_errors = .*/log_errors = On/" /etc/php5/fpm/php.ini
sudo sed -i "s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/" /etc/php5/fpm/php.ini
sudo sed -i "s/memory_limit = .*/memory_limit = ${PHP_MEMORY_LIMIT}M/" /etc/php5/fpm/php.ini
sudo sed -i "s/;date.timezone.*/date.timezone = UTC/" /etc/php5/fpm/php.ini
# Set The Nginx & PHP-FPM User
sudo sed -i "s/user www-data;/user $USER;/" /etc/nginx/nginx.conf
sudo sed -i "s/# server_names_hash_bucket_size.*/server_names_hash_bucket_size 64;/" /etc/nginx/nginx.conf
sudo sed -i "s/user = www-data/user = $USER/" /etc/php5/fpm/pool.d/www.conf
sudo sed -i "s/group = www-data/group = $USER/" /etc/php5/fpm/pool.d/www.conf
sudo sed -i "s/;listen\.owner.*/listen.owner = $USER/" /etc/php5/fpm/pool.d/www.conf
sudo sed -i "s/;listen\.group.*/listen.group = $USER/" /etc/php5/fpm/pool.d/www.conf
sudo sed -i "s/;listen\.mode.*/listen.mode = 0666/" /etc/php5/fpm/pool.d/www.conf
service nginx restart
service php5-fpm restart
# Add User To WWW-Data
# -----------------------------------------------------------------------------
usermod -a -G www-data $USER
id $USER
groups $USER
# Install Node and Grunt
# -----------------------------------------------------------------------------
if [ "$INSTALL_NODE" == "Yes" ]
then
apt-get install -y nodejs
npm install -g grunt-cli
npm install -g bower
fi
# MySQL install and tune
# -----------------------------------------------------------------------------
if [ "$INSTALL_MYSQL" == "Yes" ]
then
mysql_install $MYSQL_ROOT_PW
mysql_tune
# Create mysql user
mysql_create_user $MYSQL_ROOT_PW $MYSQL_USER $MYSQL_USER_PW
# Create database for the user
mysql_create_database $MYSQL_ROOT_PW $MYSQL_USER
# Grant / flush privileges
mysql_grant_user $MYSQL_ROOT_PW $MYSQL_USER $MYSQL_USER
service mysql restart
fi
# Install Redis, Memcached, Beanstalkd
# -----------------------------------------------------------------------------
apt-get install -y redis-server memcached beanstalkd
# Configure Beanstalkd
sudo sed -i "s/#START=yes/START=yes/" /etc/default/beanstalkd
sudo /etc/init.d/beanstalkd start
# IPtables firewall rules
# -----------------------------------------------------------------------------
cat > /etc/iptables.firewall.rules << EOF
*filter
# Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT
# Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT
# Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# Allow SSH connections
#
# The -dport number should be the same port number you set in sshd_config
#
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT
# Allow ping
-A INPUT -p icmp -j ACCEPT
# Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
# Drop all other inbound - default deny unless explicitly allowed policy
-A INPUT -j DROP
-A FORWARD -j DROP
COMMIT
EOF
# now start the firewall
sudo iptables-restore < /etc/iptables.firewall.rules
# and ensure it starts on boot
cat > /etc/network/if-pre-up.d/firewall << EOF
#!/bin/sh
/sbin/iptables-restore < /etc/iptables.firewall.rules
EOF
sudo chmod +x /etc/network/if-pre-up.d/firewall
# vim, less, colors, etc.. from linode
# -----------------------------------------------------------------------------
goodstuff
# Fail2Ban (prevents attacks by monitoring logfiles and temporarily blocking IP's after too many failed)
# -----------------------------------------------------------------------------
sudo apt-get install -y Fail2Ban
# Disable direct root login via SSH
# -----------------------------------------------------------------------------
sudo sed -i "s/PermitRootLogin yes/PermitRootLogin no/" /etc/ssh/sshd_config
sudo service ssh restart
# Copy some convenience files for working with nginx from laravel homestead
# -----------------------------------------------------------------------------
sudo wget -O /usr/share/serve.sh https://raw.githubusercontent.com/laravel/homestead/master/scripts/serve.sh
sudo chmod +x /usr/share/serve.sh
# create an alias for the serve command and a few others
# and ensure it starts on boot
cat >> /home/$USER/.bash_aliases << EOF
alias ..="cd .."
alias ...="cd ../.."
alias h='cd ~'
alias c='clear'
function serve() {
if [[ "\$1" && "\$2" ]]
then
sudo dos2unix /usr/share/serve.sh
sudo bash /usr/share/serve.sh "\$1" "\$2"
else
echo "Error: missing required parameters."
echo "Usage: "
echo " serve domain path"
fi
}
EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment