{"id":1848,"date":"2017-01-08T17:38:05","date_gmt":"2017-01-08T22:38:05","guid":{"rendered":"http:\/\/www.phpied.com\/?p=1848"},"modified":"2017-01-08T17:45:00","modified_gmt":"2017-01-08T22:45:00","slug":"https-migration-wordpress-blog-dreamhost","status":"publish","type":"post","link":"https:\/\/www.phpied.com\/https-migration-wordpress-blog-dreamhost\/","title":{"rendered":"HTTPS migration: a WordPress blog hosted on Dreamhost"},"content":{"rendered":"<p>I use Dreamhost. Have been since 2008. If you're not using Dreamhost... well, go sign up and <a href=\"https:\/\/www.dreamhost.com\/r.cgi?447675\/promo\/dreamsavings50\">here's $50 off of the $97 yearly plan<\/a>.<\/p>\n<p>Now <a href=\"https:\/\/twitter.com\/yoavweiss\">some folks<\/a> reminded me recently that <a href=\"https:\/\/calendar.perfplanet.com\/\">the Perf calendar<\/a> was not yet migrated to HTTPS... True enough. I have to do it. Eventually. In any normal situation I'll procrastinate indefinitely, but since I had more pressing things to do and \"Anyone can do any amount of work, provided it isn\u00e2\u20ac\u2122t the work he is supposed to be doing at that moment\"... I bit the bullet.<\/p>\n<p>Below are the steps that worked for me with a WordPress blog, hosted on DreamHost. The steps are still relevant to any WordPress site, just using Dreamhost as an example and since Dreamhost makes many of the steps easy. Also note that Dreamhost offers automated install of WordPress (\"one-click installs\") and something called Dreampress. My case wasn't any of those, just a plain old self-install. So some of the steps might be different if you use any of those services.<\/p>\n<h2>Steps<\/h2>\n<ol>\n<li>Setup free SSL certificate thanks to <a href=\"https:\/\/letsencrypt.org\">Let's Encrypt<\/a><\/li>\n<li>Backup all the things (or just the blog's database or just the table with the posts)<\/li>\n<li>Search and replace internal references (images and links)<\/li>\n<li>WP settings<\/li>\n<li>Redirect http to https permanently in <code>.htaccess<\/code><\/li>\n<li>Test\/tweak?<\/li>\n<\/ol>\n<h2>SSL certificate<\/h2>\n<p>Thanks to <a href=\"https:\/\/letsencrypt.org\">Let's Encrypt<\/a> you can have a free certificate. Dreamhost makes it trivial to use.<\/p>\n<p>Under <a href=\"https:\/\/panel.dreamhost.com\/index.cgi?tree=domain.secure&\">Domains\/Secure Hosting<\/a> you go add a new Let's Encrypt cert:<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/lets.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/lets-1024x658.png\" alt=\"lets\" width=\"650\" \/><\/a><\/p>\n<p>Then pick a domain.<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/lets2.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/lets2-1024x563.png\" alt=\"lets2\" width=\"650\" \/><\/a><\/p>\n<p>Done!<\/p>\n<p>Give it a coupla minutes (while you're doing backups, next step), then go visit your site with <code>https:\/\/<\/code> in front.<\/p>\n<h2>Backup<\/h2>\n<p>One of the least favorite parts when it comes to anything computer-y...<\/p>\n<h3>Backup everything (optional)<\/h3>\n<p>Dreamhost lets you backup all your things - mail and databases and files and everything. You should probably do that at one point or another but it's not required here.<\/p>\n<p>You'll find <a href=\"https:\/\/panel.dreamhost.com\/index.cgi?tree=billing.backup&\">the option under Billing and Account<\/a><\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/bu.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/bu-1024x680.png\" alt=\"bu\" width=\"650\" \/><\/a><\/p>\n<h3>Backup the database (optional)<\/h3>\n<p>Backing up your whole WP DB is a good practice, not required for the HTTPS migration but it won't hurt. Let's see how.<\/p>\n<p>You need phpMyAdmin. You'll find <a href=\"https:\/\/panel.dreamhost.com\/index.cgi?tree=goodies.mysql&\">\"MySQL databases\" under \"Goodies\"<\/a><\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/phpmyadmin-1.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/phpmyadmin-1-1024x662.png\" alt=\"phpmyadmin\" width=\"650\" \/><\/a><\/p>\n<p>Click \"phpMyAdmin\" next to the database you need.<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/phpmyadmin-login.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/phpmyadmin-login-1024x823.png\" alt=\"phpmyadmin-login\" width=\"650\" \/><\/a><\/p>\n<p>Drag, what is this password? Well, go to your <code>wp-config.php<\/code> file and copy from there.<\/p>\n<p>After you login, go to the Export tab in phpMyAdmin and ... export!<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/export-db.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/export-db-1024x846.png\" alt=\"export-db\" width=\"650\" \/><\/a><\/p>\n<p>No need to touch any of the defaults. Keep the generated file handy in case all hell breaks lose.<\/p>\n<h3>Backup the posts<\/h3>\n<p>This is the required step so that you can then replace all internal references to http content.<\/p>\n<p>Find the table that ends with <code>posts<\/code> (in case you're like me and have added weird prefix to all tables) on the left menu. Click. Go to Export tab. Click. Click \"Go\" button.<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/export-posts.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/export-posts-1024x590.png\" alt=\"export-posts\" width=\"650\" \/><\/a><\/p>\n<p>Save the file.<\/p>\n<h2>Replace internal references<\/h2>\n<p>All <code>&lt;img src=\"http:\/\/yourdomain<\/code> and <code>&lt;a href=\"http:\/\/yourdomain<\/code> need to turn into https. Actually links are optional (if you do the next steps with permanent redirect), but why not? Images are not optional, otherwise loading images over HTTP when the page is HTTPS triggers \"mixed content\" warning.<\/p>\n<p>Open the <code>*posts.sql<\/code> file you downloaded in the previous step in a regular text editor. I just did a search\/replace of \"http:\/\/calendar.perfplanet.com\" with \"https:\/\/calendar.perfplanet.com\". It's possible I've replaced more than <code>img src<\/code> and <code>a href<\/code>. But that's ok as far as I know. If you want to be more surgical in replacements... knock yourself out.<\/p>\n<p>Save this file with the http-to-https replaced.<\/p>\n<p>Go back to phpMyAdmin and click the Operations tab (while still working with the \"posts\" table). You'll see an option to rename the table. Do it. Add \"_backup\" or something at the end.<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/rename.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/rename-1024x502.png\" alt=\"rename\" width=\"650\" \/><\/a><\/p>\n<p>At this point your blog is broken, as there is no table to read the posts from. So not the best time to walk the dog or take a vacation.<\/p>\n<p>Go back to the database level (as opposed to individual table). Click Import tab.<\/p>\n<p>Select your <code>*posts.sql<\/code> file for upload, leave all defaults. Click \"Go\" button.<\/p>\n<p>Your blog is now back up.<\/p>\n<p>Not the best time to walk the dog yet, but not the worst either.<\/p>\n<h2>WordPress settings<\/h2>\n<p>Login to your WordPress admin area. Go to Settings\/General. Change URL stuff to https.<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/wp-settings-1.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/wp-settings-1-1024x589.png\" alt=\"wp-settings\" width=\"650\" \/><\/a><\/p>\n<h2>Redirect to https<\/h2>\n<p>Open your <code>.htaccess<\/code> file. It probably has an area that looks something like:<\/p>\n<pre>\r\n# BEGIN WordPress\r\n&lt;IfModule mod_rewrite.c&gt;\r\nRewriteEngine On\r\nRewriteBase \/\r\nRewriteRule ^index.php$ - [L]\r\nRewriteCond %{REQUEST_FILENAME} !-f\r\nRewriteCond %{REQUEST_FILENAME} !-d\r\nRewriteRule . \/index.php [L]\r\n&lt;\/IfModule&gt;\r\n# END WordPress\r\n<\/pre>\n<p>Now above this section, add another section:<\/p>\n<pre>\r\n# BEGIN HTTPS redirect\r\n&lt;IfModule mod_rewrite.c&gt;\r\nRewriteEngine On\r\nRewriteCond %{HTTPS} !=on\r\nRewriteRule ^(.*) https:\/\/%{HTTP_HOST}\/$1 [R=301,L]\r\n&lt;\/IfModule&gt;\r\n# END redirect\r\n<\/pre>\n<h2>Test\/tweak?<\/h2>\n<p>Now everything should be working. Go to your site (with http). It should redirect to https. And you should see some congratulatory green in the address bar.<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/green0.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/green0.png\" alt=\"green0\" width=\"650\" \/><\/a><\/p>\n<p>And more:<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/green2.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/green2.png\" alt=\"green2\" width=\"650\" \/><\/a> <\/p>\n<p>But what if it's not green? You may have the dreaded \"Mixed content\". I know I did.<\/p>\n<p>In Chrome. Expected picture:<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/chrome-green.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/chrome-green.png\" alt=\"chrome-green\" width=\"650\" \/><\/a><\/p>\n<p>Actual picture - an <code>i<\/code> icon. Whaa! Click it.<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/not-green.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/not-green.png\" alt=\"not-green\" width=\"650\" \/><\/a><\/p>\n<p>Click Details. Chrome tells you what's wrong.<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/why-not-green.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/why-not-green.png\" alt=\"why-not-green\" width=\"650\" \/><\/a><\/p>\n<p>Click \"View requests in Network Panel\". Figure out what's wrong.<\/p>\n<p>In my case I had gravatars enabled. And a default image over http if there's no gravatar for the person commenting (in a call to <code>get_avatar()<\/code>). Updating this in the <code>comments.php<\/code> of my theme fixed it.<\/p>\n<p><a href=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/avatar.png\"><img decoding=\"async\" src=\"https:\/\/www.phpied.com\/wp-content\/uploads\/2017\/01\/avatar-1024x428.png\" alt=\"avatar\" width=\"650\" \/><\/a><\/p>\n<h2>Happy HTTPS-ing!<\/h2>\n<p>And thanks for reading!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I use Dreamhost. Have been since 2008. If you&#8217;re not using Dreamhost&#8230; well, go sign up and here&#8217;s $50 off of the $97 yearly plan. Now some folks reminded me recently that the Perf calendar was not yet migrated to HTTPS&#8230; True enough. I have to do it. Eventually. In any normal situation I&#8217;ll procrastinate [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[49,4],"tags":[],"_links":{"self":[{"href":"https:\/\/www.phpied.com\/wp-json\/wp\/v2\/posts\/1848"}],"collection":[{"href":"https:\/\/www.phpied.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.phpied.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.phpied.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.phpied.com\/wp-json\/wp\/v2\/comments?post=1848"}],"version-history":[{"count":0,"href":"https:\/\/www.phpied.com\/wp-json\/wp\/v2\/posts\/1848\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.phpied.com\/wp-json\/wp\/v2\/media?parent=1848"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.phpied.com\/wp-json\/wp\/v2\/categories?post=1848"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.phpied.com\/wp-json\/wp\/v2\/tags?post=1848"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}