{"id":186,"date":"2017-12-17T11:48:02","date_gmt":"2017-12-17T11:48:02","guid":{"rendered":"https:\/\/learningcurve.xyz\/?p=186"},"modified":"2017-12-19T04:50:11","modified_gmt":"2017-12-19T04:50:11","slug":"alibaba-cloud-4-install-wordpress","status":"publish","type":"post","link":"https:\/\/learningcurve.xyz\/?p=186","title":{"rendered":"Alibaba Cloud 4 &#8211; Install WordPress"},"content":{"rendered":"<p>So here we are&#8230; The final part of our series, our <a href=\"http:\/\/learningcurve.dev\/2017\/10\/09\/alibaba-cloud-ubuntu-16-04-ecs-instance\/\" target=\"_blank\" rel=\"noopener\">Alibaba Ubuntu 16.04 ECS instance<\/a> is ready, we have <a href=\"http:\/\/learningcurve.dev\/2017\/10\/10\/alibaba-cloud-lemp-stack\/\" target=\"_blank\" rel=\"noopener\">NGINX, MariaDB, and PHP7<\/a> completing our stack. Our domain is configured and our site is protected with a <a href=\"http:\/\/learningcurve.dev\/2017\/10\/12\/alibaba-cloud-domain-and-lets-encrypt-ssl\/\" target=\"_blank\" rel=\"noopener\">Let&#8217;s Encrypt SSL certificate<\/a>. We are all ready to install WordPress, happy days!<\/p>\n<p>Completing the previous tutorials is a prerequisite for this one, so if you haven&#8217;t completed them yet, then follow the links above and come back here when you&#8217;re done.<\/p>\n<p>I would also be remiss to not point out, again, that most everything in this tutorial will work on most cloud providers.<\/p>\n<h2>Step 1. Configure NGINX for WordPress<\/h2>\n<p>The First thing we need to do is make some slight modifications to our NGINX server blocks. Open the default NGINX configuration file with <span class=\"grey-code\"> sudo<\/span> privileges:<\/p>\n<pre>$ sudo nano \/etc\/nginx\/sites-available\/default\r\n<\/pre>\n<p>Within the server block we need to add some locations blocks.<\/p>\n<p>Turn off logging requests for <span class=\"grey-code\"> \/favicon.ico<\/span> and <span class=\"grey-code\"> \/robots.txt<\/span>. Then use a regular expression to match requests for static files, then turn logging off for these requests too, and mark them as highly cacheable since they are generally expensive resources to serve. If you have any other static files you want to cache, add them here too:<\/p>\n<pre>server {\r\n    . . .\r\n\r\n    location = \/favicon.ico { log_not_found off; access_log off; }\r\n    location = \/robots.txt { log_not_found off; access_log off; allow all; }\r\n    location ~* \\.(css|gif|ico|jpeg|jpg|js|png)$ {\r\n        expires max;\r\n        log_not_found off;\r\n    }\r\n    . . .\r\n}\r\n<\/pre>\n<p>We also need to make some adjustments inside the <span class=\"grey-code\"> location \/<\/span> block.<\/p>\n<p>Comment out the <span class=\"grey-code\"> try_files<\/span> list line, where it returns a 404 error as a default option, and add code that passes control to the <span class=\"grey-code\"> index.php <\/span> file with the request argument instead:<\/p>\n<pre>server {\r\n    . . .\r\n\t\r\n    location \/ {\r\n        #try_files $uri $uri\/ =404;\r\n        try_files $uri $uri\/ \/index.php$is_args$args;\r\n    }\r\n\t\r\n    . . .\r\n}\r\n<\/pre>\n<p>When you are finished your NGINX configuration file should look like the following:<\/p>\n<figure id=\"attachment_274\" aria-describedby=\"caption-attachment-274\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-274 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/change_nginx_conf_wordpress-600x815.png\" alt=\"\" width=\"600\" height=\"815\" \/><figcaption id=\"caption-attachment-274\" class=\"wp-caption-text\">Adjust NGINX configuration file for WordPress<\/figcaption><\/figure>\n<p>Make sure to check for syntax errors:<\/p>\n<pre>$ sudo nginx -t\r\n<\/pre>\n<p>If there are none, reload NGINX:<\/p>\n<pre>sudo systemctl reload nginx\r\n<\/pre>\n<h2>Step 2. Install PHP Extensions most commonly used with WordPress<\/h2>\n<p>Previously we only installed the minimum PHP extensions required to get PHP to communicate with MariaDB and NGINX. However WordPress and its myriad ecosystem of plugins often leverage additional PHP extensions for increased functionality. We will install some of the most popular ones next.<\/p>\n<p>This step is optional, you could install these as and when you need them, but since we are already tweaking the LEMP stack for WordPress, why not do these now?<\/p>\n<p>First update your package repository index, and then install the chosen extensions by entering:<\/p>\n<pre>$ sudo apt-get update\r\n$ sudo apt-get install php-curl php-gd php-mbstring php-mcrypt php-xml php-xmlrpc\r\n<\/pre>\n<p>Once they are finished installing, we need to restart the PHP-FPM process so these new features can be leveraged:<\/p>\n<pre>sudo systemctl restart php7.0-fpm\r\n<\/pre>\n<p>Now PHP and NGINX are ready, we just need to add our Database with MariaDB and we can move on to WordPress.<\/p>\n<h2>Step 3. Create a MySQL Database and User for WordPress<\/h2>\n<p>WordPress needs a MySQL Database to store site and user information. In the previous tutorial we installedd MariaDB as a drop in, more performant, replacement for MySQL.<\/p>\n<p>Now we need to use MariaDB to create the Database and User for WordPress to use.<\/p>\n<p>Log in to MariaDB, with root privileges, using the following <span class=\"grey-code\"> mysql<\/span> command:<\/p>\n<pre>$ sudo mysql -u root -p\r\n<\/pre>\n<p>As usual, you will need to enter your superuser password before you can progress.<\/p>\n<p>Now create a Database for WordPress. Name it appropriately, for this tutorial I will be sticking with <span class=\"grey-code\"> wordpress<\/span> as my database name:<\/p>\n<pre>MariaDB [(none)]&gt; CREATE DATABASE <span class=\"green\">wordpress<\/span> DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;\r\n<\/pre>\n<p>Next we need to create the user for this database. This user will be exclusive to our new database. I&#8217;m just going to use the same username as I have for my superuser, to keep things simple. You should choose whatever username you think is appropriate. I am also using a simple password for the benefit of the tutorial, but yours should be much more secure:<\/p>\n<pre>MariaDB [(none)]&gt; GRANT ALL ON <span class=\"green\">wordpress<\/span>.* TO '<span class=\"green\">new_user<\/span>'@'localhost' IDENTIFIED BY '<span class=\"orange\">new_users_password<\/span>';\r\n<\/pre>\n<p>Now we have the necessary Database and User account, all we have to do is flush the privileges so that MariaDB knows about the changes we&#8217;ve made. Then exit MariaDB:<\/p>\n<pre>MariaDB [(none)]&gt; FLUSH PRIVILEGES;\r\nMariaDB [(none)]&gt; EXIT;\r\n<\/pre>\n<p>If you have followed along exactly, then your terminal should look like this:<\/p>\n<figure id=\"attachment_277\" aria-describedby=\"caption-attachment-277\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-277 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/wordpress_mariadb-600x550.png\" alt=\"\" width=\"600\" height=\"550\" \/><figcaption id=\"caption-attachment-277\" class=\"wp-caption-text\">Create a MariaDB Database and User for WordPress<\/figcaption><\/figure>\n<h2>Step 4. Configure root directory ownerships<\/h2>\n<p>We will be setting up WordPress in the <span class=\"grey-code\"> \/var\/www\/html<\/span> directory, as set up in our NGINX configuration file server block. Change directory to this directory:<\/p>\n<pre>$ cd \/var\/www\/html\r\n<\/pre>\n<p>If we try to import the WordPress files in this directory immediately, then we will receive a permissions error. That is because this directory currently belongs to <span class=\"grey-code\"> root<\/span> user in the <span class=\"grey-code\"> root<\/span> group.<\/p>\n<p>You can verify this by entering the following command to show the owner:<\/p>\n<pre>$ ls -l\r\n<\/pre>\n<p>Your terminal will display the file and directory permissions, owner, date, time, and contents. You should see <span class=\"grey-code\"> root<\/span> <span class=\"grey-code\"> root<\/span> in the output.<\/p>\n<p>We will need to change the owner of the directory and the group the directory belongs to, in order to allow us to write the files we need within.<\/p>\n<p>First, with root privileges, add your superuser to the <span class=\"grey-code\"> www-data<\/span> usergroup, this is the NGINX server&#8217;s usergroup. In my case that is <span class=\"grey-code\"> new_user<\/span>:<\/p>\n<pre>$ sudo usermod -aG www-data <span class=\"green\">new_user<\/span>\r\n<\/pre>\n<p>Next, change the ownership of the <span class=\"grey-code\"> \/var\/www\/html<\/span> directory to your superuser and the <span class=\"grey-code\"> www-data<\/span> usergroup. In the case of my <span class=\"grey-code\"> new_user<\/span> that would be the following command:<\/p>\n<pre>$ sudo chown -R <span class=\"green\">new_user<\/span>:www-data \/var\/www\/html\r\n<\/pre>\n<p>Once this is done you can check the ownership of the directory again with the same command as previously:<\/p>\n<pre>$ ls -l\r\n<\/pre>\n<p>Now the terminal should show the directory as belonging to your superuser and the <span class=\"grey-code\"> www-data<\/span> usergroup. If everything has been completed correctly, your terminal should look like the following:<\/p>\n<figure id=\"attachment_279\" aria-describedby=\"caption-attachment-279\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-279 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/chown_html-600x228.png\" alt=\"\" width=\"600\" height=\"228\" \/><figcaption id=\"caption-attachment-279\" class=\"wp-caption-text\">Change ownership of the directory for WordPress<\/figcaption><\/figure>\n<p>We will be revisiting this directory and its ownership once we have installed WordPress, as it currently stands we won&#8217;t be able to install themes and plugins once WordPress is up and running. We can do that later.<\/p>\n<h2>Install WordPress (Huzzah!!!)<\/h2>\n<p>Wait&#8230; you have a decision to make. This tutorial is going to show you two ways to install WordPress.<\/p>\n<p>The first is the original way, using <span class=\"grey-code\"> curl<\/span> and editing config files using nano etc. It is trusty and reliable method, and worth going through.<\/p>\n<p>The second is using <a href=\"http:\/\/wp-cli.org\/\" target=\"_blank\" rel=\"noopener\">WP CLI<\/a>, the awesome command line interface for WordPress, if you haven&#8217;t used it before then this is your chance to start. It&#8217;s awesome, and, once you get used to it, you can use it to manage all your WordPress sites with a workflow that offers such increased speed and efficiencies that you will never look back.<\/p>\n<h2>Step 5. Install WordPress using CURL<\/h2>\n<h3>Step 5a. Download WordPress<\/h3>\n<p>Change into a writable directory, yes I know we just took ownership of the WordPress destination directory, but this is just to be safe:<\/p>\n<pre>$ cd \/tmp\r\n<\/pre>\n<p>Now use <span class=\"grey-code\"> curl<\/span> to download the compressed release with the following command:<\/p>\n<pre>$ curl -O https:\/\/wordpress.org\/latest.tar.gz\r\n<\/pre>\n<p>Then extract the compressed file to create the WordPress directory and structure:<\/p>\n<pre>$ tar xzvf latest.tar.gz\r\n<\/pre>\n<p>Next we need to change the <span class=\"grey-code\"> wp-config-sample.php<\/span> file into the <span class=\"grey-code\"> wp-config.php<\/span> filename needed by wordpress, use the copy command like so:<\/p>\n<pre>$ cp \/tmp\/wordpress\/wp-config-sample.php \/tmp\/wordpress\/wp-config.php\r\n<\/pre>\n<p>We also need to create the <span class=\"grey-code\"> upgrade<\/span> directory needed by WordPress, so that it won&#8217;t run into permissino problems later when it tries to do this on it&#8217;s own:<\/p>\n<pre>$ mkdir \/tmp\/wordpress\/wp-content\/upgrade\r\n<\/pre>\n<p>Okay, now we have a correctly configured and structured WordPress directory in the <span class=\"grey-code\"> \/tmp<\/span> directory, we can copy its entire contents into our html root directory. We will use the <span class=\"grey-code\"> -a<\/span> flag to maintain permissions. Notice the <span class=\"grey-code\"> .<\/span> period at the end of our source directory, this indicates that everything in the directory should be copied, including hidden files:<\/p>\n<pre>$ sudo cp -a \/tmp\/wordpress\/. \/var\/www\/html\r\n<\/pre>\n<h3>Step 5b. Set up the WordPress Configuration File<\/h3>\n<p>We need to configure some settings in the <span class=\"grey-code\"> wp-config.php<\/span> file so WordPress can talk to our database, and also to secure the installation.<\/p>\n<p>Open the configuration file:<\/p>\n<pre>$ nano \/var\/www\/html\/wp-config.php\r\n<\/pre>\n<p>Enter the settings for the database we created with MariaDB earlier. You will need to correctly enter the name of the database, the database user, database user password and localhost, from earlier:<\/p>\n<pre>. . .\r\n\r\ndefine('DB_NAME', '<span class=\"green\">wordpress<\/span>');\r\n\r\n\/** MySQL database username *\/\r\ndefine('DB_USER', '<span class=\"green\">new_user<\/span>');\r\n\r\n\/** MySQL database password *\/\r\ndefine('DB_PASSWORD', '<span class=\"green\">new_users_password<\/span>');\r\n\r\n\/** MySQL hostname *\/\r\ndefine('DB_HOST', '<span class=\"green\">localhost<\/span>');\r\n\r\n. . .\r\n<\/pre>\n<p>Close the file and save it.<\/p>\n<p>In my case, my <span class=\"grey-code\"> wp-config.php<\/span> now looks like the following, yours should be similar:<\/p>\n<figure id=\"attachment_280\" aria-describedby=\"caption-attachment-280\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-280 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/wp-config_db-600x532.png\" alt=\"\" width=\"600\" height=\"532\" \/><figcaption id=\"caption-attachment-280\" class=\"wp-caption-text\">Add your Database settings to wp-config.php<\/figcaption><\/figure>\n<p>The <span class=\"grey-code\"> wp-config.php<\/span> file will also contain a section for secure &#8216;salt&#8217; keys. It will look like this:<\/p>\n<pre>. . .\r\n\r\ndefine('AUTH_KEY',         'put your unique phrase here');\r\ndefine('SECURE_AUTH_KEY',  'put your unique phrase here');\r\ndefine('LOGGED_IN_KEY',    'put your unique phrase here');\r\ndefine('NONCE_KEY',        'put your unique phrase here');\r\ndefine('AUTH_SALT',        'put your unique phrase here');\r\ndefine('SECURE_AUTH_SALT', 'put your unique phrase here');\r\ndefine('LOGGED_IN_SALT',   'put your unique phrase here');\r\ndefine('NONCE_SALT',       'put your unique phrase here');\r\n\r\n. . .\r\n<\/pre>\n<p>You will need to replace these keys with secure key values. We can get them from the WordPress secret key generator with the following command:<\/p>\n<pre>$ curl -s https:\/\/api.wordpress.org\/secret-key\/1.1\/salt\/<\/pre>\n<p>Your terminal will display some unique values that look like the following:<\/p>\n<figure id=\"attachment_281\" aria-describedby=\"caption-attachment-281\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-281 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/curl_salt_keys-600x533.png\" alt=\"\" width=\"600\" height=\"533\" \/><figcaption id=\"caption-attachment-281\" class=\"wp-caption-text\">Generate unique salt keys with the WordPress salt key generator<\/figcaption><\/figure>\n<p>Copy the salt keys.<\/p>\n<p>Open the<span class=\"grey-code\"> wp-config.php<\/span> file, and paste these keys in place of the placeholder values:<\/p>\n<pre>$ nano \/var\/www\/html\/wp-config.php\r\n<\/pre>\n<figure id=\"attachment_282\" aria-describedby=\"caption-attachment-282\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-282 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/wp-config_salt-600x531.png\" alt=\"\" width=\"600\" height=\"531\" \/><figcaption id=\"caption-attachment-282\" class=\"wp-caption-text\">Copy the secure salt keys into your wp-config.php<\/figcaption><\/figure>\n<p>Make sure you close and save the <span class=\"grey-code\"> wp-config.php<\/span> file.<\/p>\n<p>Now you&#8217;re ready to complete the installation.<\/p>\n<h3>Step 5c. Complete the Famous WordPress 5 Minute Installation through the web interface<\/h3>\n<p>The server configuration is complete and teh WordPress directory and Configuration file is prepared, so now you can complete WordPress&#8217;s famous 5 minute installation by visiting your domain. Open your browser and navigate to your domain url:<\/p>\n<pre>https:\/\/<span class=\"green\">an-example-domain.com<\/span>\r\n<\/pre>\n<p>You will need to select your installation language, and then you&#8217;ll be prompted to complete your site and admin user information:<\/p>\n<figure id=\"attachment_283\" aria-describedby=\"caption-attachment-283\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-283 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/install_wp_traditional-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-283\" class=\"wp-caption-text\">Complete the famous WordPress 5 minute installation<\/figcaption><\/figure>\n<p>Click install WordPress and you are done:<\/p>\n<figure id=\"attachment_284\" aria-describedby=\"caption-attachment-284\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-284 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/wp_installed_old_skool-600x375.jpg\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-284\" class=\"wp-caption-text\">WordPress installed the Old Skool way!<\/figcaption><\/figure>\n<p>Your WordPress site should be up and running, and secured with an SSL.<\/p>\n<p>Permissions will need some adjusting to allow you to install and delete plugins and themes, and make other WordPress configuration changes, but we can do that later.<\/p>\n<p>Next we shall install WordPress using the fantastic WP CLI.<\/p>\n<h2>Step 6. Installing WordPress using WP-CLI<\/h2>\n<h3>Step 6a. Install WP-CLI<\/h3>\n<p>You can download the WP-CLI PHP Archive file <span class=\"grey-code\"> wp-cli.phar<\/span> using either <span class=\"grey-code\"> curl<\/span> or <span class=\"grey-code\"> wget<\/span> commands:<\/p>\n<pre>$ curl -O https:\/\/raw.githubusercontent.com\/wp-cli\/builds\/gh-pages\/phar\/wp-cli.phar\r\n<\/pre>\n<p>or<\/p>\n<pre>$ wget https:\/\/raw.githubusercontent.com\/wp-cli\/builds\/gh-pages\/phar\/wp-cli.phar\r\n<\/pre>\n<p>Next, you need to make the <span class=\"grey-code\"> wp-cli.phar<\/span> file executable, and move it to the <span class=\"grey-code\"> \/usr\/local\/bin<\/span> directory, so that it can be run directly:<\/p>\n<pre>$ chmod +x wp-cli.phar\r\n$ sudo mv wp-cli.phar \/usr\/local\/bin\/wp\r\n<\/pre>\n<p>When these commands are completed, your terminal should look like the following:<\/p>\n<figure id=\"attachment_285\" aria-describedby=\"caption-attachment-285\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-285 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/install_wpcli-600x553.png\" alt=\"\" width=\"600\" height=\"553\" \/><figcaption id=\"caption-attachment-285\" class=\"wp-caption-text\">Install WP-CLI<\/figcaption><\/figure>\n<p>You can check that it has been installed correctly by checking it&#8217;s info:<\/p>\n<pre>$ wp --info\r\n<\/pre>\n<p>If you see something similar to the following, you can proceed:<\/p>\n<figure id=\"attachment_286\" aria-describedby=\"caption-attachment-286\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-286 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/wpcli_info-600x352.png\" alt=\"\" width=\"600\" height=\"352\" \/><figcaption id=\"caption-attachment-286\" class=\"wp-caption-text\">Check wp &#8211;info to ensure WP-CLI installed correctly<\/figcaption><\/figure>\n<p>You will want to activate Bash Completion, this allows you to see all the available WP-CLI commands on the fly.<\/p>\n<p>First, download the bash script into your home directory:<\/p>\n<pre>$ cd ~\/\r\n$ wget https:\/\/github.com\/wp-cli\/wp-cli\/raw\/master\/utils\/wp-completion.bash\r\n<\/pre>\n<p>Next open the <span class=\"grey-code\"> .bashrc<\/span> file:<\/p>\n<pre>$ nano .bashrc\r\n<\/pre>\n<p>Add the folllwing line of code at the end of the <span class=\"grey-code\"> .bashrc<\/span> file:<\/p>\n<pre>. . .\r\nsource \/home\/$USER\/wp-completion.bash\r\n<\/pre>\n<p>In the nano editor, the file should look like the following:<\/p>\n<figure id=\"attachment_287\" aria-describedby=\"caption-attachment-287\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-287 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/nano_wpcli_bash_source-600x572.png\" alt=\"\" width=\"600\" height=\"572\" \/><figcaption id=\"caption-attachment-287\" class=\"wp-caption-text\">Edit the .bashrc file so the shell loads it every time you login<\/figcaption><\/figure>\n<p>Close and save the file, then run the following command to reload the bash profile:<\/p>\n<pre>$ source ~\/.bashrc\r\n<\/pre>\n<p>Bash completion is now enabled, you can test this by typing <span class=\"grey-code\">wp theme<\/span>, including the trailing space, and then press tab twice. You will see a list of available commands with the <span class=\"grey-code\">wp theme<\/span> prompt.<\/p>\n<p>Your terminal should be showing:<\/p>\n<figure id=\"attachment_288\" aria-describedby=\"caption-attachment-288\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-288 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/source_bash-600x192.png\" alt=\"\" width=\"600\" height=\"192\" \/><figcaption id=\"caption-attachment-288\" class=\"wp-caption-text\">Test Bash Completion<\/figcaption><\/figure>\n<h3>Step 6b. Install WordPress using WP-CLI<\/h3>\n<p>Move to the <span class=\"grey-code\"> \/var\/www\/html <\/span> root directory for the site:<\/p>\n<pre>$ cd \/var\/www\/html\r\n<\/pre>\n<p>This is where we will download the WordPress files. We took ownership of the directory previously, so we shouldn&#8217;t run into any errors while downloading the files and unpacking them:<\/p>\n<pre>$ wp core download --locale=en_GB\r\n<\/pre>\n<p>You might think that I am downloading the British English version because I am British. Whilst that may be true, it&#8217;s also because there is currently a problem with the <span class=\"grey-code\">&#8211;locale=en_US<\/span> US English download.<\/p>\n<p>At the time of writing this tutorial downloading the US version throws an error during the unpack. I initially didn&#8217;t use a locale, which defaults to US English download, so this error had me running in circles until I found a github error log suggesting using a different language pack, and low and behold, it worked.<\/p>\n<p>Since I am British, this is okay, and it&#8217;s an opportunity for my US English speaking cousins to learn some proper English &#8211; win win!<\/p>\n<p>Now we need to create our wp-config file using our database values:<\/p>\n<pre>$ wp core config --dbname=<span class=\"green\">wordpress<\/span> --dbuser=<span class=\"green\">new_user<\/span> --dbpass=<span class=\"green\">new_users_password<\/span> --dbhost=<span class=\"green\">localhost<\/span> --dbprefix=<span class=\"green\">wp_<\/span>\r\n<\/pre>\n<p>Obviously you should use the database values that you created with MariaDB earlier, and not mine. Also notice how we don&#8217;t need to bother with the WordPress Salt Key Generator, that&#8217;s because WP-CLI does that for us &#8211; bonus.<\/p>\n<p>Finally, all we need to do is run the installation with the following command:<\/p>\n<pre>$ wp core install --url=\"<span class=\"green\">https:\/\/an-example-domain.com<\/span>\" --title=\"<span class=\"green\">New Skool WP-CLI Installation<\/span>\" --admin_user=\"<span class=\"green\">new_user<\/span>\" --admin_password=\"<span class=\"green\">some_password<\/span>\" --admin_email=\"<span class=\"green\">email@domain.com<\/span>\"\r\n<\/pre>\n<p>Again, make sure to use the values for your domain, admin username, password and email. Your terminal should look something like this:<\/p>\n<figure id=\"attachment_289\" aria-describedby=\"caption-attachment-289\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-289 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/wp_core_download_config_install-600x472.png\" alt=\"\" width=\"600\" height=\"472\" \/><figcaption id=\"caption-attachment-289\" class=\"wp-caption-text\">Install WordPress with WP-CLI<\/figcaption><\/figure>\n<p>And that&#8217;s it&#8230;<\/p>\n<figure id=\"attachment_291\" aria-describedby=\"caption-attachment-291\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-291 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/install_wp_wpcli_newskool-600x375.jpg\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-291\" class=\"wp-caption-text\">WordPress is now installed &#8211; WP-CLI for the win!<\/figcaption><\/figure>\n<p>Seriously, how easy and fast was that? You can use WP-CLI to update WordPress core, plugins, themes, copy whole installations and databases, add admin users so you never get locked out, and so much more. But that is for another article&#8230;<\/p>\n<p>We aren&#8217;t finished yet though, remember those permissions?<\/p>\n<h2>Step 7. Configure Root Directory Permissions for WordPress functions<\/h2>\n<p>Log in to your WordPress installation, go to the Plugins menu, and try to delete one of the preinstalled plugins. You should see a pop up box like the following:<\/p>\n<figure id=\"attachment_296\" aria-describedby=\"caption-attachment-296\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-296 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/wp_server_no_permissions-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-296\" class=\"wp-caption-text\">WordPress needs FTP credentials to access the web server<\/figcaption><\/figure>\n<p>You could configure the SFTP account and credentials, that would work, or you could change the ownership of the WordPress root directory to the <span class=\"grey-code\"> www-data<\/span> NGINX server user and usergroup, using the following command:<\/p>\n<pre>$ sudo chown www-data:www-data \/var\/www\/html\/\r\n<\/pre>\n<p>You can check that the <span class=\"grey-code\"> www-data<\/span> user and usergroup has taken ownership with the following command from within the domain root directory:<\/p>\n<pre>$ ls -l\r\n<\/pre>\n<p>You should see the following output:<\/p>\n<figure id=\"attachment_297\" aria-describedby=\"caption-attachment-297\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-297 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/chown_set_server_wp_permissions-600x551.png\" alt=\"\" width=\"600\" height=\"551\" \/><figcaption id=\"caption-attachment-297\" class=\"wp-caption-text\">Set ownership of root directory to server user\/usergroup<\/figcaption><\/figure>\n<p>Now you should be able to install and delete plugins, themes, and uploads:<\/p>\n<figure id=\"attachment_298\" aria-describedby=\"caption-attachment-298\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-298 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/wp_server_has_permissions-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-298\" class=\"wp-caption-text\">Now WordPress has access to the web server<\/figcaption><\/figure>\n<p>There you go, a fully functional WordPress site with&#8230;&#8230; hmmmm well, actually, I suppose it isn&#8217;t quite functional yet is it?<\/p>\n<p>One of the things with cloud hosting, with any provider, is that while you get a fast server you don&#8217;t get things like email functionality provided by the hosting provider.<\/p>\n<h2>BONUS ROUND &#8211; Emails!<\/h2>\n<p>Firstly, for your general email, you should either pay for an email service such GApps, Rackspace, or one of the other providers, or you could roll your own email server.<\/p>\n<h3>Email Server DNS records<\/h3>\n<p>I chose the latter for myself, and have a <a href=\"https:\/\/mailinabox.email\/\" target=\"_blank\" rel=\"noopener\">Mail-In-The-Box<\/a>\u00a0email server running on a Linode. It is quite a simple email server, there are more functional, and complicated, mail server solutions, but in general I direct most of my clients to use a professional hosted service and this is for my personal business use (I&#8217;m in China so the more common email solutions can have serious problems).<\/p>\n<p>To have my emails directed properly I added an <span class=\"grey-code\"> A<\/span> and <span class=\"grey-code\"> MX<\/span> record to the Alibaba DNS settings like so:<\/p>\n<figure id=\"attachment_300\" aria-describedby=\"caption-attachment-300\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-300 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/mx_ecs_dns-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-300\" class=\"wp-caption-text\">Add MX and A (Mail) records for an Email Server<\/figcaption><\/figure>\n<h2>WordPress Transactional Emails<\/h2>\n<p>From a WordPress perspective though, what we really need to sort out, is our transactional emails. We need our WordPress installation to be able to send password reset emails, and the like.<\/p>\n<p>To do that, we could install Dovecot, PostFix etc etc on our server. But that would need maintaining and in my case I already have one email server to look after.<\/p>\n<p>So instead, let&#8217;s use an online hosted SMTP service, of which there are several. I personally use <a href=\"https:\/\/www.mailgun.com\/\" target=\"_blank\" rel=\"noopener\">mailgun<\/a>\u00a0so this tutorial will demonstrate how to set their service up on your new install.<\/p>\n<h3>Create a Mailgun account and add a domain<\/h3>\n<p>If you add a credit card to your account, mailgun has a free tier. On this tier you can send 10,000 emails a month, which is more than enough for anyone&#8217;s need of a free tier. If you are sending more emails than that a month, then you can surely afford to pay!<\/p>\n<p>Create a mailgun account at <a href=\"https:\/\/www.mailgun.com\/\">mailgun.com<\/a>, then\u00a0login and verify your email address.<\/p>\n<p>They have a free tier that doesn&#8217;t require you add a credit card, but is restricted to sending mail to at most 5 whitelisted email addresses. On the other hand, if you do add a credit card you can send up to 10,000 emails a month for free. Can&#8217;t say fairer than that!<\/p>\n<figure id=\"attachment_301\" aria-describedby=\"caption-attachment-301\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-301 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/mailgun_add_domain-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-301\" class=\"wp-caption-text\">Create a mailgun account and add a domain<\/figcaption><\/figure>\n<p>Mailgun needs you to add your domain to their system with a subdomain, they recommend using <span class=\"grey-code\"> mg.an-example-domain.com<\/span>, but I always use <span class=\"grey-code\"> mailgun.an-example-domain.com<\/span>, I prefer to be clear if a little verbose.<\/p>\n<p>Once you have added this domain, they will provide you with some DNS records:<\/p>\n<figure id=\"attachment_302\" aria-describedby=\"caption-attachment-302\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-302 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/mailgun_dns_records-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-302\" class=\"wp-caption-text\">Get the DNS records from your mailgun domain<\/figcaption><\/figure>\n<p>Go to your Alibaba ECS DNS records panel in the console, and add these records:<\/p>\n<figure id=\"attachment_303\" aria-describedby=\"caption-attachment-303\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-303 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/mailgun_ecs_dns-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-303\" class=\"wp-caption-text\">Add those records to your Alibaba Instance DNS records<\/figcaption><\/figure>\n<p>Once your DNS changes have propagated, your mailgun domain settings panel will show your domain as <span class=\"grey-code\"> Active<\/span>, and give you the settings you need to configure one of the many WordPress SMTP plugins:<\/p>\n<figure id=\"attachment_304\" aria-describedby=\"caption-attachment-304\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-304 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/mailgun_domain_active_settings-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-304\" class=\"wp-caption-text\">After DNS record propagation your mailgun domain will be active<\/figcaption><\/figure>\n<p>Go back to your WordPress site, and choose an SMTP plugin. Mailgun has one, but at the moment there is a bug causing TLS connection errors, so instead I recommend <a href=\"https:\/\/wordpress.org\/plugins\/easy-wp-smtp\/\" target=\"_blank\" rel=\"noopener\">Easy WP SMTP<\/a>:<\/p>\n<figure id=\"attachment_305\" aria-describedby=\"caption-attachment-305\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-305 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/easy_wp_smtp_plugin-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-305\" class=\"wp-caption-text\">Easy WP SMTP is an excellent choice for SMTP plugin<\/figcaption><\/figure>\n<p>Upon installation, goto the Easy WP SMTP plugins settings page and enter the credentials given to you on the mailgun domain settings page:<\/p>\n<figure id=\"attachment_306\" aria-describedby=\"caption-attachment-306\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-306 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/easy_wp_smtp_mailgun_settings-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-306\" class=\"wp-caption-text\">Enter your mailgun credentials in the plugin settings<\/figcaption><\/figure>\n<p>You can send a test mail from a test settings panel directly below the main settings:<\/p>\n<figure id=\"attachment_307\" aria-describedby=\"caption-attachment-307\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-307 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/easy_wp_smtp_mailgun_test-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-307\" class=\"wp-caption-text\">Send a test email<\/figcaption><\/figure>\n<p>The plugin will display information from the test send, and whether it was succesful or not. If your settings are correct and everything is set up correctly you should see something like this:<\/p>\n<figure id=\"attachment_308\" aria-describedby=\"caption-attachment-308\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-308 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/easy_wp_smtp_mailgun_test_success-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-308\" class=\"wp-caption-text\">A successful test<\/figcaption><\/figure>\n<p>You can also verify that the email has been sent successfully by checking the logs in your mailgun account:<\/p>\n<figure id=\"attachment_309\" aria-describedby=\"caption-attachment-309\" style=\"width: 600px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" class=\"tutorial-float wp-image-309 size-medium-large-soft-crop\" src=\"https:\/\/learningcurve.xyz\/wp-content\/uploads\/2017\/10\/mailgun_log_send_verified-600x375.png\" alt=\"\" width=\"600\" height=\"375\" \/><figcaption id=\"caption-attachment-309\" class=\"wp-caption-text\">Verify email sending success in the mailgun logs<\/figcaption><\/figure>\n<p><strong><em>Now<\/em><\/strong> we are complete, we have a WordPress site running on a modern, performant LEMP stack, secured with an SSL, and with mailgun transactional emails, all on the Alibaba Cloud!<\/p>\n<p>If you have any questions, or noticed any mistakes or poor configuration practices, please leave a comment.<\/p>\n<p>Thanks<\/p>\n<p>Jeff<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So here we are&#8230; The final part of our series, our Alibaba Ubuntu 16.04 ECS instance is ready, we have NGINX, MariaDB, and PHP7 completing our stack. Our domain is configured and our site is protected with a Let&#8217;s Encrypt SSL certificate. We are all ready to install WordPress, happy days! Completing the previous tutorials [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":176,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[5,4],"tags":[],"_links":{"self":[{"href":"https:\/\/learningcurve.xyz\/index.php?rest_route=\/wp\/v2\/posts\/186"}],"collection":[{"href":"https:\/\/learningcurve.xyz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learningcurve.xyz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learningcurve.xyz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/learningcurve.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=186"}],"version-history":[{"count":3,"href":"https:\/\/learningcurve.xyz\/index.php?rest_route=\/wp\/v2\/posts\/186\/revisions"}],"predecessor-version":[{"id":218,"href":"https:\/\/learningcurve.xyz\/index.php?rest_route=\/wp\/v2\/posts\/186\/revisions\/218"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/learningcurve.xyz\/index.php?rest_route=\/wp\/v2\/media\/176"}],"wp:attachment":[{"href":"https:\/\/learningcurve.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=186"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learningcurve.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=186"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learningcurve.xyz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=186"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}