How to setup multiple WordPress on Ubuntu 16.04
Introduction
WordPress is the most popular website framework in the world, powering 30% of the web all around the world. Over 60 million people have chosen WordPress to power the place on the web they call “home”.
In this tutorial, we will demonstrate how to setup multiple WordPress websites on a same Ubuntu 16.04 server. The setup includes nginx, MySQL, PHP, and WordPress itself.
Prerequisites
Before you complete this tutorial, you should have a regular, non-root user account on your server with sudo privileges. You can learn how to set up this type of account by completing DigitalOcean’s Ubuntu 16.04 initial server setup.
Once you have your user available, sign into your server with that username. You are now ready to begin the steps outlined in this guide.
Step 1. Install the Nginx Web Server
Install nginx
$ sudo apt-get update $ sudo apt-get install nginx
Enable ufw to allow HTTP
$ sudo ufw allow 'Nginx HTTP'
Verify the change
$ sudo ufw status
You should see HTTP traffic allowed in the displayed output:
Output Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx HTTP ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx HTTP (v6) ALLOW Anywhere (v6)
With the new firewall rule added, you can test if the server is up and running by accessing your server’s domain name or public IP address in your web browser.
Navigate your browser to test if nginx is working:
Test Nginx’s default landing page in browser
http://server_domain_or_IP
If you see the above page, you have successfully installed Nginx.
Step 2. Install MySQL to Manage Site Data
Now that we have a web server, we need to install MySQL, a database management system, to store and manage the data for our site.
Install MySQL server
$ sudo apt-get install mysql-server
You will be asked to supply a root (administrative) password for use within the MySQL system.
The MySQL database software is now installed, but its configuration is not exactly complete yet.
To secure the installation, we can run a simple security script that will ask whether we want to modify some insecure defaults. Begin the script by typing:
Secure MySQL installation
$ sudo mysql_secure_installation
You will be asked to enter the password you set for the MySQL root account. Next, you will be asked if you want to configure the VALIDATE PASSWORD PLUGIN
.
Warning: Enabling this feature is something of a judgment call. If enabled, passwords which don’t match the specified criteria will be rejected by MySQL with an error. This will cause issues if you use a weak password in conjunction with software which automatically configures MySQL user credentials, such as the Ubuntu packages for phpMyAdmin. It is safe to leave validation disabled, but you should always use strong, unique passwords for database credentials.
Answer y for yes, or anything else to continue without enabling.
VALIDATE PASSWORD PLUGIN can be used to test passwords and improve security. It checks the strength of password and allows the users to set only those passwords which are secure enough. Would you like to setup VALIDATE PASSWORD plugin? Press y|Y for Yes, any other key for No:
If you’ve enabled validation, you’ll be asked to select a level of password validation. Keep in mind that if you enter 2
, for the strongest level, you will receive errors when attempting to set any password which does not contain numbers, upper and lowercase letters, and special characters, or which is based on common dictionary words.
There are three levels of password validation policy: LOW Length >= 8 MEDIUM Length >= 8, numeric, mixed case, and special characters STRONG Length >= 8, numeric, mixed case, special characters and dictionary file Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 1
If you enabled password validation, you’ll be shown a password strength for the existing root password, and asked you if you want to change that password. If you are happy with your current password, enter n for “no” at the prompt:
Using existing password for root. Estimated strength of the password: 100 Change the password for root ? ((Press y|Y for Yes, any other key for No) : n
For the rest of the questions, you should press Y
and hit the Enter
key at each prompt. This will remove some anonymous users and the test database, disable remote root logins, and load these new rules so that MySQL immediately respects the changes we have made.
At this point, your database system is now set up and we can move on.
Step 3. Install PHP for Processing
We now have Nginx installed to serve our pages and MySQL installed to store and manage our data. However, we still don’t have anything that can generate dynamic content. We can use PHP for this.
Since Nginx does not contain native PHP processing like some other web servers, we will need to install php-fpm, which stands for “fastCGI process manager”. We will tell Nginx to pass PHP requests to this software for processing.
We can install this module and will also grab an additional helper package that will allow PHP to communicate with our database backend. The installation will pull in the necessary PHP core files. Do this by typing:
Install php-fpm and php-mysql
$ sudo apt-get install php-fpm php-mysql
Configure the PHP Processor
We now have our PHP components installed, but we need to make a slight configuration change to make our setup more secure.
Open the main php-fpm
configuration file with root privileges:
$ sudo nano /etc/php/7.0/fpm/php.ini
What we are looking for in this file is the parameter that sets cgi.fix_pathinfo
. This will be commented out with a semi-colon (;) and set to “1” by default.
This is an extremely insecure setting because it tells PHP to attempt to execute the closest file it can find if the requested PHP file cannot be found. This basically would allow users to craft PHP requests in a way that would allow them to execute scripts that they shouldn’t be allowed to execute.
We will change both of these conditions by uncommenting the line and setting it to “0” like this:
Change cgi.fix_pathinfo
# /etc/php/7.0/fpm/php.ini cgi.fix_pathinfo=0
Save and close the file when you are finished.
Now, we just need to restart our PHP processor by typing:
Restart PHP processor
$ sudo systemctl restart php7.0-fpm
This will implement the change that we made.
Step 4. Install WordPress
The plan
To make the best use of the server, we will setup the server so that we can also host other websites in PHP or Python in the future. To do that, we will have the following arrangement:
- Websites’ source code will stay in
/www/hexadix.com/ /www/example.com/
- Each website configuration will be saved in
/etc/nginx/sites-enabled/hexadix.com.conf /etc/nginx/sites-enabled/example.com.conf
- The full configuration for each website will be in the above mentioned file. The default nginx configuration file will be removed.
/www
folder will be chown to nginx’s user
By default, nginx will run as
www-data
ornginx
, you can find this out by runningps aux | grep nginx
in your terminal)
Using this arrangement, we can freely add future websites in such manner so everything is kept organized.
Step 4.1. Create database for your WordPress
Login to MySQL shell
$ mysql -u root -p
Create database and mysql user for our WordPress
mysql> CREATE DATABASE wordpress CHARACTER SET utf8 COLLATE utf8_unicode_ci; mysql> CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'wppassword'; mysql> GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost'; mysql> FLUSH PRIVILEGES; mysql> SHOW GRANTS FOR 'wpuser'@'localhost';
A common practice here is to use website name as database name, and also as database user name. This way, each database user will have access to only its database, and the naming convention is easy to remember.
Step 4.2. Setup WordPress folder
Change directory to /www
$ cd /www
Download the latest WordPress.
$ wget http://wordpress.org/latest.tar.gz
Extract it.
$ tar -zxvf latest.tar.gz
Move it to our document root.
$ mv wordpress/* /www/hexadix.com
Copy the wp-sample-config.php file and make it as wp-config.php file.
$ cp /www/hexadix.com/wp-config-sample.php /www/hexadix.com/wp-config.php
Edit the config file and mention the database information.
$ vi /www/hexadix.com/wp-config.php
Default will look like below.
# /www/hexadix.com/wp-config.php // ** MySQL settings – You can get this info from your web host ** // /** The name of the database for WordPress */ define('DB_NAME', 'database_name_here'); /** MySQL database username */ define('DB_USER', 'username_here'); /** MySQL database password */ define('DB_PASSWORD', 'password_here'); /** MySQL hostname */ define('DB_HOST', 'localhost');
Modified entries according to the created database user and database will look like.
# /www/hexadix.com/wp-config.php // ** MySQL settings – You can get this info from your web host ** // /** The name of the database for WordPress */ define('DB_NAME', 'wordpress'); /** MySQL database username */ define('DB_USER', 'wpuser'); /** MySQL database password */ define('DB_PASSWORD', 'wppassword'); /** MySQL hostname */ define('DB_HOST', 'localhost');
Make nginx user as the owner to WordPress directory.
$ chown -R www-data:www-data /www/hexadix.com/
Step 4.3. Configure nginx
Open nginx main configuration file
$ sudo vi /etc/nginx/nginx.conf
Look for the line below.
include /etc/nginx/sites-enabled/*;
Change it to
include /etc/nginx/sites-enabled/*.conf;
The purpose of this step is to tell nginx to only load files with .conf extension. This way, whenever we want to disable a website, we only need to change the extension of that website’s configuration file to something else, which is more convenient.
Test new nginx configuration
$ sudo nginx -t
Reload nginx
$ sudo systemctl reload nginx
If everything works correctly, when you navigate your browser to your website now, the default Welcome to Nginx page would have been disabled.
Create nginx configuration file for our WordPress
$ sudo vi /etc/nginx/sites-enabled/hexadix.com.conf
Put the following content in the file
server { listen 80; server_name hexadix.com www.hexadix.com; root /www/hexadix.com; index index.php index.html index.htm; if (!-e $request_filename) { rewrite /wp-admin$ $scheme://$host$uri/ permanent; rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last; rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last; } location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { try_files $uri $uri/ /index.php?q=$uri&$args; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
Remember to change the server_name
and root
to match your website. Also, the fastcgi_pass
path may differ in your server installation.
Test new nginx configuration
$ sudo nginx -t
Reload nginx
$ sudo systemctl reload nginx
If everything works correctly, by this time you can navigate to your domain (in this case http://hexadix.com) and see your WordPress Installation Wizard page. Follow the instruction on the Wizard to setup an admin account and you’re done.
You can now login to your WordPress administrator site by navigating to:
http://yourdomain.com/wp-admin/
Your front page is at:
http://yourdomain.com
Setup multiple WordPress
To setup another WordPress on the same server, repeat the whole Step 4 in the same manner with the corresponding configurations.
Conclusion
You should now have multiple WordPress websites on your Ubuntu 16.04. Now you can setup as many additional websites as you may need by following the same steps in the tutorial.