
{"id":186,"date":"2013-06-11T13:05:44","date_gmt":"2013-06-11T20:05:44","guid":{"rendered":"https:\/\/chrislea.com\/?p=186"},"modified":"2013-06-11T13:05:44","modified_gmt":"2013-06-11T20:05:44","slug":"a-production-quality-wordpress-configuration-tutorial","status":"publish","type":"post","link":"https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/","title":{"rendered":"A Production Quality WordPress Configuration Tutorial"},"content":{"rendered":"<p>The blogging software used to power this site, <a href=\"http:\/\/www.wordpress.org\" title=\"WordPress\" target=\"_blank\">WordPress<\/a>, has just had its 10th anniversary. In the last decade it has become incredibly popular, and currently accounts for about 18% of all websites. Due to my job at (mt) Media Temple, I&#8217;ve gotten to admin <a title=\"TechCrunch\" href=\"http:\/\/www.techcrunch.com\" target=\"_blank\">several<\/a> <a title=\"Mashable\" href=\"http:\/\/www.mashable.com\" target=\"_blank\">popular<\/a> <a title=\"Summer Tomato\" href=\"http:\/\/summertomato.com\" target=\"_blank\">blogs<\/a> at various times over the years, and thus have a pretty good idea of how to optimize everything for good efficiency. In this WordPress configuration tutorial, I&#8217;m going to walk you through the production quality setup that I have for this blog, which makes use of <a title=\"Ubuntu Linux\" href=\"http:\/\/www.ubuntu.com\" target=\"_blank\">Ubuntu Linux<\/a>, <a title=\"Nginx\" href=\"http:\/\/nginx.org\" target=\"_blank\">Nginx<\/a>, <a title=\"PHP\" href=\"http:\/\/www.php.net\" target=\"_blank\">php5-fpm<\/a> and <a title=\"MariaDB\" href=\"https:\/\/mariadb.org\" target=\"_blank\">MariaDB<\/a>.<br \/>\n<!--more--><\/p>\n<hr \/>\n<p><strong>UPDATE:<\/strong> I have recently switched over from using the <a href=\"http:\/\/wordpress.org\/plugins\/wp-super-cache\/\" target=\"_blank\">WP Super Cache<\/a> plugin for caching to the <a href=\"http:\/\/wordpress.org\/plugins\/w3-total-cache\/\" target\"_blank\">W3 Total Cache<\/a> plugin. My reasons are varied. While I don&#8217;t think it provides quite the same level of bare metal performance for page caching that WP Super Cache does, I still think it&#8217;s the better choice right now. It has significant additional options, is trivial to configure, and makes great use of the APC cache features if available. If there&#8217;s sufficient interest I&#8217;ll update this post or make another to talk about it.<\/p>\n<hr \/>\n<p>I&#8217;ll be making several assumptions throughout this article. Specifically:<\/p>\n<ul>\n<li><span style=\"line-height: 14px;\">You are using Ubuntu Lucid (10.04) or a newer supported release.<\/span><\/li>\n<li>You are using a &#8220;naked&#8221; install of Ubuntu (no control panels or anything of that sort).<\/li>\n<li>You have the ability to run all the commands I&#8217;ll list as <code>root<\/code> using <code>sudo<\/code>.<\/li>\n<li>You&#8217;re just going to use the server you&#8217;re using for a WordPress blog, or you have a good enough understanding of user permissions not to create any security risks.<\/li>\n<li>You&#8217;ll be serving up a blog at <code>example.com<\/code>, and you&#8217;ll be running various services with user and group permissions of a user called <code>example<\/code>, which needs to exist on your system.\n<\/ul>\n<h3><span style=\"line-height: 24px;\">Step 1: Install Needed Software<\/span><\/h3>\n<p>There&#8217;s a variety of things you&#8217;ll want to install on your system. For starters, let&#8217;s install Nginx and MariaDB. Nginx is very easy as I have a <a title=\"Chris Lea's Nginx development PPA\" href=\"https:\/\/launchpad.net\/~chris-lea\/+archive\/nginx-devel\" target=\"_blank\">Launchpad PPA<\/a> with all the goodies you&#8217;ll need ready to go. In case you don&#8217;t already have it, install <code>python-software-properties<\/code> with:<\/p>\n<pre lang=\"bash\" line=\"1\">sudo apt-get -y install python-software-properties<\/pre>\n<p>Now, you can add my Nginx PPA and install it:<\/p>\n<pre lang=\"bash\" line=\"1\">sudo add-apt-repository -y ppa:chris-lea\/nginx-devel\nsudo apt-get update\nsudo apt-get -y install nginx-full<\/pre>\n<p>MariaDB is also very easy to install. You&#8217;ll need to import their signing key first with the command:<\/p>\n<pre lang=\"bash\" line=\"1\">sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db<\/pre>\n<p>When you install the server software, you&#8217;re going to have to enter a password for the <code>root<\/code> MariaDB user (which is <strong>NOT<\/strong> to be confused with the system <code>root<\/code> user, though they are used in similar ways here). Looking ahead, let&#8217;s pre-select a strong password with the <code>apg<\/code> password generator.<\/p>\n<pre lang=\"bash\" line=\"1\">sudo apt-get -y install apg\napg -x 10 -m 10<\/pre>\n<p>This will generate a half dozen reasonably strong 10 character passwords to pick from. Choose one and keep it handy. Now, to install MariaDB, use your favorite editor (I&#8217;m assuming it&#8217;s <a href=\"http:\/\/www.gnu.org\/software\/emacs\/\" title=\"Emacs\" target=\"_blank\">Emacs<\/a>, obviously) and create the file:<\/p>\n<pre lang=\"bash\">\/etc\/apt\/sources.list.d\/mariadb.list<\/pre>\n<p>Put the following* into the file:<\/p>\n<pre lang=\"bash\" line=\"1\">deb http:\/\/mirror.jmu.edu\/pub\/mariadb\/repo\/5.5\/ubuntu lucid main\ndeb-src http:\/\/mirror.jmu.edu\/pub\/mariadb\/repo\/5.5\/ubuntu lucid main<\/pre>\n<blockquote><p><strong>*If you are using a distribution different than Ubuntu Lucid (10.04), replace <code>lucid<\/code> in the above two lines with the distro name you have installed.<\/strong><\/p><\/blockquote>\n<p>Now, install MariaDB with the commands:<\/p>\n<pre lang=\"bash\" line=\"1\">sudo apt-get update\nsudo apt-get -y install mariadb-server<\/pre>\n<p>The installer will prompt you for a password for the <code>root<\/code> user, so enter the password you got from the <code>apg<\/code> output earlier. For a pro tip, make a file at <code>~\/.my.cnf<\/code> with the following contents:<\/p>\n<pre lang=\"bash\" escaped=\"true\" line=\"1\">[client]\nuser = root\npassword = &lt;YOURPASSFROMAPG&gt;<\/pre>\n<p>and change the permissions so only you can read it:<\/p>\n<pre lang=\"bash\">chmod 600 ~\/.my.cnf<\/pre>\n<p>Now you won&#8217;t have to enter the username and password when you type <code>mysql<\/code> to use the MariaDB client.<\/p>\n<p>The last thing to install is the needed PHP software. If you are running Ubuntu Lucid, use the following command to add a PHP5 PPA maintained by Ond\u0159ej Sur\u00fd:<\/p>\n<pre lang=\"bash\" line=\"1\">sudo add-apt-repository -y ppa:ondrej\/php5<\/pre>\n<p>If you are using a release newer than Lucid you won&#8217;t need to do that step. Next, install all the PHP things we&#8217;ll need with:<\/p>\n<pre lang=\"bash\" line=\"1\">sudo apt-get update\nsudo apt-get -y install php-apc php-geshi php-pear php5 php5-cli \\\nphp5-common php5-curl php5-fpm php5-gd php5-imagick php5-mysqlnd \\\nphp5-pspell<\/pre>\n<h3><span style=\"line-height: 24px;\">Step 2: Configuring the Software<\/span><\/h3>\n<p>We&#8217;ll need to configure the things we&#8217;ve just installed for optimal performance. Let&#8217;s start with the database. Configuring a database correctly is a career level amount of knowledge these days, so there&#8217;s nothing I can really tell you in a post like this that will cover every case. But there are a few things we can do to the default setup that will generally always help in this particular WordPress case.<\/p>\n<p>First, open up the file<\/p>\n<pre lang=\"bash\">\/etc\/mysql\/my.cnf<\/pre>\n<p>in your text editor. Look for a line that reads:<\/p>\n<pre lang=\"bash\" line=\"1\">tmpdir          = \/tmp<\/pre>\n<p>and add the following three lines underneath it:<\/p>\n<pre lang=\"bash\" line=\"2\">skip-external-locking\nskip-name-resolve\ncharacter-set-server = utf8<\/pre>\n<p>These make sure that the default character set is UTF-8, that the server doesn&#8217;t try and do DNS based hostname lookups (which it shouldn&#8217;t need to do here) and that external locking isn&#8217;t enabled. Note that with locking disabled, you&#8217;ll need to make sure to shutdown the server if you ever need to run <code>myisamchk<\/code> to repair something.<\/p>\n<p>Next, you will probably want to increase the default value for the <code>key_buffer<\/code>. What you use depends on how much free memory you have on your system, but increasing it from the default 16M value is a good idea if you can. This site currently uses the setting:<\/p>\n<pre lang=\"bash\">key_buffer              = 128M<\/pre>\n<p>Finally, you may want to change the default value for the database query cache. Look for the line that reads:<\/p>\n<pre lang=\"bash\">query_cache_size        = 16M<\/pre>\n<p>The default of 16M is probably fine for most blogs. If you get a lot of traffic you may wish to raise this value, but never raise it to more than 512M as it starts doing more harm than good at that point. Even for a blog with a lot of traffic, 128M or 256M is generally plenty. Restart the server to pick up these changes with<\/p>\n<pre lang=\"bash\" line=\"1\">sudo \/etc\/init.d\/mysql restart<\/pre>\n<p>Of course, you&#8217;ll want to create a database for your blog. I&#8217;ll assume it&#8217;s called <code>example_com_wordpress<\/code>. You&#8217;ll want to generate another password as we did before that&#8217;s specific to this database. Do <strong>NOT<\/strong> use the same password as you have for the <code>root<\/code> user. Once you have this, enter the MariaDB command prompt by simply typing<\/p>\n<pre lang=\"bash\">mysql<\/pre>\n<p>at the command line. Then, use the following commands to create your database and get it ready for use (note how we&#8217;re at the MariaDB prompt):<\/p>\n<pre lang=\"bash\">MariaDB [(none)]> CREATE DATABASE example_com_wordpress;\nQuery OK, 1 row affected (0.00 sec)\n\nMariaDB [(none)]> GRANT ALL PRIVILEGES ON example_com_wordpress.* TO `example`@`localhost` IDENTIFIED BY 'NEWPASSFROMAPG';\nQuery OK, 0 rows affected (0.04 sec)\n\nMariaDB [(none)]> FLUSH PRIVILEGES;\nQuery OK, 0 rows affected (0.04 sec)<\/pre>\n<p>Then just type <code>exit<\/code> to get out of MariaDB, and your database is ready to go.<\/p>\n<p>Next, let&#8217;s configure <code>php5-fpm<\/code>. Open up the file at<\/p>\n<pre lang=\"bash\">\/etc\/php5\/fpm\/pool.d\/www.conf<\/pre>\n<p>and look for the <code>user<\/code> and <code>group<\/code> directives. Change these so that PHP runs as your <code>example<\/code> user like this:<\/p>\n<pre lang=\"bash\">user = example\ngroup = example<\/pre>\n<p>Then, look for the <code>listen<\/code> directive and change it to read:<\/p>\n<pre lang=\"bash\">listen = \/var\/run\/php5-fpm.sock<\/pre>\n<p>so that Nginx can communicate to PHP via a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Unix_socket\" title=\"Unix Domain Sockets\" target=\"_blank\">Unix domain socket<\/a> and thus bypass the TCP stack which isn&#8217;t needed. Finally, there are some directives for the process manager that could use some changes. The ideal configuration depends on your traffic and hardware, but this site is currently using:<\/p>\n<pre lang=\"bash\">pm = dynamic\npm.max_children = 40\npm.start_servers = 4\npm.min_spare_servers = 4\npm.max_spare_servers = 5\npm.max_requests = 500<\/pre>\n<p>and that should be a good starting point for most blogs.<\/p>\n<p>Lastly for PHP, you should make one quick edit to the file:<\/p>\n<pre lang=\"bash\">\/etc\/php5\/fpm\/php.ini<\/pre>\n<p>where you&#8217;ll want to make sure the following is set:<\/p>\n<pre lang=\"bash\">cgi.fix_pathinfo = 1<\/pre>\n<p>You should now be able to fire up your PHP processes with the command:<\/p>\n<pre lang=\"bash\">sudo \/etc\/init.d\/php5-fpm start<\/pre>\n<p>The last, and most involved thing you&#8217;ll need to configure is Nginx. To begin, we&#8217;ll also want to run it as our <code>example<\/code> user. Open up the file:<\/p>\n<pre lang=\"bash\">\/etc\/nginx\/nginx.conf<\/pre>\n<p>and set the <code>user<\/code> directive to<\/p>\n<pre lang=\"bash\">user example;<\/pre>\n<p>Generally speaking, you want to have as many worker processes as you do physical CPU cores. If you&#8217;re unsure how many cores you have, the command<\/p>\n<pre lang=\"bash\">grep -c 'processor' \/proc\/cpuinfo<\/pre>\n<p>will tell you. So, if you have a four core machine, set<\/p>\n<pre lang=\"bash\">worker_processes 4;<\/pre>\n<p>Next, we&#8217;ll do a virtual host configuration for our <code>example.com<\/code> site. If you&#8217;re going to run a production WordPress site, it&#8217;s generally recommended to use some sort of caching plugin if you expect any real traffic. Our configuration is going to be tailored to take advantage of the <a href=\"http:\/\/wordpress.org s.org\/plugins\/wp-super-cache\/\" title=\"WP Super Cache\" target=\"_blank\">WP Super Cache<\/a> plugin, which works very well and is written by one of the key WordPress engineers.<\/p>\n<p>Create a new file called <code>example.com<\/code> here:<\/p>\n<pre lang=\"bash\">\/etc\/nginx\/sites-available\/example.com<\/pre>\n<p>To begin with, let&#8217;s define an Nginx <code>upstream<\/code> for PHP listening to the Unix socket we specified earlier. Put the following into the beginning of our <code>example.com<\/code> config file:<\/p>\n<pre lang=\"nginx\" line=\"1\"># Upstream to abstract backend connection(s) for php\nupstream php {\n    server unix:\/var\/run\/php5-fpm.sock;\n}\n<\/pre>\n<p>After that comes some fairly straightforward Nginx directives to tell it what port to listen to, what the server name is, where to log, and so on:<\/p>\n<pre lang=\"nginx\" line=\"5\">server {\n    listen 80;\n    server_name example.com;\n\n    access_log \/var\/log\/nginx\/example.com-access.log;\n    error_log \/var\/log\/nginx\/example.com-error.log;\n\n    add_header X-Frame-Options DENY;\n\n    root \/var\/www\/example.com;\n    index index.php index.html;\n<\/pre>\n<p>The only thing of possible note here is the <code>add_header<\/code> directive at line 12, which should keep your site from being embedded in a &lt;frame&gt; or &lt;iframe&gt; anywhere. If for some reason you want that to be possible, remove that line. After this, we have some <code>rewrite<\/code> directives to make the generated sitemap work correctly:<\/p>\n<pre lang=\"nginx\" line=\"17\">    rewrite ^\/sitemap_index\\.xml$ \/index.php?sitemap=1 last;\n    rewrite ^\/([^\/]+?)-sitemap([0-9]+)?\\.xml$ \/index.php?sitemap=$1&sitemap_n=$2 last;\n<\/pre>\n<p>and then some specific <code>location<\/code> directives for the favicon, robots.txt file, and to keep people out of some common directories and files that shouldn&#8217;t be public:<\/p>\n<pre lang=\"nginx\" line=\"20\">    location = \/favicon.ico {\n        log_not_found off;\n        access_log off;\n    }\n\n    location = \/robots.txt {\n        allow all;\n        log_not_found off;\n        access_log off;\n    }\n\n    location ~ \/\\.svn|\/\\.ht|\/\\.git {\n        deny all;\n    }\n<\/pre>\n<p>Now on to the good part, where we set Nginx up to use WP Super Cache. It&#8217;s easier to explain how this works if you can already see the configuration, so here it is, and we&#8217;ll go over it next:<\/p>\n<pre lang=\"nginx\" line=\"35\">    location \/ {\n        # This is cool because no php is touched for static content.\n        # include the \"?$args\" part so non-default permalinks doesn't break when using query string\n        try_files $uri\n                  $uri\/\n                  \/index.php?$args;\n\n        gzip on;\n        gzip_static on;\n        gzip_disable \"MSIE [1-6]\\.\";\n        default_type text\/html;\n        gzip_types text\/plain text\/css application\/x-javascript text\/xml application\/xml application\/xml+rss text\/javascript;\n\n        if (-f $request_filename) {\n            break;\n        }\n\n        set $supercache_file '';\n        set $supercache_uri $request_uri;\n\n        if ($request_method = POST) {\n            set $supercache_uri '';\n        }\n\n        if ($query_string) {\n            set $supercache_uri '';\n        }\n\n        if ($supercache_uri ~ ^(.+)$) {\n            set $supercache_file \/wp-content\/cache\/supercache\/$http_host$1index-http.html;\n        }\n\n        if (-f $document_root$supercache_file) {\n            rewrite ^ $supercache_file break;\n        }\n\n        if (!-e $request_filename) {\n            rewrite ^ \/index.php last;\n        }\n\n    }\n<\/pre>\n<p>Lines 35 to 46 are fairly obvious. They tell Nginx where to look for an index file with the <code>try_files<\/code> directive and set up gzip compression. The <code>gzip_static<\/code> directive is somewhat interesting. It tells Nginx that if it sees a file that is supposed to be gzipped, it should look for a file in the same directory with the same name that ends in &#8220;.gz&#8221;, and if it&#8217;s there, to serve that directly. Doing this keeps the server from having to compress the file every time it is served.<\/p>\n<p>The really interesting part, however, starts on line 48. This is where we get Nginx to play nicely with WP Super Cache. First, if the request corresponds to an actual file on the filesystem, we tell Nginx to just serve it and move on. Next we set some variables we&#8217;ll need. If the request type is a POST, or if there&#8217;s any sort of query string, we disable caching by setting <code>$supercache_uri<\/code> to be blank. If we&#8217;ve made it this far and that variable isn&#8217;t blank, then we look for a deterministically named file at<\/p>\n<pre lang=\"bash\">\/wp-content\/cache\/supercache\/<the domain name>\/<the request uri>\/index-http.html<\/pre>\n<p>For example, if you had a standard &#8220;About&#8221; page located at <code>http:\/\/example.com\/about\/<\/code>, Nginx would look for the file<\/p>\n<pre lang=\"bash\">\/wp-content\/cache\/supercache\/example.com\/about\/index-http.html<\/pre>\n<p>This exactly corresponds to how WP Super Cache writes out its &#8220;supercached&#8221; files to the filesystem. The beauty of this setup is that if a cached file exists, Nginx will serve it without ever having to talk to PHP whatsoever. This is great, because Nginx is amazingly good at serving up static content such as these cached files, and it keeps PHP from having to do work unless it actually needs to. If there&#8217;s any legitimate &#8220;secret sauce&#8221; in this configuration recipe, this is it.<\/p>\n<p>The last stanzas we need tell Nginx how to talk to PHP using FastCGI, and then just sets some expire headers for our static content types:<\/p>\n<pre lang=\"nginx\" line=\"77\">    location ~ \\.php$ {\n        #NOTE: You should have \"cgi.fix_pathinfo = 0;\" in php.ini\n        include fastcgi_params;\n        fastcgi_index index.php;\n        fastcgi_intercept_errors on;\n        fastcgi_pass php;\n    }\n\n    location ~* \\.(?:js|css|png|jpe?g|gif|ico|html|txt)$ {\n        expires 7d;\n        log_not_found off;\n    }\n}\n<\/pre>\n<p>We are now ready to turn Nginx on. We&#8217;ll need to remove the default configuration that Nginx ships with, symlink our configuration into the <code>sites-enabled<\/code> directory, and then fire it up.<\/p>\n<pre lang=\"bash\">\ncd \/etc\/nginx\/sites-enabled\nsudo rm -fv default\nsudo ln -s ..\/sites-available\/example.com .\nsudo \/etc\/init.d\/nginx start\n<\/pre>\n<p>If that all works, we&#8217;re on to the third and final stretch.<\/p>\n<h3>Step 3: Installing and Setting Up WordPress<\/h3>\n<p>This is a tutorial about server configuration, so I&#8217;m going to assume that you can handle the basics of <a href=\"http:\/\/codex.wordpress.org\/Installing_WordPress#Famous_5-Minute_Install\" title=\"Famous WordPress 5 Minute Install\" target=\"_blank\">getting and installing WordPress<\/a> itself. You&#8217;ll want to put everything in the directory <code>\/var\/www\/example.com<\/code>, which you&#8217;ll need to create and set to be owned by our <code>example<\/code> user:<\/p>\n<pre lang=\"bash\">cd \/var\/www\nsudo mkdir example.com\nsudo chown -R example:example example.com\n<\/pre>\n<p>Be sure when you put the WordPress files in there, you&#8217;re installing them as the <code>example<\/code> user. Edit the <code>wp-config.php<\/code> file to use our <code>example_com_wordpress<\/code> database with the credentials we set up earlier. Also, be <strong>sure<\/strong> to set up random values for the unique keys and salts. Automattic has <a href=\"https:\/\/api.wordpress.org\/secret-key\/1.1\/salt\/\" target=\"_blank\">handy endpoint<\/a> to help you do this.<\/p>\n<p>Once you have WordPress up and running, there&#8217;s just a few more steps before you&#8217;re ready to start your blogging empire. First, set up pretty permalinks for your blog. In the WordPress admin, just go to Settings->Permalinks, choose the &#8220;custom&#8221; option, and put the following in for the link structure:<\/p>\n<pre lang=\"bash\">\/%year%\/%monthnum%\/%day%\/%postname%\/<\/pre>\n<p>This will give you the standard date-centric link structure that many popular blogs have.<\/p>\n<p>The final step is to set up WP Super Cache. Go to Plugins->Add New and search for &#8220;WP Super Cache&#8221;. Since PHP is running as the same user who owns the WordPress files and directory, it can install the plugin for you (it can also easily upgrade WordPress for you, as an added bonus). You&#8217;ll then need to configure it. Navigate to the settings page for the plugin, and click on the Advanced tab. Check the box to &#8220;Cache hits to this website for quick access&#8221;, then click the radio button for &#8220;Use mod_rewrite to serve cache files&#8221;. You should <strong>ignore<\/strong> the warnings at the top of the page that complain about <code>mod_rewrite<\/code> not being installed. The plugin assumes you&#8217;re using Apache to serve the site, but you&#8217;re not, so this warning is superfluous. Finally, scroll down and click the &#8220;Update Status&#8221; button to save your changes.<\/p>\n<p>After this, log out of the admin, navigate to your home page, and reload it a few times. If you view the page source, down near the bottom, you should see some comments that indicate the page is a cached page. If so, congratulations, you&#8217;re all done!<\/p>\n<h3>In Conclusion<\/h3>\n<p>This is a setup I&#8217;ve refined over several years, starting from when keeping Techcrunch up and running was part of my job description. It&#8217;s worked well for me for a lot of WordPress sites (including this one), so I hope you find it useful. If there are questions or issues, please just let me know in the comments.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The blogging software used to power this site, WordPress, has just had its 10th anniversary. In the last decade it has become incredibly popular, and currently accounts for about 18% of all websites. Due to my job at (mt) Media Temple, I&#8217;ve gotten to admin several popular blogs at various times over the years, and<\/p>\n<div class=\"read-more\"><a href=\"https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/\" title=\"Read More\">Keep Reading<i class=\"icon icon-angle-right\"><\/i><\/a><\/div>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[6,7,9,4],"tags":[12,15,16,17,23,25,27],"class_list":{"0":"post-186","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-linux","7":"category-nginx","8":"category-sysadmin","9":"category-technology","10":"tag-configuration","11":"tag-linux","12":"tag-mariadb","13":"tag-nginx","14":"tag-sysadmin","15":"tag-ubuntu","16":"tag-wordpress"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>A Production Quality WordPress Configuration Tutorial - Chris Lea<\/title>\n<meta name=\"description\" content=\"A complete, production quality WordPress configuration tutorial using Ubuntu Linux, php5-fpm, Nginx and MariaDB.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"A Production Quality WordPress Configuration Tutorial - Chris Lea\" \/>\n<meta name=\"twitter:description\" content=\"A complete, production quality WordPress configuration tutorial using Ubuntu Linux, php5-fpm, Nginx and MariaDB.\" \/>\n<meta name=\"twitter:creator\" content=\"@chrislea\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"chris lea\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/chrislea.com\\\/2013\\\/06\\\/11\\\/a-production-quality-wordpress-configuration-tutorial\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/chrislea.com\\\/2013\\\/06\\\/11\\\/a-production-quality-wordpress-configuration-tutorial\\\/\"},\"author\":{\"name\":\"chris lea\",\"@id\":\"https:\\\/\\\/chrislea.com\\\/#\\\/schema\\\/person\\\/320ffc132f82aa79d47e7d1d7e149cf2\"},\"headline\":\"A Production Quality WordPress Configuration Tutorial\",\"datePublished\":\"2013-06-11T20:05:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/chrislea.com\\\/2013\\\/06\\\/11\\\/a-production-quality-wordpress-configuration-tutorial\\\/\"},\"wordCount\":2293,\"commentCount\":22,\"keywords\":[\"configuration\",\"linux\",\"mariadb\",\"nginx\",\"sysadmin\",\"ubuntu\",\"wordpress\"],\"articleSection\":[\"linux\",\"nginx\",\"sysadmin\",\"technology\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/chrislea.com\\\/2013\\\/06\\\/11\\\/a-production-quality-wordpress-configuration-tutorial\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/chrislea.com\\\/2013\\\/06\\\/11\\\/a-production-quality-wordpress-configuration-tutorial\\\/\",\"url\":\"https:\\\/\\\/chrislea.com\\\/2013\\\/06\\\/11\\\/a-production-quality-wordpress-configuration-tutorial\\\/\",\"name\":\"A Production Quality WordPress Configuration Tutorial - Chris Lea\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/chrislea.com\\\/#website\"},\"datePublished\":\"2013-06-11T20:05:44+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/chrislea.com\\\/#\\\/schema\\\/person\\\/320ffc132f82aa79d47e7d1d7e149cf2\"},\"description\":\"A complete, production quality WordPress configuration tutorial using Ubuntu Linux, php5-fpm, Nginx and MariaDB.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/chrislea.com\\\/2013\\\/06\\\/11\\\/a-production-quality-wordpress-configuration-tutorial\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/chrislea.com\\\/2013\\\/06\\\/11\\\/a-production-quality-wordpress-configuration-tutorial\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/chrislea.com\\\/2013\\\/06\\\/11\\\/a-production-quality-wordpress-configuration-tutorial\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/chrislea.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A Production Quality WordPress Configuration Tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/chrislea.com\\\/#website\",\"url\":\"https:\\\/\\\/chrislea.com\\\/\",\"name\":\"Chris Lea\",\"description\":\"With the mochas he was strong.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/chrislea.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/chrislea.com\\\/#\\\/schema\\\/person\\\/320ffc132f82aa79d47e7d1d7e149cf2\",\"name\":\"chris lea\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d35b2d5c2d0a0509b317bc6cce928be6812761d2eb81cfcb736169fd262bf491?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d35b2d5c2d0a0509b317bc6cce928be6812761d2eb81cfcb736169fd262bf491?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/d35b2d5c2d0a0509b317bc6cce928be6812761d2eb81cfcb736169fd262bf491?s=96&d=mm&r=g\",\"caption\":\"chris lea\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/chrislea\",\"https:\\\/\\\/x.com\\\/chrislea\"],\"url\":\"https:\\\/\\\/chrislea.com\\\/author\\\/chl\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"A Production Quality WordPress Configuration Tutorial - Chris Lea","description":"A complete, production quality WordPress configuration tutorial using Ubuntu Linux, php5-fpm, Nginx and MariaDB.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/","twitter_card":"summary_large_image","twitter_title":"A Production Quality WordPress Configuration Tutorial - Chris Lea","twitter_description":"A complete, production quality WordPress configuration tutorial using Ubuntu Linux, php5-fpm, Nginx and MariaDB.","twitter_creator":"@chrislea","twitter_misc":{"Written by":"chris lea","Est. reading time":"14 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/#article","isPartOf":{"@id":"https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/"},"author":{"name":"chris lea","@id":"https:\/\/chrislea.com\/#\/schema\/person\/320ffc132f82aa79d47e7d1d7e149cf2"},"headline":"A Production Quality WordPress Configuration Tutorial","datePublished":"2013-06-11T20:05:44+00:00","mainEntityOfPage":{"@id":"https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/"},"wordCount":2293,"commentCount":22,"keywords":["configuration","linux","mariadb","nginx","sysadmin","ubuntu","wordpress"],"articleSection":["linux","nginx","sysadmin","technology"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/","url":"https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/","name":"A Production Quality WordPress Configuration Tutorial - Chris Lea","isPartOf":{"@id":"https:\/\/chrislea.com\/#website"},"datePublished":"2013-06-11T20:05:44+00:00","author":{"@id":"https:\/\/chrislea.com\/#\/schema\/person\/320ffc132f82aa79d47e7d1d7e149cf2"},"description":"A complete, production quality WordPress configuration tutorial using Ubuntu Linux, php5-fpm, Nginx and MariaDB.","breadcrumb":{"@id":"https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/chrislea.com\/2013\/06\/11\/a-production-quality-wordpress-configuration-tutorial\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/chrislea.com\/"},{"@type":"ListItem","position":2,"name":"A Production Quality WordPress Configuration Tutorial"}]},{"@type":"WebSite","@id":"https:\/\/chrislea.com\/#website","url":"https:\/\/chrislea.com\/","name":"Chris Lea","description":"With the mochas he was strong.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/chrislea.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/chrislea.com\/#\/schema\/person\/320ffc132f82aa79d47e7d1d7e149cf2","name":"chris lea","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/d35b2d5c2d0a0509b317bc6cce928be6812761d2eb81cfcb736169fd262bf491?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/d35b2d5c2d0a0509b317bc6cce928be6812761d2eb81cfcb736169fd262bf491?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d35b2d5c2d0a0509b317bc6cce928be6812761d2eb81cfcb736169fd262bf491?s=96&d=mm&r=g","caption":"chris lea"},"sameAs":["https:\/\/www.facebook.com\/chrislea","https:\/\/x.com\/chrislea"],"url":"https:\/\/chrislea.com\/author\/chl\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p88PCy-30","jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/chrislea.com\/wp-json\/wp\/v2\/posts\/186","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chrislea.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/chrislea.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/chrislea.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/chrislea.com\/wp-json\/wp\/v2\/comments?post=186"}],"version-history":[{"count":0,"href":"https:\/\/chrislea.com\/wp-json\/wp\/v2\/posts\/186\/revisions"}],"wp:attachment":[{"href":"https:\/\/chrislea.com\/wp-json\/wp\/v2\/media?parent=186"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/chrislea.com\/wp-json\/wp\/v2\/categories?post=186"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chrislea.com\/wp-json\/wp\/v2\/tags?post=186"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}