Gentoo LAMP Stack

by beladmin
5 deployments · 0 still active · last rev. 24 days ago

[421642] Install, configure and basic tuning of Apache 2.4.x, MySQL 5.7.x and PHP 7.x - can be used for production out-of-the box (small to medium traffic).

REQUIREMENT: at least 2GB of RAM+swap (**Nanode must manually allocate enough swap space before booting)

NOTE: This may take 3 hours++ to complete if running on Nanode (1vCPU, 1GB RAM).

BUG: 'emerge --config dev-db/mysql' tend to fail in starting mysqld if deploy from StackScript (which is no problem in actual shell), this can cause the root password never been set. An ugly hack is inserting mysqladmin right after mysql has been started. Alternately, manually set the root password once the StackScript finished.
- mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'super-secret-password'

NOTE: This script is intended to deploy directly (not suitable for include), works for Gentoo image only.

[13Aug2019] - Modified to allow include from other script as long TIMEZONE,HOSTNAME & FQDN is declared some where.

Compatible with: Gentoo
						#!/bin/bash

# LAMP StackScript for Gentoo
# [28Apr2019]:0.1 - Initial Draft
# [30Aug2019]:0.2 - Upd: Idempotent. To be able to source from other script. 
#                        However, TIMEZONE, HOSTNAME & FQDN must be declared somewhere.
#                   Upd: MYROOTPASSWORD default to "xxxxx2008"
#                   Upd: Check exist before proceed on settings on TIMEZONE, HOSTNAME & FQDN.
#                   Add: Download the latest version of PHPMyAdmin onto /var/www/localhost/htdocs
#                   Add: Apache MPM tuning              
#                   Add: PHP opcache on UDF options enable/disable (default is disable)
# [23Aug2019]:0.3 - Add: 1) bcmath for PHP. 2) dev-php/imagick (small size). 3) PHP_TARGETS in /etc/portage/make.conf

# StanckScript Variables
# 
#<UDF name="hostname" label="Hostname (do not use localhost)" example="myhost">
# HOSTNAME=
#
#<UDF name="fqdn" label="Fully Qualified Domain Name" example="www.mysite.com">
# FQDN=
#
#<UDF name="timezone" label="Time zone" example="Asia/Kuala_Lumpur">
# TIMEZONE=
#
#<UDF name="myrootpassword" label="MySQL root password">
# MYROOTPASSWORD=
#
#<UDF name="phpopcache" label="PHP opcache" oneOf="Enable,Disable" default="Disable">
# PHPOPCACHE=
#

echo " >> Setting local timezone to $TIMEZONE"
# set time zone 
if ! grep -q $TIMEZONE /etc/timezone; then 
   echo $TIMEZONE > /etc/timezone
   emerge --config sys-libs/timezone-data
fi

# script local variables
LOCALHOSTPATH="/var/www/localhost/htdocs"
LAMPSTARTTIME=$(date +"%F %T.%3N")
# -----------------------------------------------------------------
# If you want to sync repo and update portage (if any), un-comment the line below:
echo " >> Gentoo repo sync...."
if [ `emerge --sync -q | grep -c 'emerge --oneshot portage'` -gt "0" ]; then echo emerge -1q portage; else echo 'repo sync completed!'; fi

# configure hostname and /etc/hosts
IPADDR=$(ifconfig eth0 | awk '/inet / { print $2 }')
grep -q $HOSTNAME /etc/conf.d/hostname || sed -i "s/localhost/${HOSTNAME}/" /etc/conf.d/hostname
grep -q $FQDN /etc/hosts || echo $IPADDR  $FQDN  $HOSTNAME >> /etc/hosts
hostname $HOSTNAME

# Gentoo use flags for Apache MySQL PHP & etc..
cat <<EOL  > /etc/portage/package.use/amp
# for Apache & PHP
dev-libs/apr-util mysql
www-servers/apache threads apache2_modules_authn_dbd apache2_modules_dbd apache2_mpms_event
app-eselect/eselect-php apache2 fpm
dev-lang/php apache2 bcmath calendar cgi cjk curl curlwrappers ctype exif ftp fpm gd hash imap intl json mysql mysqli mysqlnd pdo soap sockets sodium spell ssl threads truetype tokenizer unicode wddx xml xmlreader xmlrpc xmlwriter zlib zip
media-gfx/imagemagick hdri jbig jpeg jpeg2k lcms lzma png tiff truetype webp -openmp
EOL

echo " >> compiling and installing (sit back and take you beer....)"
# MySQL 5.x (default use flags is good)
#MYSQLVER=$(emerge -p dev-db/mysql | awk '/dev-db\/mysql-5/{print $4}')  # anyway, emerge installation & config will work without to specify the minor version 
USE="perl server" emerge -q dev-db/mysql

[ -z "$MYROOTPASSWORD" ] && MYROOTPASSWORD="apple2008"  
sleep 5
# NOTE: config won't work if hostname="localhost"
echo -e "${MYROOTPASSWORD}\n${MYROOTPASSWORD}" | emerge --config dev-db/mysql

# Apache 2.4.x
emerge -q www-servers/apache

# PHP 7.x
PHPVER=$(emerge -p dev-lang/php | awk '/dev-lang\/php/{print $4}' | cut -d/ -f2 | cut -d- -f2 | awk -F. '{printf "%s.%s",$1,$2}')
grep -q 'PHP_TARGETS="php7' /etc/portage/make.conf || echo "PHP_TARGETS=\"php${PHPVER}\"" | sed "s/\./-/" >> /etc/portage/make.conf
emerge -q dev-lang/php
emerge -q dev-php/pecl-imagick

# configuration...
echo " >> configuring MySQL 5.7.x, Apache 2.4.x & PHP 7.x ...."
# configure MySQL (MySQL 5.7.x default config was good enough, 
#                  this is the minimum tuning that does/may help, the others doesn't help in normal condition) 
# (TODO: set value according to LINODE_RAM size - this is a reference for Nanode, value=RAM x nanode value)
if [ `grep -c '<::DONOTREPEAT::>' /etc/mysql/mysql.d/50-distro-server.cnf` -eq "0" ]; then
cat <<EOL >> /etc/mysql/mysql.d/50-distro-server.cnf

# **[`date '+%F'`] - Generated by StackScript - Gentoo LAMP Stack **<::DONOTREPEAT::>
# --------- Config Reference ---- based on 1GB RAM Nanode -------------------------------------
max_connections = 384
#sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
secure_file_priv = ""

# in general - not specific to any storage engines
sort_buffer_size = 512K

# InnoDB
innodb_buffer_pool_size = 256M
innodb_log_file_size = 128M
innodb_read_io_threads = 32
innodb_write_io_threads = 32

# myISAM
key_buffer_size = 32M
table_open_cache = 400
read_buffer_size = 1024K
read_rnd_buffer_size = 512K
EOL
fi

# configure Apache 2
# configure in-house log format
sed -i '/^LogF.*vhostio$/a LogFormat \"%v %h %t \\\"%r\\\" %>s size=%b in=%I out=%O (%D micro-sec)\" myvhostio' /etc/apache2/modules.d/00_mod_log_config.conf
sed -i '/^CustomLog/ s/common/myvhostio/' /etc/apache2/modules.d/00_mod_log_config.conf
## Advanced config on Apache2 event mpm
sed -i '/^<IfModule mpm_event_module>/,/^<\/IfModule>/ s/.*\?MinSpareThreads.*/        MinSpareThreads         4/'  /etc/apache2/modules.d/00_mpm.conf
sed -i '/^<IfModule mpm_event_module>/,/^<\/IfModule>/ s/.*\?MaxSpareThreads.*/        MaxSpareThreads         16/' /etc/apache2/modules.d/00_mpm.conf
sed -i '/^<IfModule mpm_event_module>/,/^<\/IfModule>/ s/.*\?ThreadsPerChild.*/        ThreadsPerChild         32/' /etc/apache2/modules.d/00_mpm.conf
sed -i '/^<IfModule mpm_event_module>/,/^<\/IfModule>/ s/.*\?MaxRequestWorkers.*/        MaxRequestWorkers       32/' /etc/apache2/modules.d/00_mpm.conf

# configure PHP (the directory name derived from PHP version in Gentoo)
PHPINI="/etc/php/apache2-php${PHPVER}/php.ini"
sed -i '/^max_execution_time/c  max_execution_time = 45' $PHPINI
sed -i '/^memory_limit/c  memory_limit = 256M' $PHPINI
sed -i '/^post_max_size/c  post_max_size = 196M' $PHPINI
sed -i '/^upload_max_filesize/c  upload_max_filesize = 160M' $PHPINI

# enable opcache [11/Jul/2019]
[ -z "$PHPOPCACHE" ] && PHPOPCACHE="Disable"
if [[ "$PHPOPCACHE" == "Enable" ]]; then
sed -i "/opcache.enable=/c opcache.enable=1" $PHPINI
sed -i '/opcache.memory_consumption/c opcache.memory_consumption=256' $PHPINI
sed -i '/opcache.validate_timestamps/c opcache.validate_timestamps=0'  $PHPINI
sed -i '/opcache.enable_file_override/c opcache.enable_file_override=1'  $PHPINI
sed -i '/opcache.save_comments/c opcache.save_comments=0' $PHPINI
sed -i '/opcache.log_verbosity_level/ s/^;//'   $PHPINI
sed -i '/opcache.optimization_level/ s/^;//'    $PHPINI
sed -i '/opcache.max_accelerated_files/ s/^;//'  $PHPINI
sed -i '/opcache.interned_string_buffer/ s/^;//' $PHPINI
sed -i '/opcache.huge_code_pages/ s/^;//' $PHPINI
fi

sed -i "/^;\?date.timezone/c  date.timezone = '${TIMEZONE}'" /etc/php/*/php.ini
# PHP cli
sed -i '/^post_max_size/c  post_max_size = 100M' /etc/php/cli-php${PHPVER}/php.ini
sed -i '/^upload_max_filesize/c  upload_max_filesize = 95M' /etc/php/cli-php${PHPVER}/php.ini

# enable PHP
sed -i 's/-D LANGUAGE/& -D PHP/' /etc/conf.d/apache2

# add to defailt run level
rc-update add mysql default
rc-update add apache2 default

# run the services
/etc/init.d/mysql start
/etc/init.d/apache2 start

## ugly hack...
mysqladmin password ${MYROOTPASSWORD}

# get the latest phpMyAdmin and extract to the localhost/htdocs
wget https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.tar.gz
tar -xzvf phpMyAdmin-latest-all-languages.tar.gz -C $LOCALHOSTPATH
mv ${LOCALHOSTPATH}/phpMyAdmin-* ${LOCALHOSTPATH}/phpmyadmin
rm phpMyAdmin-*.tar.gz

echo " >>"
echo " >> Gentoo LAMP stack installation completed"
echo " >> Start Time: ${LAMPSTARTTIME}"
echo " >> End Time  : `date +'%F %T.%3N'`"