PHP application with Nginx and Varnish on ElasticBeanstalk

AWS ElasticBeanstalk service provides platforms for PHP applicaitons but it has Apache as a backend webserver. But there are situations where Apache does not perform well for PHP applications specially for heavy traffic websites. In those kind of situations you may would like to use Nginx and php-fpm to gain some performance with same hardware or want to use varnish as well for caching instead of using AWS elasticache service and pay extra cost.

There are couple of approaches one can take to replace Apache with Nginx and php-fpm.
1. Use of Custom AMI
2. Use of ebextensions

1. In my personal experience, Using Custom AMI for Beanstalk is not that smooth. I have faced lot of unexpected weird issues while using custom AMI for Beanstalk environment.

2. However on the other hand using ebextensions is somewhat more reliable and giving you expected behaviour. However, it would add some delays in instance setup time. But I would say, its worth it for a stable and expected environment behaviour.

Below are the guidelines for using Nginx, php-fpm and Varnish for high traffic PHP application for ElasticBeanstalk.

I will follow the ebcli way to setup the PHP environment, however one can use AWS console as well.


~/ # mkdir php_demo
~/ # cd php_demo
~/php_demo # wget http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/samples/php-v1.zip
~/php_demo # unzip php-v1.zip
~/php_demo # rm php-v1.zip
~/php_demo # git init

Initialized empty Git repository in /Users/ramesh/php_demo/.git/
~/php_demo # git status
On branch master

Initial commit

Untracked files:
(use “git add …” to include in what will be committed)

.gitignore
cron.yaml
index.php
logo_aws_reduced.gif
scheduled.php
styles.css

nothing added to commit but untracked files present (use “git add” to track)
~/php_demo # git add .
~/php_demo # git commit -m”Adding sample php application”

[master (root-commit) c8a306a] Adding sample php application
Committer: Kumar <ramesh@gladiator>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly. Run the
following command and follow the instructions in your editor to edit
your configuration file:

git config –global –edit

After doing this, you may fix the identity used for this commit with:

git commit –amend –reset-author

6 files changed, 215 insertions(+)
create mode 100644 .gitignore
create mode 100644 cron.yaml
create mode 100644 index.php
create mode 100644 logo_aws_reduced.gif
create mode 100644 scheduled.php
create mode 100644 styles.css
~/php_demo # eb init
Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-south-1 : Asia Pacific (Mumbai)
7) ap-southeast-1 : Asia Pacific (Singapore)
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
10) ap-northeast-2 : Asia Pacific (Seoul)
11) sa-east-1 : South America (Sao Paulo)
12) cn-north-1 : China (Beijing)
(default is 3): 1
Select an application to use
1) WindowsTesting02
2) [ Create new Application ]
(default is 2): 2
Enter Application Name
(default is “php_demo”): php_demo
Application php_demo has been created.
It appears you are using PHP. Is this correct?
(y/n): y
Select a platform version.
1) PHP 5.4
2) PHP 5.5
3) PHP 5.6
4) PHP 7.0
5) PHP 5.3
(default is 1): 4
Note: Elastic Beanstalk now supports AWS CodeCommit; a fully-managed source control service. To learn more, see Docs: https://aws.amazon.com/codecommit/
Do you wish to continue with CodeCommit? (y/n)(default is n): n
Do you want to set up SSH for your instances?
(y/n): y
Select a keypair.
1) aws-eb
2) [ Create new KeyPair ]
(default is
2): 2
Type a keypair name.
(Default is aws-eb2): beanstalk_demo
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/ramesh/.ssh/beanstalk_demo.
Your public key has been saved in /Users/ramesh/.ssh/beanstalk_demo.pub.
The key fingerprint is:
SHA256:SvVMNNaHuh1ja/mPUBS8+uynk713MpizMAeY13fWsSk beanstalk_demo
The key’s randomart image is:
+—[RSA 2048]—-+
| +. o. |
| o .o o. |
| . .. ..o |
| . *..+.. =|
| . S =+.Eoo+|
| . . …*o.o |
| . o.o* o |
| ++.O.=|
| .++O=|
+—-[SHA256]—–+
WARNING: Uploaded SSH public key for “beanstalk_demo” into EC2 for region us-east-1.
~/php_demo # eb create
Enter Environment Name
(default is php-demo-dev):
Enter DNS CNAME prefix
(default is php-demo-dev):

Select a load balancer type
1) classic
2) application
(default is 1): 1
Creating application version archive “app-c8a3-161024_143514”.
Uploading php_demo/app-c8a3-161024_143514.zip to S3. This may take a while.
Upload Complete.
Environment details for: php-demo-dev
Application name: php_demo
Region: us-east-1
Deployed Version: app-c8a3-161024_143514
Environment ID: e-tttpfzgmwu
Platform: 64bit Amazon Linux 2016.03 v2.1.7 running PHP 7.0
Tier: WebServer-Standard
CNAME: php-demo-dev.us-east-1.elasticbeanstalk.com
Updated: 2016-10-24 03:35:23.150000+00:00
Printing Status:
INFO: createEnvironment is starting.
INFO: Using elasticbeanstalk-us-east-1-694883035934 as Amazon S3 storage bucket for environment data.
INFO: Environment health has transitioned to Pending. Initialization in progress (running for 12 seconds). There are no instances.
INFO: Created load balancer named: awseb-e-t-AWSEBLoa-1SZPIURQCQLAS
INFO: Created security group named: awseb-e-tttpfzgmwu-stack-AWSEBSecurityGroup-1IFU4V4TYJHJV
INFO: Created Auto Scaling launch configuration named: awseb-e-tttpfzgmwu-stack-AWSEBAutoScalingLaunchConfiguration-27LW0YLNAY4R
INFO: Created Auto Scaling group named: awseb-e-tttpfzgmwu-stack-AWSEBAutoScalingGroup-LR8B4Y0NO912
INFO: Waiting for EC2 instances to launch. This may take a few minutes.
INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:us-east-1:694883035934:scalingPolicy:18e38892-134f-4157-aaf4-98ae6b862913:autoScalingGroupName/awseb-e-tttpfzgmwu-stack-AWSEBAutoScalingGroup-LR8B4Y0NO912:policyName/awseb-e-tttpfzgmwu-stack-AWSEBAutoScalingScaleUpPolicy-RYICFUMHRY7A
INFO: Created Auto Scaling group policy named: arn:aws:autoscaling:us-east-1:694883035934:scalingPolicy:16854060-1c91-4f5b-8c1c-9a6fe02f9259:autoScalingGroupName/awseb-e-tttpfzgmwu-stack-AWSEBAutoScalingGroup-LR8B4Y0NO912:policyName/awseb-e-tttpfzgmwu-stack-AWSEBAutoScalingScaleDownPolicy-31BLMDNESLS1
INFO: Created CloudWatch alarm named: awseb-e-tttpfzgmwu-stack-AWSEBCloudwatchAlarmHigh-TZ0S2PWV4K6B
INFO: Created CloudWatch alarm named: awseb-e-tttpfzgmwu-stack-AWSEBCloudwatchAlarmLow-1XI8XP64BTFZW
INFO: Added instance [i-0a627cf68eece0f5a] to your environment.
INFO: Environment health has transitioned from Pending to Ok. Initialization completed 34 seconds ago and took 3 minutes.
INFO: Successfully launched environment: php-demo-dev

~/php_demo # eb open

You would see your php app open up on your default browser.

~/php_demo # mkdir .ebextensions
~/php_demo # cd .ebextensions
~/php_demo/.ebextensions # wget http://linuxtrove.com/wp/download/ebextensions.zip
~/php_demo/.ebextensions # unzip ebextensions.zip
~/php_demo/.ebextensions # rm -f ebextensions.zip
~/php_demo/.ebextensions # git add .
~/php_demo/.ebextensions # git commit -m”Adding ebextensions”
~/php_demo/.ebextensions # cd ..
~/php_demo # eb deploy

Creating application version archive “app-be39-161024_151059”.
Uploading php_demo/app-be39-161024_151059.zip to S3. This may take a while.
Upload Complete.
INFO: Environment update is starting.
INFO: Deploying new version to instance(s).
INFO: Environment health has transitioned from Ok to Info. Application update in progress (running for 37 seconds).
INFO: New application version was deployed to running EC2 instances.
INFO: Environment update completed successfully.

Now varify if Nginx and varnish in action.

~/php_demo # eb ssh
INFO: Attempting to open port 22.
INFO: SSH port 22 open.
INFO: Running ssh -i /Users/ramesh/.ssh/beanstalk_demo ec2-user@52.201.230.174
sudo su –
Last login: Mon Oct 24 04:27:22 2016 from d49-192-1-247.bla1.nsw.optusnet.com.au
_____ _ _ _ ____ _ _ _
| ____| | __ _ ___| |_(_) ___| __ ) ___ __ _ _ __ ___| |_ __ _| | | __
| _| | |/ _` / __| __| |/ __| _ \ / _ \/ _` | ‘_ \/ __| __/ _` | | |/ /
| |___| | (_| \__ \ |_| | (__| |_) | __/ (_| | | | \__ \ || (_| | | <
|_____|_|\__,_|___/\__|_|\___|____/ \___|\__,_|_| |_|___/\__\__,_|_|_|\_\
Amazon Linux AMI

This EC2 instance is managed by AWS Elastic Beanstalk. Changes made via SSH
WILL BE LOST if the instance is replaced by auto-scaling. For more information
on customizing your Elastic Beanstalk environment, see our documentation here:
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html
[ec2-user@ip-172-31-8-84 ~]$ sudo su –
[root@ip-172-31-8-84 ~]# rpm -qa|grep -i fpm

php70-fpm-7.0.10-1.15.amzn1.x86_64
[root@ip-172-31-8-84 ~]# rpm -qa|grep -i nginx
nginx-1.8.1-3.27.amzn1.x86_64
[root@ip-172-31-8-84 ~]# /etc/init.d/nginx status
nginx (pid 4008) is running…
[root@ip-172-31-8-84 ~]# /etc/init.d/varnish status
varnishd (pid 4066) is running…
[root@ip-172-31-8-84 ~]# /etc/init.d/httpd status
Equivalent Upstart operations: start httpd, stop httpd, restart httpd, status httpd
httpd is stopped

You can check the http header information as attached screenshot that sample app is served by Nginx and varnish.

Http Header

Also, note that configuration of Nginx and Varnish are just for demo purpose. You need to test your own nginx and varnish configuration then use them via ebextensions as mentioned above.

I'm happy to use Increase Sociability.