Nginx + PHP-FPM for Drupal 7 on AWS EC2

photo

Yesterday my dedicated hosting service with WHM/CPanel in Taiwan slapped me in the face by getting hacked seriously. Although it’s not all the server provider’s fault but I couldn’t really improve the server structure as WHM/CPanel limited me while giving me conveniences to manage the server via web admin pages. I’ve been learning Linux server just to wait the day I can totally build my server environment and configure it with my own philosophy. And it’s today!

I tried Linode first but 4 hours are just not enough, and they block me after I signed up the third time to use the free trial: I have to practice until I’m sure I can handle the server then to pay however much I should pay. So I go for AWS EC2 now. They have 1 year free trial. Here’s the detailed note on building environment for Drupal 7 with Ubuntu Server 12.04.1 LTS, Nginx, PHP-FPM and Mysql.

Launch Instance and Connect

Go to EC2 console page, choose “Ubuntu Server 12.04.1 LTS 64 bit”, remember to create a key and put it on your computer.

Screen Shot 2013-03-31 at 13.53.23

After finishing creating the instance, on the console page, right click the name of the instance, click connect. Choose a way to connect, for example via Terminal on Mac:

$ ssh -i aws.pem ubuntu@ec2-x-x-x-x.ap-northeast-1.compute.amazonaws.com
After login via SSH, go back to console page, note the security group on you instance, then navigate to Security Groups, choose that group and add Port 80. Otherwise you won’t be able to see any page via http.

Screen Shot 2013-03-31 at 19.39.19

Prepare the testing domain

On your computer, edit hosts to test the websites by domain, on Mac

$ sudo nano /etc/hosts
Substitue miss-hana.com to any domain you want to use on testing the site.
x.x.x.x miss-hana.com
#### Basic Installation

On SSH, login as root as it saves some energy to type sudo every time.

ubuntu@ip-x-x-x-x:~$ sudo -i
Before install any package, update first.
$ apt-get update $ apt-get upgrade --show-upgraded
#### LEMP Installation

LEMP means Linux, Nginx, Mysql and PHP.

$ apt-get install nginx $ /etc/init.d/nginx start   $ apt-get install mysql-server mysql-client $ mysql_secure_installation   $ apt-get install php5-fpm php5-mysql $ /etc/init.d/php5-fpm restart
There are some other packages for Drupal, for example a must-have: Drush.
$ apt-get install drush $ drush dl drush --destination='/usr/share'
For [Commerce Kickstart](http://drupal.org/project/commerce_kickstart)
$ apt-get install php5-gd $ apt-get install php5-curl
Restart,
$ /etc/init.d/php5-fpm restart
##### Testing Nginx

Now go to the public DNS like:

http://ec2-x-x-x-x.ap-northeast-1.compute.amazonaws.com/

You’ll see “Welcome to nginx!”.

Basic Configuration

Edit default configurations

$ nano /etc/nginx/sites-available/default
Add index.php to index:
index index.html index.htm index.php;
Uncomment the location php section, for example:
location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$;# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini # # With php5-cgi alone: # fastcgi_pass 127.0.0.1:9000; # With php5-fpm: fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php;include fastcgi_params;}
Edit PHP configuration
$ nano /etc/php5/fpm/pool.d/www.conf
Find:
listen = 127.0.0.1:9000
Replace it with:
listen =/var/run/php5-fpm.sock
Restart Services
$ /etc/init.d/php5-fpm restart $ /etc/init.d/nginx restart
##### Testing LEMP

Print phpinfo to nginx index page to test.

$ echo "phpinfo();?>" > /usr/share/nginx/www/index.php
Change the default “Welcome to nginx!” index.html to index2.html
$ mv /usr/share/nginx/www/index.html /usr/share/nginx/www/index2.html
On your browser, go to the Public DNS.
http://ec2-x-x-x-x.ap-northeast-1.compute.amazonaws.com/
You’ll see phpinfo.

Virtual Host Configuration

It’s the most complicated step as the configuration for each sites could be different. Here’s the example for Drupal.

$ nano /etc/nginx/sites-available/miss-hana.com
Copy and pasted the Nginx configuration for Drupal.
server { server_name miss-hana.com; root /var/www/miss-hana.com;   access_log /var/log/nginx/miss-hana.com.access.log;error_log/var/log/nginx/miss-hana.com.error.log info;   index index.php;   location =/favicon.ico { log_not_found off; access_log off;}   location =/robots.txt { allow all; log_not_found off; access_log off;}   # This matters if you use drush location =/backup { deny all;}   # Very rarely should these ever be accessed outside of your lan location ~* \.(txt|log)$ { allow 127.0.0.1; deny all;}   location ~ \..*/.*\.php {return403;}   location /{# This is cool because no php is touched for static content try_files $uri$uri/@rewrite; expires max;}   location @rewrite {# Some modules enforce no slash (/) at the end of the URL # Else this rewrite block wouldn't be needed (GlobalRedirect) rewrite ^/(.*)$ /index.php?q=$1;}   location ~ \.php$ { fastcgi_split_path_info ^(.+.php)(/.+)$;#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini fastcgi_pass unix:/var/run/php5-fpm.sock;include fastcgi_params; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_intercept_errors on;}   # Catch image styles for D7 too. location ~ ^/sites/.*/files/styles/{ try_files $uri@rewrite;}   location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires max; log_not_found off;}}
Then create a link.
$ ln -s /etc/nginx/sites-available/miss-hana.com /etc/nginx/sites-enabled
Remove the default site
$ rm /etc/nginx/sites-enabled/default
Reload nginx configuration
$ /etc/init.d/nginx reload
Create the root document for this website and start putting files
$ mkdir-p /var/www/miss-hana.com
Now you can start playing with Drupal on AWS EC2!