easyengine (ee) note: If you are using easyengine, you can accomplish everything in this article using following command:
ee stack install --all
A complete WordPress-Nginx setup will involve PHP, MySQL, Nginx stack and on the top of it WordPress itself.
If you already have PHP, MySQL & Nginx up & running then you may jump to next part i.e Nginx configuration for different WordPress
I am assuming few things before you start.
- You have a Ubuntu server up and running. This guide may work on other Debian based distros but this is tested on Ubuntu 12.04 LTS only.
- You have shell access to your Ubuntu server with sudo privilege or you have direct root-user access.
Installing PHP 5.6
We are going to use latest PHP 5.6 as it is much faster & better than PHP 5.3 and PHP 5.4.
As official repo for Ubuntu 12.04 LTS contains PHP version 5.3 only, we will use a launchpad repo maintained by Ondřej Surý
Run following codes to add launchpad repo to apt-sources:
sudo apt-get install python-software-properties sudo add-apt-repository ppa:ondrej/php
Press “enter” key whenever asked!
This is must, otherwise next command may end up installing PHP 5.3!
sudo apt-get update
Now, run following to install PHP itself
sudo apt-get install php5-common php5-mysqlnd php5-xmlrpc php5-curl php5-gd php5-cli php5-fpm php-pear php5-dev php5-imap php5-mcrypt
Check PHP Version
Run following command…
You will see following output…
PHP 5.6.29-1+deb.sury.org~xenial+1 (cli) Copyright (c) 1997-2016 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
We use Percona-MySQL everywhere for extra features and up-to-date Ubunut builds they maintain.
Add Percona Repo
Execute following commands:
apt-key adv --keyserver keys.gnupg.net --recv-keys 1C4CBDCDCD2EFD2A echo "deb http://repo.percona.com/apt `lsb_release -cs` main" >> /etc/apt/sources.list.d/percona.list echo "deb-src http://repo.percona.com/apt `lsb_release -cs` main" >> /etc/apt/sources.list.d/percona.list apt-get update
Installing percona-mysql server
sudo apt-get install percona-server-server-5.6 percona-server-client-5.6
Above wizard should ask you to enter a mysql password for user
root. If it doesn’t, then run the following command to change MySQL password.
sudo mysqladmin -u root password NEWPASSWORD
Please note that above command will not help you in case you forget your mysql root password in future.
If you want to send mails from your WordPress, you will need a SMTP server. You can use a remote SMTP server like gmail.com for this. But I prefer using postfix package to run a SMTP server locally.
In simple words, if you skip this step and do not configure remote SMTP server with WordPress either, your WordPress will not be send email notifications for comments, etc.
sudo apt-get install postfix
It will take you through few steps. The important one are:
- Select option – Internet Site
- Hostname – generally your main domain i.e example.com. Recommended – a FQDN like mail.example.com
You no need to touch other options. Just restart mail service to be safe.
Testing your mail config:
Run following PHP code with [email protected] replaced by your mail id:
php -a mail ('[email protected]', "Hello from nginx!", "My email setup works!"); exit ();
Alternatively you can use check-mail WordPress Plugin after your WordPress setup completes to be sure that your WordPress can send emails.
Ubuntu official repos come with a Nginx package but I prefer using launchpad repo maintained by Nginx team.
sudo add-apt-repository ppa:nginx/stable sudo apt-get update sudo apt-get install nginx
If you prefer to use Nginx package in Ubuntu repo, you can simply run following command:
sudo apt-get install nginx-full
At this point, we are done with installing prerequisite for WordPress.
As technology evolves, we keep upgrading our installation. This article is “how” we work here at rtCamp. So this article need to be changed over time.
Oct 15, 2013
- Replaced PHP 5.4 with PHP 5.5
- Removed APC
- Using PHP’s built-in zend-opcache for opcode-cache.
- Using memcache for user/data-cache requirement
- Switched to mysql native driver for PHP (php-mysqlnd package)
- Replaced oracle-mysql with percona-mysql. Mysql 5.6 at the time of writing this article.
Got into bit of trouble here..
I have tried to install APC for my current server ( aleady nginx, running on Centos)
Now it seems APC is conflicting with Zend Optimizer
If i enable APC extension on php.in then nginx will get me a 502 Error.
Any idea to solve it.
If you are not using any application that uses Zend Optimizer, you can disable it.
In my opinion WordPress will benefit from APC more rather than Zend Optimizer.
I don’t like this line:
sudo mysqladmin -u root password NEWPASSWORD
because you’ll have the password in you bash history.
For me the better way is to use the
Thanks for your feedback. 🙂
I am aware of
mysql_secure_installationand bash history concern but if I can read your bash history then I will be able to read other files as well. 😉
Goal of this chapter is to get all needed software up and running quickly. This is part of a large on-going wordpress-nginx series tutorials. I will be covering security in-depth towards end where I will revisit this and few more things.
if you don’t want a command show up in your bash history, just execute it with a preceding space. That’s all.
Nice trick 🙂
I think you’ll should explain the configuration of php-fpm too. The default options are quite good, but not for best performance. I’m using this one for my pool
What you are using is quite customised. In real-life people don’t need to make these many changes to their config. As explained earlier this article is part of a large series. If I cover everything here itself, then this article will become too big to be useful!
I covered php slowlog in details here. It’s not good to keep slowlog always on as it itself slows-down PHP scripts. I will recommend turning it off when you are done with debugging.
request_terminate_timeoutis commented by default and it takes value of
php.inifile. Only when your php scripts fails to terminate after
max_execution_timeelapses (most likely because of some bug) you need to set value for
I explained this in more details here.
You can find all articles in this series here. More will be added soon. 🙂
Please add that to get out of interactive mode , need to hit – d
Looks like your PHP is not complied with readline support. I mentioned about this in – http://rtcamp.com/tutorials/checking-if-phpwordpress-can-send-mails/
if I give APC say 1GB for caching, does it share that space between all vhosts even though they are running with different users?
I am not sure but I think APC will “allocate” 1 GB for every PHP’s linux-user. Still, OS may not complain as long as that much memory is not “used” by all processes together.
You can simply do following:
apc.phpfile under different vhosts.
apc.phpshows from browser.
apc.phpshows same amount of memory consumption then memory may be shared among all.
apc.phpoutput in any-case, you can increase memory allocated to APC.
Doesn’t really work. I tried that before. The reason is that each vhost runs the webserver under its own user so apc.php within one vhost sees only stuff it has access to.
i.e. apc.php within site a) show i.e. 60MB out of 256M in use while apc.php within site b) shows 58MB out of 256MB in use.
I think that is because they run as different users so they only see their usage?
The reason for my question was: i.e. if I know each of my ten wordpress sites needs 60MB, do I assign 60MB to apc.ini and since each vhost runs its own settings each uses 60MB or should I assign 600MB to apc.ini?
Sorry for delayed reply.
You can try 60MB and if you see apc.php is using 100% of memory, you can start increasing it gradually.
As every vhost is having separate memory segment, small segments can be used.
php -a puts me in interactive mode rather than interactive shell, what do I need to do to get interactive shell. I am following your tutorial step by step.
It looks like your php is not compiled with
I have written about it in article – http://rtcamp.com/tutorials/checking-if-phpwordpress-can-send-mails/
My wordpress can not send email, i has install postfix. Why it happen? how to fix this problem?
additional information, i has check email function using wordpress plugin, but it NOT WORK (email no sent). Need assistance as soon as possible.
Please send postfix error log – http://rtcamp.com/tutorials/debugging-postfix-config-mail-logs-mail-queues-more/
Great series.. one detail I couldn’t find though off the bat:
Do I use Ubuntu 12.04 x32 server or 12.04 x64 server?
We mostly use 64-bit servers but these articles should work on 32-bit variants without any problem.
If you face any issues, please let me know. We will sort it out! 🙂
Thanks for the great blog series. It has helped me out tremendously.
Unfortunately, I’ve hit a snag here with my nginx configuration. I am trying to deploy my blog at
sudofoo.net, but I am getting a 403 error.
Here is my
(I’m not sure why the text is the same color as the background, but highlighting the code should reveal it)
I gave ownership of the following directories and sub-directories to the
Also, if I change the root and index to
index.htmlrespectively, I do get the default nginx welcome page.
Does anyone have any tips on how to troubleshoot this issue?
Have you checked PHP permissions? Is PHP running by user `www-data`?
Also, you can enable debug log in Nginx to get more details. See – http://rtcamp.com/tutorials/debugging-nginx-configuration/
Awesome Tutorial Rahul,
I also changed ‘cgi.fix_pathinfo=0’ in ‘/etc/php5/fpm/php.ini’ because i had it written down in my own notes as security issue.
“If this number is kept as 1, the php interpreter will do its best to process the file that is as near to the requested file as possible. This is a possible security risk. If this number is set to 0, conversely, the interpreter will only process the exact file path—a much safer alternative. ”
Is this necessary Rahul, what do you think?
Sorry for delayed reply.
try_filesin nginx will eliminate security risk without changing
I prefer try_files as it is efficient and takes care of security without any edit to php.ini
Ok thanks Rahul. Im pretty new to nginx. Your tutorials are extremely helpful.
This series has been tremendously helpful for a newbie such as myself that is new to linux and setting up dedicated websites. I largely followed your guide with some other additions and I wanted to ask you about security.
1. Is it ok for www-data to have write permissions over /var/www ? Some discussions say that it is not safe to do so, whats your take on it? For me, I changed it to give ubuntu user/group ownership over /var/www because I wanted to be able to sftp in and change files.
2. In /etc/php5/fpm/pool.d/www.conf and /etc/nginx/nginx.conf I changed the user/group to ubuntu from www-data. Will this open me up to hacking by doing this and if so, what is the best way to keep it www-data and be able to sftp in to the server with the ubuntu user?
Any other security tips you or anyone here may have will be appreciated. As I said, I’m very new to all this and just trying to get a grasp of it so I can run my own site on Amazon EC2.
Its hard to answer what should be the way but I will tell you what we do…
#1. I make sure
/var/wwwis owned by user & group
www-data. Though I do not use sftp (I use scp/rsync for file transfer), I think a linux-user should be owner of his own home. If you create a new linux-user using
addusercommand, linux will make that user/group owner for his home directory.
#2. I also use same
www-datalinux-user to run nginx and php processes. This makes things easy. But for shared-hosting scenarios, where 2-people are hosting on same machine and cannot trust each other, we prefer creating php-fpm pools per linux-user to run their sites’ php files. In this case they share `www-data` which is added to different php-fpm pools. Nginx, with `www-data` can read-only all website files.
You can create separate php-fpm pools for different sites owned by same user as well. php-fpm pool with open_basedir restriction can prevent one sites php-files from accessing other-sites php-files.
Apart from this, security itself is a big topic and I intend to write about it in-depth someday. Since its a senstive subject, I should post any “tip” without proper testing.
You may subscribe here for future nginx-related updates.
Dear. Very thank you about this article.
I just have one problem that after install postfix, my WordPress site still can not send email.
Do you have any site that work with WordPress email on Digital Ocean?
Thak you very much,
On DigitialOcean, make sure that droplet-hostname matches your domain-name. DigitalOcean uses hostname for Reverse PTR.
Sure would be nice if DO mentioned this during initial droplet configuration 🙂 Though, admittedly not a big deal to change.
By the way, I recently became fan of DO for their hostname > reverse-PTR mapping.
They are one of very few companies to get this right! 🙂
Yep, adding a notice like: “Hostname will be used as domain for all outgoing email’s” then a read more link for detailed explanation.
Hi Rahul, for some reason I cannot make my setup pass the postfix php mail test… How would you advise to debug? Thanks 🙂
If mails are “sent” but not received, it could be because of reverse-PTR issue.
Howdy, How do you install plugins and themes without a FTP?
Hi Mike, in the WordPress admin go to Plugins > Add new… Similarly for themes.
As of today, this guide will install PHP 5.5.4-1+debphp.org~precise+1 (cli) (built: Sep 27 2013 11:36:42).
Yep. I will update article.
We always use latest PHP build and
ppa:ondrej/php5repo provides always latest build.
Thanks Rahul, I was going to mention APC, but looks like you’re way ahead of the game! Nice.
However, I’m not sure if this was due to any change you recently made, but the 1st link on this page 404: http://rtcamp.com/wordpress-nginx/tutorials/single-site/wp-super-cache/
Work on APC is halted from long time. Its better to use uptodate softwares.
Thanks for bringing broken link to attention. Fixed it. 🙂
Rahul, what can we use instead of APC with W3TC? I used your W3TC config for one of my servers. If you have an alternate suggestion, could you put up a tutorial for it?
We are using memcache for object-cache (using W3TC) – http://rtcamp.com/tutorials/php/memcache/ and zend opcache for opcode caching – http://rtcamp.com/tutorials/php/zend-opcache/
Cool but Zend Opcache isn’t available within W3TC is it? Only memcache, right?
So what method do you choose now for Page, Minify and Database if Object Cache is being used by Memcache?
Opcache works at PHP code level. W3TC is not supposed to have an option for that.
It’s more like set and forget thing – http://rtcamp.com/tutorials/php/zend-opcache/
For minify, we are using disk based cache as it removed PHP process overhead which would have needed to get data from memcache.
For object and database cache, we are using memcache – http://rtcamp.com/tutorials/php/memcache/
I have witnessed a solid sober man driven perfectly mad at the moment by two associated with so-called
rum, supplied to him at one of these simple shanties.
–LINK REMOVED –>Grammy Nominations 2011<. Neighbours were few in number, where there were only three other women living inside the neighbourhood – all lived in both bark huts or tents using their young children.
When is your easy engine going to be updated? Trying install and fails at Unable to Update Apt Cache.
Installing Python Software Properties, Please Wait…
Reading package lists…
Building dependency tree…
Reading state information…
python-software-properties is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 108 not upgraded.
Adding Brianmercer Nginx Launchpad Repository, Please Wait…
Adding Ondrej PHP5 Launchpad Repository, Please Wait…
Updating APT Cache, Please Wait…
[ Thu Jan 30 14:19:58 UTC 2014 ] Unable To Update APT Cache
http://ppa.launchpad.net/brianmercer/nginx/ubuntu/dists/raring/main/binary-amd64/Packages does not exist
http://ppa.launchpad.net/brianmercer/nginx/ubuntu/dists/precise/main/binary-amd64/Packages does exist
I fixed it by changing brianmercer-nginx-raring.list raring main to precise main
I did not get it. Are you using manual install or EasyEngine?
Hey Rahul great tutorials! I have a small issue when installing the percona repository. Somehow the permission is denied for both echo’s.
echo "deb http://repo.percona.com/apt `lsb_release -cs` main" >> /etc/apt/sources.list.d/percona.list
-bash: /etc/apt/sources.list.d/percona.list: Permission denied
I’m using an account with sudo priviledge, not root. What am I doing wrong? Thnx
Try becoming root first. Check if
sudo sugives you a root shell.
I’m new to VPS hosting. I always use shared hosting with my website. I followed all you instructions setting a wordpress website here
It was working fine but I have one problem, My server eat lots of RAM. Here’s the screenshot:
Last week I tried webuzo and installed LEMP stack on their panel. My ram consumes 120 – 190MB only.
I’m so confuse now why my server eats a lot of RAM by following your tutorial.
Can you please help me find what’s the problem?
Here’s my VPS specs:
Operating System Ubuntu 12.04 32-bit
Memory 512 MB
VSwap 512 MB
CPU 1x 3.7GHz Core
free -mcommand from command line to get correct usage. There is a chance that memory usage reported by that tool includes “buffers/cache” memory. OS will always try to use maximum memory and will try to buffers/cache as much content as possible.
Also, if you are setting up a new system, it will be better to use http://rtcamp.com/easyengine . It automates everything!
I can’t be able to see the screenshot so I’m posting it here.
459.05 MB of 512 MB Used / 52.95 MB Free
easyengine doesn’t install percona?
Not for now. You can continue with mysql.
We will be soon adding percona-support and at that time easyengine will have update script to make a switch.
We use percona-mysql internally.
When we started EasyEngine percona-mysql 5.6 GA release wasn’t available.
I found out what the problem was. It was the Percona-mysql that was eating a lot of RAM. Thanks!
You can tweak Percona to use less RAM. Although for InnoDB database, it’s always recommended to provision RAM bigger than actual database size.
If i already have ee on my server.. Is ee running on percona?
I want to try percona for my server..
ee do not have percona as of now. Percona will be added in future.
How to migrate mysql to percona? Any tutorial on rtcamp?
I am really not able to recall but you can try this:
0. stop mysql
service mysql stopand backup eveyrthing.
1. Follow this tutorial – https://rtcamp.com/tutorials/mysql/percona-toolkit/
apt-get install percona-server-server-5.6or
3. start mysql
mysql -v. You may see:
After following this tutorial, I want to make an email like for example [email protected] and access it through thunderbird. How do I do it? I have already installed postfix. Thanks!
You can setup mail server by following https://rtcamp.com/tutorials/mail/server/postfix-dovecot-ubuntu/
Also one more thing Sir. I want to use cloudflare on my website. Does ppa:nginx/stable includes httprealipmodule? Thanks.
Not sure. We use this nginx repo https://launchpad.net/~brianmercer/+archive/nginx and it has realip module
Thank you. How d I check if the one I’m using includes httprealipmodule?
Can I use this command?
2>&1 nginx -V | tr — – ‘\n’ | grep _module
Run `nginx -V 2>&1 | grep http_realip_module -o`
If you see `http_realip_module` in output, you have that module.