Skip to content

Instantly share code, notes, and snippets.

@quicksketch
Created April 18, 2016 18:20
Show Gist options
  • Save quicksketch/3070c757482f2335d72917223957bc76 to your computer and use it in GitHub Desktop.
Save quicksketch/3070c757482f2335d72917223957bc76 to your computer and use it in GitHub Desktop.
General setup instructions for Drupal/Backdrop on nginx
# Server configuration for example.com
server {
# Require HTTP authentication.
#auth_basic "Restricted";
#auth_basic_user_file /home/example/.htpasswd;
# Limit each user to 20 max connections.
limit_conn default 20;
# Set up ports and server address.
listen 80;
listen 443 ssl;
server_name .example.com;
root /home/example/www;
# Specify certificates used globally.
ssl_certificate /home/example/certs/example-com.crt;
ssl_certificate_key /home/example/certs/example-nopass.key;
# Configure reverse-proxy settings for CloudFlare.
#set_real_ip_from 204.93.240.0/24;
#set_real_ip_from 204.93.177.0/24;
#set_real_ip_from 199.27.128.0/21;
#set_real_ip_from 173.245.48.0/20;
#set_real_ip_from 103.22.200.0/22;
#set_real_ip_from 141.101.64.0/18;
#set_real_ip_from 108.162.192.0/18;
#real_ip_header CF-Connecting-IP;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Deny access to text files.
location ~ \..*/.*\.(txt|log|htaccess)$ {
deny all;
}
# Set a high lifetime on static assets.
location ~* ^/(sites/|files/|misc/).*\.(js|css|png|jpg|jpeg|gif|ico)(\?[a-zA-Z0-9]+)?$ {
expires max;
#log_not_found off;
}
# No executing PHP files of any files besides ones in the root (cron.php, xmlrpc.php, etc.)
location ~ \..*/.*\.php$ {
return 403;
}
# Try checking if the file exists physically before calling index.php (a la mod_rewrite in Apache).
location / {
try_files $uri @rewrite;
}
location @rewrite {
rewrite ^/(.*)$ /index.php?q=$1;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_intercept_errors on;
fastcgi_pass_header Set-Cookie;
fastcgi_cache drupal_cache; # Define the name of the cache bin.
fastcgi_cache_valid 200 302 1h; # Store pages and redirects for 1 hour.
fastcgi_cache_valid 301 1d; # Store permanent redirects for 1 day.
fastcgi_cache_valid any 1m; # Store all other requests (errors) for 1 minute.
fastcgi_cache_min_uses 1;
fastcgi_cache_use_stale error timeout invalid_header http_500; # Use stale caches when errors occur.
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_bypass $logged_in;
fastcgi_cache_bypass $cookie_NO_CACHE;
}
# To override the above rule, match more specifically against the image styles directory.
location ^~ /files/styles/ {
try_files $uri @rewrite;
}
# Error pages.
error_page 500 502 504 /50x.html;
error_page 404 /404.html;
location ~ /(50x|404).html {
root /home/example/error_pages;
}
}
#######################################################################
#
# This is the main Nginx configuration file.
#
# More information about the configuration options is available on
# * the English wiki - http://wiki.nginx.org/Main
# * the Russian documentation - http://sysoev.ru/nginx/
#
#######################################################################
#----------------------------------------------------------------------
# Main Module - directives that cover basic functionality
#
# http://wiki.nginx.org/NginxHttpMainModule
#
#----------------------------------------------------------------------
user nginx;
worker_processes 4;
error_log /var/log/nginx/error.log;
#error_log /var/log/nginx/error.log notice;
#error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;
#----------------------------------------------------------------------
# Events Module
#
# http://wiki.nginx.org/NginxHttpEventsModule
#
#----------------------------------------------------------------------
events {
worker_connections 1024;
}
#----------------------------------------------------------------------
# HTTP Core Module
#
# http://wiki.nginx.org/NginxHttpCoreModule
#
#----------------------------------------------------------------------
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 120;
client_max_body_size 50m;
# Enable gziping of assets.
gzip on;
gzip_static on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types text/plain text/xml application/xml application/xml+rss
text/css text/javascript application/javascript application/x-javascript application/json;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
# Define the cache path for Backdrop/Drupal sites.
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=www_cache:10m;
# Define a default storage for keeping track of connection sessions.
# http://wiki.nginx.org/HttpLimitZoneModule
# 1m == 32000 sessions
limit_conn_zone $binary_remote_addr zone=default:10m;
# Prefer the fastest possible ciphers. See
# http://zombe.es/post/4078724716/openssl-cipher-selection
ssl_ciphers RC4:AES128-SHA:AES:CAMELLIA128-SHA:!ADH:!aNULL:!DH:!EDH:!eNULL:!LOW:!SSLv2:!EXP:!NULL;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # SSLv2 and SSLv3 have been proven breakable.
ssl_session_cache shared:SSL:2m; # 1m of cache roughly == 4000 SSL connections
# Drupal needs to check $_SERVER['HTTPS'] for SSL pages, but nginx does not set
# this variable by default. Set $https based on the scheme (http or https).
map $scheme $https { default off; https on; }
# Set a $logged_in variable based on the Drupal session cookie.
map $http_cookie $logged_in {
default 0;
~SESS 1;
}
# Load config files from the /etc/nginx/conf.d directory
# The default server is in conf.d/default.conf
include /etc/nginx/conf.d/*.conf;
}
# First thing, set the machine host name.
# See http://library.linode.com/getting-started#sph_set-the-hostname
vi /etc/sysconfig/network
# Add HOSTNAME=example-www1 to the file.
hostname example-www1
# Then edit /etc/hosts on all machines to add the new machine host.
127.0.0.1 localhost.localdomain localhost
66.228.37.37 example-www1.example.com example-www1
66.228.44.22 example-util1.example.com example-util1
# Install atomic repository (nginx)
wget -q -O - http://www.atomicorp.com/installers/atomic | sh
# Install EPEL repository (GeoIP, misc packages)
rpm -Uhv http://ftp.osuosl.org/pub/fedora-epel/6/x86_64/epel-release-6-8.noarch.rpm
# Install packages
yum install php php-pdo php-mysql php-gd php-mbstring php-devel php-pear php-xml
yum install geoip # Required for Atomic's nginx install.
yum install php-fpm
yum install dovecot
yum install mysql mysql-server
yum install nginx
yum install gcc make # Needed to get pecl install and phpize commands working.
yum install zlib zlib-devel
# Start up services.
chkconfig --add nginx
chkconfig --level 345 nginx on
chkconfig --add mysqld
chkconfig --level 345 mysqld on
chkconfig --add php-fpm
chkconfig --level 345 php-fpm on
chkconfig --add postfix
chkconfig --level 345 postfix on
# Users.
adduser example
# Set the timezone
ln -sf /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
# Set up nginx. Copy in nginx.conf and example.conf files.
# Important! For my install of nginx, this setting was missing from
# /etc/nginx/fastcgi_params:
# !!!!!!
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_script_name;
# !!!!!!
# Without it, nginx gave WSOD with no log messages of any kind when loading
# PHP pages. :P
# Set up the web root.
yum install git
su example
cd ~
mkdir .ssh
chmod 755 ssh
ssh-keygen -t rsa -C "[email protected]"
# Add the server SSH key to the Git repository (Github, Unfuddle, BitBucket, etc).
git clone [email protected]:example/drupal7.git www
# Set up PHP-FPM
# Set up a new "pool" for each virual host. Each virtual host should have it's
# own user name and web directory root. PHP-FPM will run as the same user that
# owns the web directory root files.
mv /etc/php-fpm.d/www.conf /etc/php-fpm.d/[example].conf
vi /etc/php-fpm.d/[example].conf
; Start a new pool for this server.
[example]
user = example
group = example
# Adjust max_children to amount of available RAM
# Assuming 50 MB PHP processes * 20 = 1GB RAM
pm.max_children = 20
# Set up PHP
vi /etc/php.ini
# Use secure cookies to make it so that secure sessions are forced over HTTPS.
session.cookie_secure = 1
post_max_size = 52M
upload_max_filesize = 50M
# Set up mysql to give the root user a password:
# On old server:
mysqldump --all-databases > all_databases.sql
scp root@old_server:~/all_databases.sql root@new_server:~/all_databases.sql
# On new server:
mysql < all_databases.sql;
# Run upgrade script since new server is running a newer MySQL. Also fixes a
# lot of permissions issues when moving user accounts.
mysql_upgrade
# Secure MySQL accounts:
mysql_secure_installation
mysql
> CREATE USER 'example'@'localhost' IDENTIFIED BY 'enter your pass'
> GRANT ALL PRIVILEGES ON *.* to 'example'@'localhost';
# Install APC
pecl install apc
vi /etc/php.d/apc.ini
; Enable and configure the APC extension.
extension=apc.so
apc.shm_size = 128M
service php-fpm restart
# Install Memcache:
yum install memcached libmemcached
# Set up two bins/services for Memcache:
cp /etc/init.d/memcached /etc/init.d/memcached-cache
cp /etc/init.d/memcached /etc/init.d/memcached-sessions
# Edit each one to replace "memcache" with "memcache-*" as needed:
vi /etc/init.d/memcached-cache
vi /etc/init.d/memcached-sessions
if [ -f /etc/sysconfig/memcached-cache ];then
. /etc/sysconfig/memcached-cache
fi
prog="memcached-cache"
pidfile=${PIDFILE-/var/run/memcached/memcached-cache.pid}
lockfile=${LOCKFILE-/var/lock/subsys/memcached-cache}
cp /etc/sysconfig/memcached /etc/sysconfig/memcached-cache
cp /etc/sysconfig/memcached /etc/sysconfig/memcached-sessions
# Make a new global memcache service to start/stop both the other ones.
rm /etc/init.d/memcached
rm /etc/sysconfig/memcached
vi /etc/init.d/memcached
#! /bin/sh
#
# chkconfig: - 55 45
# description: The memcached daemon is a network memory cache service.
# processname: memcached
# config: /etc/sysconfig/memcached
# pidfile: /var/run/memcached/memcached.pid
/etc/init.d/memcached-sessions $*
/etc/init.d/memcached-cache $*
chmod 755 /etc/init.d/memcached
chkconfig --add memcached
chkconfig --level 345 memcached on
pecl install igbinary
vi /etc/php.d/igbinary.ini
extension=igbinary.so
yum install php-memcached
# Configure dovecot/sendmail. Without these changes the full machine hostname
# will be used as the sender (example-www1.localhost in my experience).
vi /etc/postfix/main.cf
mydomain = example.com
myorigin = $mydomain
# Install Drush
cd /usr/local/bin
wget http://ftp.drupal.org/files/projects/drush-7.x-4.5.tar.gz
tar -zxvf drush-7.x-4.5.tar.gz
rm drush-7.x-4.5.tar.gz
chown -R root:root drush
mv drush drush-4.5
ln -s drush-4.5/drush drush
# OR
pear channel-discover pear.drush.org
pear install drush/drush
# Set up DKIM mail keys.
# See http://stevejenkins.com/blog/2011/08/installing-opendkim-rpm-via-yum-with-postfix-or-sendmail-for-rhel-centos-fedora/
yum install opendkim
mkdir /etc/opendkim/keys/example.com
opendkim-genkey -D /etc/opendkim/keys/example.com/ -d example.com -s default
chown -R opendkim:opendkim /etc/opendkim/keys/example.com
mv /etc/opendkim/keys/example.com/default.private /etc/opendkim/keys/example.com/default
vi /etc/opendkim.conf
Mode sv
Domain example.com
Selector default
#KeyFile /etc/opendkim/keys/default.private
KeyTable /etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
vi /etc/opendkim/KeyTable
default._domainkey.example.com example.com:default:/etc/opendkim/keys/example.com/default
vi /etc/opendkim/SigningTable
*@example.com default._domainkey.example.com
example.com default._domainkey.example.com
.example.com default._domainkey.example.com
vi /etc/opendkim/TrustedHosts
127.0.0.1
example-www1.example.com
example.com
# Copy the value from /etc/opendkim/keys/example.com/default.txt into a DNS
# record. This record will look something like this:
default._domainkey IN TXT ( "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCszwbXFfmOdsgcKICNUcMGG5b64gOEQNE/APja0GVt2Um2hvqOdN5Mrz921SVN0ogFxvBeWlNikW3D4r5kkpd2mF3ZaV63+JzxFHNDnBRVkrjuyPNC7yrujRQdbXKgs5IMu7v0dif93DgJe6Gwg+Iuf2glk5Bfpbuo9Eg0FJCHZwIDAQAB" );
# Additionally add the following to complete DKIM:
_adsp._domainkey.example.com IN TXT ( "dkim=unknown" )
# And set up SPF while we're here:
@ IN TXT ( v=spf1 a:spf.example.com mx ~all )
spf IN A 23.239.2.17
# While
vi /etc/postfix/main.cf
# OpenDKIM configuration.
# Tie the sendmail smtpd process to OpenDKIM to sign outgoing e-mail.
# Added based on tutorial at:
# http://stevejenkins.com/blog/2011/08/installing-opendkim-rpm-via-yum-with-postfix-or-sendmail-for-rhel-centos-fedora/
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept
service opendkim start
chkconfig --add opendkim
chkconfig --level 345 opendkim on
# Set up Private IP addresses.
# In the Linode manager under "Remote Access". Click "Add private IP".
# Follow instructions at http://library.linode.com/networking/configuring-static-ip-interfaces
vi /etc/sysconfig/network-scripts/ifcfg-eth0:1
# Configuration for eth0:1
DEVICE=eth0:1
BOOTPROTO=none
# This line ensures that the interface will be brought up during boot.
ONBOOT=yes
# eth0:1 - Private IPs have no gateway (they are not publicly routable) so all you need to
# specify is the address and netmask.
IPADDR=192.168.xxx.xxx
NETMASK=255.255.128.0
# Install munin
# See munin-installation.txt.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment