loading...
Cover image for Complete Guide To Hosting Wordpress On Heroku With SSL Certification

Complete Guide To Hosting Wordpress On Heroku With SSL Certification

aryaziai profile image aryaziai Updated on ・7 min read

I recently moved all of my self-hosted Wordpress websites to Heroku and I'm now spending $0 a month, happily saving over $300 a year in hosting and SSL Certificate fees! I thought it'd be useful to share this guide that I put together with anyone who manages a self-hosted Wordpress site and is looking to cut down on expenses. A special shoutout to Philipp Heuer for making this all possible.

Disclaimer: You are limited to a 5MB database, which is more than enough for most people unless you plan on having over 1,000 posts and/or plugins that generate new rows anytime that you publish a new post (not common). For anyone who may not know this: images, code, etc. are not stored in the database, they are simply referenced. I'll share a tool you should use to manage your database size later in this guide. You will also not be able to update the Wordpress version or add new plugins/themes from the WP Admin Dashboard. You're required to update the Wordpress version number in our Composer.json file, and manually add themes/plugins into our local Wordpress repo before pushing to heroku. This may sound time consuming, but it'll only require an extra 1-2 minutes each time that you need to make a Wordpress version, theme, or plugin update.

Steps

1) Register a Heroku account for your respective site. Select "PHP" for primary development language. Adding credit card information is required for us to install Wordpress. It'll also improve our free plan by increasing our 500 free dyno hours to 1000. If you want to learn more about dyno hours work, I highly recommend reading Andrey Azimov's blog post. My Wordpress installation wouldn't complete without adding the CC. I've never been charged and my sites are very active. You can check your usage here. Also try to keep a separate heroku account for each website, unless you don't expect much traffic.

2) Click the Deploy to Heroku button in Philipp Heuer's repo. I've tested several different Heroku/Wordpress installations and this is by far the best.

3) Visit your new app from your heroku dashboard and open the settings. Clone the Heroku git URL onto your computer.

4) Clone wordpress-heroku onto your computer. Afterwards, move the contents of wordpress-heroku into your empty app's repo. CD into your app, git add, commit, and push. You can now remove the empty wordpress-heroku folder from your computer.

5) Register a Cloudflare account. Cloudflare will provide the appropriate instructions for updating your nameservers. i.e. Login to GoDaddy, edit DNS settings, update nameservers.

Example nameservers:
NS aldo.ns.cloudflare.com
NS josephine.ns.cloudflare.com

You can now check cloudflare to see if your nameservers are pointing to Cloudflare. I recommend waiting at least 5-10 minutes for it to update.

6) This step is optional but highly recommended. Click the "Page Rules" tab on Cloudflare and enter the following three page rules:

  1. *YOURDOMAIN.com/*
    Always Use HTTPS

  2. www.YOURDOMAIN.com/*
    Forwarding URL - 301 Permanent Redirect
    https://YOURDOMAIN.com/$1

  3. YOURDOMAIN.com/*
    • Auto-minify Html, Css, Js
    • Rocket Loader On
    • Browser Cache TTL - 1 month

7) Open a new tab and visit your heroku app's settings again. Click "Add Domain" and enter your domain name without "www" or "https". Copy the DNS target. Go to your Cloudflare dashboard and click the DNS tab. We'll only need the following two rows. You can remove the other rows if you'd like.

Note: Your DNS Target will most likely be different from than the one provided in the screenshot.

Congrats you can now visit your new Wordpress site!


Updating Wordpress Version

You'll be updating Wordpress via Composer.json. If you do not have Composer installed on your computer, simply run brew install composer from the terminal. Open Composer.json in your repo's directory and look for: johnpbloch/wordpress. Change the version number to the latest wordpress version number.
i.e. "johnpbloch/wordpress": "4.9.2" -> "johnpbloch/wordpress": "5.4"

Advanced: Comment-out any plugins that you won't be using. Make sure that you're not missing any commas, or ending the last key-value pair in an object with a comma! I personally don't care for the Wordfence or All in One SEO plugin.

Once your done, run composer update from the terminal. Don't forget to push your changes.

Adding/Removing Plugins & Themes

To make changes to your plugins/themes, go to your repo /web/app. Here you will find your Theme and Plugin folders. Unzip your theme and plugins and place them inside these two folders. Once you've made the appropriate changes: git add, commit, and push to see changes.
Official Directory: Wordpress Themes and Plugins.

Note: The mu-plugins folder stands for Must-Use plugins. These plugins are automatically enabled and will be hidden from your plugin dashboard.

Preventing Redirect Loops/HTTPS Issues

If you're unable to login to the backend or getting "Not secure" errors, don't worry, there is a quick fix! Install Cloudflare Flexible SSL and update you SSL/TLS setting in Cloudflare to "Flexible".

Advanced: Replace any instances of "http" to "https" inside your repo's config/application.php file. You may now remove the plugin. Just be sure to use "https" links or the connection to your site will not be secure.

Managing Database

I recommend using MySQL Workbench by Oracle to manage your database. To get your database credentials, visit your app's dashboard in Heroku and click the "JawsDB Maria" link. Whenever you make a change in MySQL Workbench, be sure to apply changes.

If you're not comfortable with optimizing your database with manual SQL queries, I recommend using the WP Optimize plugin in Wordpress. The plugin will optimize your tables and help reduce your database size.

Uploading Images

Each time that we make any changes to our Wordpress files and push our code, we are overwriting our uploads folder. Therefore any images that we uploaded inside our Wordpress dashboard will be overwritten. Sure you can manually add images to the web/app/uploads folder on your computer, push it up, and link to the images inside your post.. but this eventually become very tiring. The solution is AWS - S3 Storage.

  1. Install WP Offload Media Lite.
  2. Create an AWS account.
  3. Follow these instructions. Please do not skip any of the steps. It's very short, and will save you a lot of hassle from debugging the permission settings later on.
  4. You can store the access keys inside the database and change this option later.

Important: While recently debugging this plugin for a client, I noticed that the URL's of the uploaded images were not updating to the S3 bucket URL's. I figured that the plugin is incompatible with the latest version of Wordpress in our Heroku configuration. To be on the safe side, stick to Wordpress 5.2 until this issue is resolved. You can downgrade Wordpress in the Composer.json.

Debugging

If you run into any issues, visit YOURAPPNAME.herokuapp.com rather than your custom domain. This eliminates Cloudflare from the picture and any potential caching or SSL issues. Ignore your wp-config file, it's almost useless to our configuration. Instead use your repo's config/application.php file if you want to add a PHP constant such as WP_DEBUG. Also, disabling plugins one by one is always a smart choice in Wordpress but don't forget about the mu-plugins that are hidden from the dashboard. It's common for the redis-cache/object-cache.php to create issues. Comment-out all three lines pertaining to redis-cache in your composer.json before running an update, as well as deleting it from your mu-plugins folder if it's creating issues.

Prevent Sleeping

Heroku's free plan will put an app to sleep after 30 minutes of inactivity. This will force the next visitor to wait several extra seconds before they can view your site. In order to prevent this from occuring, create a free account on Cron-job.org, enter your site link, and set the schedule to every 30 minutes.

The End

I hope that you found my guide useful, please let me know if you have any questions and I'll be more than happy to help 🙂

Posted on May 26 by:

Discussion

markdown guide
 

Thank you for this awesome post! I am kind of newbie in heroku and git. I am facing some problems. After adding a plugin/theme, i can't see it in my dashboard plugin/theme page. I did git add, commit and push. Still couldn't able to see any change on dashboard. I also can't login to dashboard with custom domain. Probably cloudflare flexible ssl plugin will solve the problem. But for that I need to be able to add a plugin which I am unable. Any help will be highly appreciated.
Thanks in advance.

 

Hey Monir, are you adding inside the app folder? And git add/commit/pushed it up to heroku? It should appear in your dashboard once you've done so... Yes the cloudflare flexible plugin will solve it. Once you become more comfortable, you can modify the config/application.php file and remove any instances of "http" ... Think of application.php as your wp-config.php file

 

Thank you for your reply. Yes, I did add inside pulled repo containing app name/web/app/plugins or /web/app/themes folder. And then add/commit/push it up to heroku using the command "git push heroku master". Meanwhile wordpress update with composer(I have updated to the latest version 5.4.2) and then pushing worked like a charm. But the plugins & themes don't appear in the respective section. I did try once again overriding the folder of themes and plugins to check but it shows "nothing to change/working directory clean (i dont remember exactly, but type of this text showed up). I also faced trouble because the git add,commit,push command was not working from that sub-folder but trying from the main branch showed nothing to change text on my windows(I am really a newbie in git console using and commands).

It's ok, you're getting very close to getting everything up and going. Do you use VSCode? Try dragging or opening your heroku app folder into VSCode and tracking git changes from there.. Also, is there a chance your adding the folder to the "wordpress-heroku" folder? because that's not the folder we are linked to in Heroku. My apologies if that's not the case.. This issue just seems to be git related, so I'm trying to figure out which folder you're pushing up

I also think I may have messed up something with git related. And I am adding folders on my given app name folder which was created by pulling my heroku app git url, not the "wordpress-heroku" folder. BTW, I didn't work with vscode. Let me try, although dont know how to manage it. Also trying to learn to get with git commands. Thank you for your replies. I am very close yet so far :(

Cool just wanted to make sure that you cloned down the git url from heroku, so thats good that you did that. I recommend using Vscode (visual code studio) for many reasons. One of the reasons is that it helps me visualize git a lot better. Whenever I'm coding, I can see which files to need to be pushed up. It also has a terminal of its own :)

By the way, did you type “heroku login” in your terminal to link your computer with your heroku account? I left that line out of the guide.

Thank you for your super effort. I will try vscode. One last thing to ask you, whenever I add a plugin in plugin folder then how should I connect it with main branch to use git push. Trying from the folder shows that there is no branch. And trying from the main branch shows nothing is changed. Thank you again.

Edit: I used heroku login earlier while uploading fresh wordpress. I was redirected to a browser and after successful login it returned back to the git bash terminal. After that, I didn't use login everytime as i suppose the connection isn't changed. And I could able to update wordpress also without any login.

Right on, you just need to run heroku login once so you're good. just wanted to make sure. It should already be connected to the main branch. Are you doing "CD" to go to the root folder of your app, then doing git add && git commit -m "anything" && git push ?

PS. I'm only using the master branch, never created any other branches since It's just me working on it.

Solved the problem! Probably a .gitignore file causing me to interrupt the uploading of the plugins. Thank you!

Awesome, looking forward to your success with your new wordpress site

 
  1. Paid dynos / hobby plan? What about the database hosting costs?
  2. Paid SSL? Why not let's Encrypt?
 

Hey Pacharapol, thank you for reaching out!

1) The Heroku free plan allows up to 1,000 free dyno hours (upon CC activation) which is more than enough. The main limitation is that the site goes to sleep after 30 minutes, which can easily be avoided if you ping your site before it goes to sleep. There are lot's of services that can help accomplish this. There are zero database costs, we are using the "Kitefin Shared" plan: elements.heroku.com/addons/jawsdb-....
2) Let's Encrypt is awesome. We're using Cloudflare for free SSL, plus many other benefits (i.e. minifying code, security.. )

There are zero costs involved with this guide. I'd say overall the biggest limitation is the 5MB max db size, which is more than enough for most basic Wordpress sites.

 

I've had a problem with Heroku when need a custom domain. SSL is immediately removed, unless paid dyno (hobby 7 USD/mo fixed). That's why I moved to Docker and Google Cloud Run, which automatically provision SSL. It's Pay As You Go and very cheap.

The only time I have to touch Let's Encrypt is on Digital Ocean. Luckily, there is Nginx-le Docker image with auto renew.

Thats so odd. Have you tried following Steps 5-7? I simply update the nameservers at GoDaddy to point to Cloudflare. I then click custom domain in my heroku app's setting (insert my url without www or https), and grab the dns target. Then I go over to Cloudflare and and add the two CNAME rows with the DNS target.

Anyways Heroku freeTier dyno will shut down after an idle. So not sure if I will use it for something serious.

Just set up a cron job that pings your site every 30 minutes medium.com/better-programming/keep...

Now, I made it with free everything.

  • Free Heroku
  • Free MongoDB Atlas
  • Free Cloudflare
  • Free subdomain (I already owned the domain name and used it elsewhere)

I think I currently don't need to keep it awake, or cron job; but I will consider it.

BTW, for your WordPress, it seems to be possible to build pages in advance, to static page; and host it on Netlify, where it is always awake anyway.

The search bar inside WordPress would probably be dead, without Heroku or some kind of serverless function, though.

Awesome! Glad to hear this. Will it work with a dynamic site as well? I've been using cron-job.org (for free) and haven't had any issues

 

I tried my way, but it seems to only run in Heroku, not local. I cannot run locally at all.

Which is probably as same as this isse.

DB error on local environment construction #33

Description of your issue

I guessed that the DB setting is set by CUSTOM_DB_URL of the .env file and set it up.

However, when I opened the top page, DB error occurred frequently such as no wp_post.

CUSTOM_DB_URL seemed to be not working effectively. So, do I need to add DB settings to web / wp / wp-config.php?

Also, config / environments / development.php Is it possible to switch the DB settings of each environment by describing the DB definition?

If possible, where do you decide the current declaration of (environment / production / staging / development)?

Steps to Reproduce

github.com/PhilippHeuer/wordpress-...

Other Information

Git Commit/Version: current master

 

Very inspiring. If you have article about Heroku build and deploy site with static generator such Hugo, Jekyll, Gatsby, Eleventy, please let me know.

 

I used Nuxt Universal (i.e. not SSG mode) with MongoDB Atlas, and is quite happy with it. This might also prevent rebuilding SSG for every new posts.

Hosted on Google App Engine for less than 1 USD/mo. The domain name is less than 10 USD/year.

 

Hi Bayu, I appreciate the comment. I'm sorry I haven't gotten there yet.