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've put together this guide for anyone who manages a self-hosted Wordpress site and is looking to not a dime (aside from annual domain fees). 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:
*YOURDOMAIN.com/*
Always Use HTTPSwww.YOURDOMAIN.com/*
Forwarding URL - 301 Permanent Redirect
https://YOURDOMAIN.com/$1YOURDOMAIN.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.
- Install WP Offload Media Lite.
- Create an AWS account.
- 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.
- 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 🙂
Latest comments (55)
Hey @aryaziai
What if I'm starting a brand new wordpress site (no host or domain yet) to be deployed on heroku? Would I still need Cloudflare?
I don't think cloudflare is necessary. I was using it just for "https"
Thanks a lot for this great help!
I tried it but it doesn't seem to be usable with S3.
Indeed, when I try to upload a picture, even small, it crashes saying it ran out of memory. Even when I change the memory limit to 512 MB, Heroku free plan's maximum, it still crashes when uploading the file.
I have to admit that I upgraded Heroku to 5.8, just because composer 1 is reaching end of life. I also upgraded other plugins but did not add any.
Did anybody run into the same problem? Did anybody find a solution?
Is it normal that Wordpress require more than 500 MB of memory?
Never mind, it seems gone now. Probably a bug by the AWS library
Interested in doing this, but 5Mb doesn't seem enough.
My WordPress site is 12,000+ posts.
My MySQL is 89Mb.
Files supposedly 3Gb.
Last night, I deployed my first thing to do Heroku, free. It's Nocodb, the open-source Airtable alternative. I have used it to browse my WP MySQL database. Nocodb seems to deploy as postgresql. The Heroku dashboard says it's using 11.5Mb. I guess it's different for MySQL?
Next one up for ClearDB on Heroku is $9.99pm.
This post (itecnote.com/tecnote/heroku-how-mu...) says "You can go over it by quite a lot (by 5-10x) before Heroku will get unhappy with you."
Is this right?
Hello @aryaziai, This is an awesome article. However, I ran into an issue when I change the Permalink to
POST NAME
in WordPress Permalink settings.It's giving me 404 on all my post pages.
Hi, i have an issue. anytime i activate a plugin or new theme. my website crashes and i get the notice as shown in the attached picture. please how do i fix this
I'm having issues updating to a newer version of WordPress. I opened the Composer.json file and changed the version number to "johnpbloch/wordpress": "5.8.1". Then, I updated composer (as per the instructions) and pushed my changes, but this only updates the version of composer, not the version of WordPress. I think I misunderstood the instructions somewhere. What am I missing? Thanks!
I am getting error when accessing admin page. After adding mentioned plugin in the folder, error persists.
Hi, thanks for the informative guide post.
I was able to deploy my wordpress site to heroku. Nonetheless, I have some few challenges.
First, adding
{
"require": {
"ext-gd": "*",
}
}
in my composer.json seems not to be working.
An attempt to run composer update brings up errors.
I attached a screenshot of my terminal for details of the errors.
Secondly, it seems setting up cloudflare with Amazon S3 Offload Media Lite plugin requires creating a sub-domain first, and then creating a CNAME record that matches the bucket name and sub-domain as explained in docs.aws.amazon.com/AmazonS3/lates...
However, is it possible to create a sub-domain with the Heroku wordpress hosting?
I'll gladly provide clarifications where necessary and will appreciate any help possible.
Many thanks to everyone.
Screenshot 2
I receive en error: Error establishing a database connection But at documentation said that data will be established automatically.
I got 500 error after deploy !
Some comments may only be visible to logged-in visitors. Sign in to view all comments.