Here is a Step by Step Guide on Setting Up WordPress Multisite on Nginx on Ubuntu 14.04 on HP Cloud with All Commands and the Configuration. So, we have no theory in this guide. This Guide, WordPress Multisite on Nginx on Ubuntu 14.04 on HP Cloud Will Be Followed By a Theoretical Article and a Screencast. The step by step commands obviously can be used by a newbie too on non-HP Cloud setup, the reader should start from third sub header in that case (Steps).
In any case, you must copy the commands on your plain text editor and then copy to SSH screen.
WordPress Multisite on Nginx on Ubuntu 14.04 on HP Cloud : Getting Started
In order to getting started with WordPress Multisite on Nginx on Ubuntu 14.04 on HP Cloud, we have taken it granted, that you have done proper steps, like setting up the Router on HP Helion Public Cloud, Setting Up Ingress – Egress Policies, optionally using HP Cloud Banner as pre-login SSH screen.
---
We always recommend to use, two server configuration. Hence, the guide for having a Separate Database Server. We will use the Subnet for internally connecting, which will not be discussed here. WordPress Multisite on Nginx on Ubuntu 14.04 on HP Cloud Demands Minimum Idea about Server Administration. You, possibly should add couple of Varnish Server in Replication to make it fail safe.
We are taking it granted that, you opted to go for WordPress Multisite on Nginx on Ubuntu 14.04 on HP Cloud instead of using IP based Virtual Hosts.
So, you can Install Nginx PHP5-FPM on HP Cloud at least like the author. You should use Port Knocking if you plan for making it like wordpress.com
or
WordPress Multisite on Nginx on Ubuntu 14.04 on HP Cloud : Fuss To Read
You will need a 8 GB instance to run WordPress Multisite on Nginx on Ubuntu 14.04 Parter Image on HP Cloud for smoothly running 10 websites with some load. Application Server can be of 4 GB, if you are using InnoDB as Engine, provided that you are using W3 Total Cache’s Database Cache. WordPress Multisite is a complicated matter, if the server fails, your nerve will fail. This WordPress Multisite infrastructure on Nginx is for managed hosting. Only exceptions of using lesser resource is either websites with very low load or all websites are yours. 2GB – 1GB configuration will be fine in that case. WordPress is written in the worst language named PHP. Nowadays, you will find PHP Experts. Fact is, if WordPress was written in Ruby or Python, we would need one 1 GB server. For the ineffective language plus WordPress, plus MySQL, it is risky; too risky to lower down your budget. With that one 1 GB server, your websites would run more faster than one 8 GB instance at frontend. An excellent project is going on to make a kind of WordPress in Python. Do you know the name? No. Your guess is wrong, you are thinking about that one which starts with “M”? No. That is running on my this Mac as localhost! I am writing that for my own need!
By default, HP Cloud’s Ubuntu 14.04 LTS will give you server’s public file’s root NOT at /usr/share/nginx/html
, but at /var/www
. Do not ask me why, sometimes it becomes /usr/share/nginx/html
. This website accidentally uses that /usr/share/nginx/html
location, which I personally like. So, your public root is either /var/www
or /usr/share/nginx/html
. We will use /usr/share/nginx/html
as default one. You should make your head configured rightly. If you want to change it, run locate /usr/share/nginx/
to find if there is any other configuration file, conflicting. If you have /var/www
but love /usr/share/nginx/html
, run locate /usr/share/nginx/
. mkdir -p /usr/share/nginx/html
will give pathetic pain with SSL certificate installation. You have to create directories manually like a kid – cd /usr && ls
, if no share
directory, then mkdir share && cd share
. Same goes for SSL certificate. There is reason of this odd stuff in POSIX. Read man mkdir
:
1 2 3 4 5 6 7 | -p Create intermediate directories as required. If this option is not specified, the full path prefix of each operand must already exist. On the other hand, with this option specified, no error will be reported if a directory given as an operand already exists. Intermediate directories are created with permission bits of rwxrwxrwx (0777) as modified by the current umask, plus write and search permission for the owner. |
Read the line :
Intermediate directories are created with permission
bits of rwxrwxrwx (0777) as modified by the current umask, plus
write and search permission for the owner
Very meaningful line. The pathetic pain with SSL certificate installation can push you to read older docs on IBM’s website! Ubuntu is not the original UNIX. UNIX Wheel group is not present. Nginx www
user be unable to find the path for SSL. mkdir -p
is for ordinary works.
WordPress Multisite on Nginx on Ubuntu 14.04 on HP Cloud : Steps
SSH to the instance, run sudo su
to become root. If sudo is throwing error like “sudo: unable to resolve host”, read it. You have a Separate Database Server. This is the bunch of commands needed to install Nginx and PH5-FPM.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | apt-get update -y && apt-get upgrade apt-get dist-upgrade -y # this hash means, it is not a command or is a command or is optional command apt-get install python-software-properties apt-get install snmp # aha, big command 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 # we will reboot apt-get autoremove add-apt-repository ppa:nginx/stable add-apt-repository -y ppa:nginx/stable apt-get update -y reboot ## are you blindly copy pasting? # comeback with ssh are you blindly copy pasting? # are not found? lol are you blindly copy pasting? apt-get install nginx apt-get install php5-mysql php5-curl php5-gd php5-intl php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl php5-xcache # make sure these are not missed sudo apt-get install php5-fpm apt-get install php5-gd libssh2-php apt-get install mysql-client apt-get install php5-snmp # check nginx nginx -t # check php php -v service nginx restart && service php5-fpm restart nano /etc/php5/fpm/php.ini # -> cgi.fix_pathinfo = 0 service nginx restart && service php5-fpm restart apt-get install unzip |
My :
My Website 1 is abhishekghosh.net
(Primary domain). This is the site that is created when WordPress is installed. My External Domain (My Website 2) is abhishekghosh.pro
. dr.abhishekghosh.net
is a subdomain (My Website 3).
You will rightly configure the main server for abhishekghosh.net
(Primary domain) from Domain Registerer, HP Cloud DNS etc. Not exactly abhishekghosh.net
, what is your website. Got it? Good. 15 minutes work. Check whether abhishekghosh.net
is working or not from webpagetest.org
. No need to clear cache cookies. As I can not buy wordpress. [com] [net] [org]
etc, I will use this location /usr/share/nginx/wordpress
as public directory for dr.abhishekghosh.net
. Else, I will get confused later. So, like a kid :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | cd /usr/share/ cd nginx # if bash: no such thing comes, then mkdir nginx && cd nginx cd share # if bash: no such thing comes, then mkdir share && cd share cd html # if bash: no such thing comes, then mkdir html && cd html cd .. && pwd # /usr/share/nginx mkdir wordpress # html directory is created for the hackers :p ### fully optional for the advanced users # fully chmod it to 777 and keep a html file named index.html with a separate Google Analytics code # ownership should be to www:www not root:www # set a Google alert for that Google Analytics ID # yeah it works. If ever get hacked from that path, # www means nginx will get hacked. You'll stop nginx # Install all security stuffs, block at Router level # check log for IP # block IP and start nginx |
WordPress Multisite is very difficult to manage from backend on security point.
We will replace Nginx default
virtual host located at /etc/nginx/sites-enabled/default
as well as the symlink :
1 | rm /etc/nginx/sites-enabled/default |
We will create a new one named thecustomizewindows
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | cd /etc/nginx/sites-available/ nano thecustomizewindows <pre> This should be for me : <pre> server { listen [::]:80 ipv6only=off; server_name abhishekghosh.net *.abhishekghosh.net abhishekghosh.pro www.abhishekghosh.pro; root /usr/share/nginx/wordpress; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php?$args ; } location ~ /favicon.ico { access_log off; log_not_found off; } location ~ \.php$ { try_files $uri /index.php; include fastcgi_params; fastcgi_pass unix:/var/run/php5-fpm.sock; } access_log /var/log/nginx/$host-access.log; error_log /var/log/nginx/thecustomizewindows-error.log; } |
That /var/log/nginx/thecustomizewindows-error.log
should exist.
If we hosted only this WordPress installation, the directives should be changed to the following:
1 2 | listen [::]:80 default_server ipv6only=off; server_name abhishekghosh.net *.abhishekghosh.net; |
If a moron creates a subdomain via WordPress, then it will be like :
1 2 3 4 5 6 7 8 9 | moron.abhishekghosh.net<.pre> Like `wordpress.com`. `$host` variable creates separate log files for each domain. It does thing like the `cat` utility. Symlink of this file inside the sites-enabled directory : <pre>ln -s /etc/nginx/sites-available/thecustomizewindows /etc/nginx/sites-enabled/thecustomizewindows |
Run :
1 | nginx -t && service nginx restart |
If everything runs fine, we will cheat a bit for security reason :
1 | nano /etc/nginx/sites-available/abhishekghosh |
Put misdirecting content :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ## All website's main configuration file server { listen [::]:80 ipv6only=off; ## ask your server admin before changing these server_name abhishekghosh.net *.abhishekghosh.net abhishekghosh.pro www.abhishekghosh.pro; ## main path root /usr/share/nginx/html; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php?$args ; } location ~ /favicon.ico { access_log off; log_not_found off; } location ~ \.php$ { try_files $uri /index.php; include fastcgi_params; fastcgi_pass unix:/var/run/php5-fpm.sock; } access_log /var/log/nginx/$host-access.log; error_log /var/log/nginx/abhishekghosh-error.log; } |
Understood? The hacker, if someway enters, naturally will think, /etc/nginx/sites-available/abhishekghosh
is the main file. You are a moron and someone has configured for you. These waste the time of the hacker. Where we get caught? By the HTML comments by various WordPress Plugins – from the cache plugins to anything. They echo the whole unix path on HTML output :
1 | Config from /etc/nginx/sites-available/thecustomizewindows/wp-content/plugins/moron-plugin/ad.php loaded |
This is why, the advanced coders get angry on PHP and WordPress. Hackers are also reading this! You have to apply a sense to give the output to the fake location /etc/nginx/sites-available/abhishekghosh
at fronted. Your basic target is to stop the hacker to change your HP Cloud Account’s Password!
/etc/nginx/nginx.conf
should be edited :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | user www-data; worker_processes auto; pid /var/run/nginx.pid; events { worker_connections 2560; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server_tokens off; client_max_body_size 8m; reset_timedout_connection on; index index.php index.html index.htm; include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; gzip_disable "msie6"; upstream php5-fpm { keepalive 8; server unix:/var/run/php5-fpm.sock; } include /etc/nginx/sites-enabled/*; } |
Some lines are deleted. Yeah. So :
1 | nginx -t && service nginx restart |
Now, from your MySQL server, You’ll normally run :
1 2 3 4 5 6 7 8 9 10 11 12 | mysql u root -p CREATE DATABASE notthiswordpressname; CREATE USER 'notthiswordpress_user'@'localhost' IDENTIFIED BY 'userealpassword'; GRANT ALL PRIVILEGES ON notthiswordpressname.* TO 'wordpress_user'@'userealpassword'; CREATE USER 'notthiswordpress_user'@'10.0.0.x' IDENTIFIED BY 'userealpassword'; ; change 10.0.0.x FLUSH PRIVILEGES; exit # for mysql exit # for the root user exit # for exiting SSH session # in short # you can not use && here like exit && exit or exit and then exit && exit |
It is normal, that you need to copy paste the real password somewhere. my.cnf
can have 0.0.0.0
as Bind IP. It does not matter much on HP Cloud’s setup. On Rackspace, as there is no visible Router, that Private IP is a bit dangerous. Again, paid Amazon is like HP Cloud. Digital Ocean is like Rackspace (minus the cost). Rackspace is worthless right now. We used Rackspace for the past 4 years. Excellent behavior. For the excellent behavior we are writing about HP Cloud! HP Cloud, IBM and the other old companies are reliable, Digital Ocean is least costly. But, on Digital Ocean, your instance can get deleted! Amazon is less reliable than HP Cloud, IBM and the other old companies.
Now, back to the 8 GB server instance, running for abhishekghosh.net
. Download and extract WordPress :
1 2 3 4 5 6 7 8 9 10 | wget http://wordpress.org/latest.tar.gz tar -xzvf l* && mv wordpress/* /usr/share/nginx/wordpress/ cat /usr/share/nginx/wordpress cd /usr/share/nginx/wordpress # you will see the contents rm -r wo* latest* read* READ* chown -R www-data:www-data /usr/share/nginx/wordpress ## I like # chown -R root:www-data /usr/share/nginx/wordpress ## this gives upload error, which can be fixed from wp-config.php |
Access the primary domain in your browser :
http://example.com/
Install WordPress! You will delete the first user later for security from MySQL. Use a peculiar username like PuTTYWind000z
or matcuttscutswebsitesin20115
. Now, we will enable Multisite and Create Additional Sites. You’ll get error like WordPress can not write etc. Thats the right security settings! If WordPress can write, hackers can also easily write! They’ll change the script to an executable to get shell access as root. Thats why, first, copy the suggested material from browser, then create the wp-config.php
file:
nano /usr/share/nginx/wordpress/wp-config.php
I chown it to :
chown -R wheel:www-data /usr/share/nginx/wordpress
It can give a bit pain initially, but secure. Again Nginx
can get only in trouble. wp-config.php
is a dangerous file!
Add the following code before the comment That's all, stop editing! Happy blogging
:
1 2 3 4 5 6 7 8 | /* Multisite*/ define( 'WP_ALLOW_MULTISITE', true ); define('SUBDOMAIN_INSTALL', true); define('DOMAIN_CURRENT_SITE', 'abhishekghosh.net'); define('PATH_CURRENT_SITE', '/'); define('SITE_ID_CURRENT_SITE', 1); define('BLOG_ID_CURRENT_SITE', 1); define('FS_METHOD', 'direct'); |
That define('FS_METHOD', 'direct');
will solve upload issue. You can tighten the security by chmod
value later. We need only read access to wp-admin
, wp-includes
except at the time of updates. A tight chmod
value is better. When you’ll update, again chmod
to 0777 or whatever you want. Again chmod
to a tighter after the update. PHP is a great software, thats why so much precaution! Ruby would need env, Python would need env. PHP needs nothing. If you put a PHP INFO
file at public root, you might get hacked. Yeah, its quite easy. Scripts are available to hack. Do not try those scripts on other’s server, even own server! Police will immediately arrive and put you inside a cage! You need a written permission only to hack your own website. Because, Cloud is Multitenant!
From the admin toolbar [top left], navigate to My Sites > Network Admin > Sites
. Click the [Add New] option to open the Add New Site form. Very nice thing indeed. It is typical :
Lather, rinse, repeat
model!
Anyway, from SSH (or WordPress panel) :
1 2 3 4 5 6 7 8 9 10 11 | cd /usr/share/nginx/wordpress/wp-content/plugins/ wget http://downloads.wordpress.org/plugin/wordpress-mu-domain-mapping.latest-stable.zip unzip wordpress-mu-domain-mapping.latest-stable.zip ls -l rm wordpress-mu-domain-mapping.latest-stable.zip cp /usr/share/nginx/wordpress/wp-content/plugins/wordpress-mu-domain-mapping/sunrise.php /usr/share/nginx/wordpress/wp-content/ cd .. && pwd # /usr/share/nginx/wordpress/wp-content/ mkdir mu-plugins # again chown, we did some crime chown -R www-data:www-data /usr/share/nginx/wordpress/wp-content/ |
Edit the wp-config.php
file again before That's all, stop editing! Happy blogging
, add this :
1 2 | nano /usr/share/nginx/wordpress/wp-config.php define('SUNRISE', 'on'); |
If we did it before, we would face White Page. May be. No warranty with PHP.
Save it. From the WordPress toolbar, navigate to My Sites > Network Admin > Plugins
. Click Network Activate link under the WordPress MU Domain Mapping plugin. Go to Settings > Domain Mapping
, Options should be modified like :
1 2 3 | Uncheck Remote Login Check Permanent Redirect Uncheck Redirect administration pages to site's original domain |
Unchecking the option 2 and checking the option 5 can create duplicate content issues with search engines. This is why You’ll see, self hosted websites works better in long term. Self hosted = 1 server, 1 website at minimum.
Click Save.
Basically, mapping a domain name to each site based on the site ID. For easier administration we will create a WordPress plugin that displays an additional ID column on the Sites page. It depends on the usage. If you are offering a paid system, them probably it is a bad idea. Here is a Plugin, put it inside mu-plugins folder :
1 | https://gist.github.com/AbhishekGhosh/897d36d120eb4c7f79d8 |
The Sites > All Sites section should now show an additional ID column. Note down the ID values for each site.
Edit the php.ini
file:
1 2 3 | nano /etc/php5/fpm/php.ini # find it and increase it to upload_max_filesize = 2M |
Reload PHP5-FPM:
1 2 3 4 5 6 7 8 | service php5-fpm reload pidof php5-fpm # change ID with real of your own 21397 21396 21395 kill 21395 kill 21396 kill 21397 service php5-fpm start |
Alternative /etc/nginx/sites-available/default
can be :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | server { server_name example.com *.example.com ; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; root /usr/share/nginx/html; index index.php; if (!-e $request_filename) { rewrite /wp-admin$ $scheme://$host$uri/ permanent; rewrite ^(/[^/]+)?(/wp-.*) $2 last; rewrite ^(/[^/]+)?(/.*\.php) $2 last; } location / { try_files $uri $uri/ /index.php?$args ; } location ~ \.php$ { try_files $uri /index.php; include fastcgi_params; fastcgi_pass unix:/var/run/php5-fpm.sock; # Yoast SEO rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last; rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=$1&sitemap_n=$2 last; } location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ { access_log off; log_not_found off; expires max; } location = /robots.txt { access_log off; log_not_found off; } location ~ /\. { deny all; access_log off; log_not_found off; } } |
As you can understand, this guide WordPress Multisite on Nginx on Ubuntu 14.04 on HP Cloud is a basic guide, it is very dangerous to run WordPress Multisite on Nginx without 24×7 management. Those PHP-WordPress guys knows only to increase RAM, Memcached etceteras. Unless you run a business with domains, do not run these. For learning, its good but these are not practical as there is no real IP based or name based virtual host. Google, basically do not like it except the whitelisted domains. Otherwise all top notch blogs including us, would offer $1.00 per month nginx hosting service! In Codex, there are something written :
1 | http://codex.wordpress.org/Network_Admin |
I wrote something there along with the others. Whatever, you might face error, you might need to edit a bit, but this way will give 95% chance to run without pain. It is very complicated to optimize FPM or FAST CGI. There is way to make WordPress WP-Admin running on different server – Move WordPress Administration to Different Server or Sub-Domain. Thats great to prevent getting hacked. We have separate guides for optimizing the parts of everything mentioned here.
Your Database server is the main Server! That is the Application Server. There are all the post contents, all data. FTP server only saves the media content. Taking backup of MySQL database and WP-Content will work fine. Openstack Snapshots will be very big. Keep one Snapshot at running condition and take file level backup manually from a third server.
You can ask Rackspace or HP Cloud’s support personnel as a client – whether this WordPress Multisite on Nginx is safe or not, they will ask your need. That falls among Cloud Consultancy. Do not use hundreds of Plugins if you resell. The plugins, themes for sites should be manually checked, links removed, any tracking code needs deletion.