This article documents deploying the WordPress content management system (CMS) in Google Cloud as a fast, friendly, cheap (possibly free!) platform to blog from.
This is probably relevant for you if:
- Youāre looking to start a blog
- Youāve settled on WordPress, the top Open Source blogging engine
- You have some Linux command line skills
Iām not going to discuss choosing WordPress over some other content management platform. Spending too much time worrying about the content management engine is a trap; Get to producing your content and donāt worry about the platform youāre using to publish it. Thatās something you can change later on, as most of the major CMS platforms have tools to migrate from the other major platforms.
Why: Motivation
I host WordPress on tiny virtual machines in Google Cloud for administrative performance, and entry-level price. Iāve been asked āhowā enough times that Iād like to document it for others.
My Blogging History ā Blogger
My writing for the web has been a hobby, not a profession. I got started publishing personal short and medium form content on the Blogger platform. Blogger still exists, and if it fits your purpose, you might want to bypass all of this and just use it. Again, you can always change your platform later. The content is the important thing.
Blogger to WordPress shared hosting
I eventually moved my personal writing and professional musings to shared WordPress hosting platforms. WordPress is probably the most popular Open Source content management system out there. With that footprint comes tons of support, active development, and a large ecosystem of enhancements (themes, plugins, customizations). WordPress hosting services were an easy way to get started using WordPress without thinking about the infrastructure. Over the years I used a variety of vendors including (I think) Bluehost, DreamHost, and iPage.
WordPress shared hosting to WordPress in Google Cloud
After a number of years, I grew frustrated at the slow performance during upgrades of WordPress plugins and themes. I would log in to WordPress, intending to copy some content in and move on, a 2 minute task, only to see the latest group of upgrades that needed my attention. Those upgrades require suspending the WordPress engine and could lock up 10-15 minutes of my time. I ran some tests and found that WordPress running in a small VM could do the same thing in less than 15 seconds. Despite the poor relative performance, shared hosting vendors were expensive relative to what you could pay for in a cloud VM. I had the expertise to do the minimal administrative tasks, so I bit the bullet and migrated my content to self-hosted WordPress within Google Cloud. Iāve been promising/threatening to document that process for years, and have finally gotten around to doing so.
Why blog ā Self-documentation
In both professional and personal contexts, Iāve long advocated writing about things one cares about as part of the process of improving skills. When blogging about my profession, I started as a consumer of other peopleās technical writing, searching out solutions to my problems in other peopleās writing. The thing that pushed me towards doing my own writing was when no one had encountered the specifics of my situation, which forced me to synthesize a number of different articles and documentation to reach my solution. At first I wouldnāt document it, mistakenly thinking it was a one-off situation. Eventually, Iād find myself wasting time re-creating the solution. It took an embarrassing number of times before I finally started just writing and publishing the variations of solutions I needed. And it didnāt take long at all before I was Googling a problem and found my own article on how to solve it.
Why blog ā Improve thinking
Writing has benefited me in a number of ways, not just documenting knowledge for my future self. Writing clarifies my thinking. Well, more accurately, it reveals to me when my thinking isnāt clear, and the process of getting the writing done forces me to concentrate on clarifying my thoughts. It organizes my thinking. Writing this article, for example, forced me to separate out the process of deploying WordPress for the first time from the process of migrating to it, migrating instead of upgrading, and using it as a podcast publishing platform. I thought of, and tabled other projects, such as using WordPress as a Knowledge Management CMS.
I donāt think Iāve ever gotten a job or even improved a performance review because of my technical blogging. However, Iāve found that the process of organizing my thoughts and documenting solutions for repeatability has helped me professionally.
Why Google Cloud?
I happened to choose Google Cloud when I first started migrating my sites. I want to disclose that I now work for Google Cloud as a Customer Engineer, but that employment change happened years after I made my blogging platform decision. The main reasons I chose Google Cloud, at the time, was a slight price advantage and the fact that I was already using most of the Google consumer products (Gmail, Maps, Photos, YouTube, etc).
How to deploy WordPress in Google Cloud
The overall process of deploying WordPress to Google Cloud has four overall steps:
- Get Google Cloud prepped for the WordPress deployment
- Deploy WordPress into a small Google Cloud Engine virtual machine
- Configure the path people will use to reach the site
- Start publishing
Get Started with Google Cloud
If you have a Gmail account, you already have the basis for getting started with Googleās Cloud services. Hereās the Getting Started landing page. If you havenāt tried it before from that Gmail account, youāll get $300 in credits for the first 90 days that youāre using it. Thatāll make your WordPress virtual machine essentially free during that time for most use cases.
-
Log in to the Google Cloud Console Youāll need a (free) Google account, which many people already have for Gmail. If you donāt have that, your first step will be to get it. Youāll get a click-through Terms of Service statement.
-
Create a Project for the WordPress instance. Use a meaningful name for your project, such as a the name of the blog. A project is just an administrative construct within which youāll be deploying your cloud resources. Later on, you might want to report on or do budget alerts for the blog. And if you want to publish multiple different blogs, you generally want different projects so you can report on and control them separately. Donāt overthink the permissions discussed in the official documentation; If youāre running a business, you might need to have multiple people with access to the project and different levels of permissions, but as a single hobbyist, project level permissions in the official documentation donāt really matter.
-
Set up payment for your Google Cloud account, (most likely a credit card). Again, youāll have $300 of free credits to use for the first 90 days, and after that weāll be using the free tier of services, but youāll need a payment method for any non-free services.
This discussion is focused on those who want the minimal infrastructure for a self-hosted instance of WordPress on a virtual machine (VM). This involves only two real parts of GCP; Google Cloud Engine is the virtual machine service and getting the underlying static IP address for the site, part of cloud networking.
Deploy a curated version of WordPress
- For your first VM, deploy on an e2-micro in us-central1 to use in Google Cloudās free tier. As of the time of this writing, the only machine qualifying for the free tier is a single e2-micro instance running in us-west1, us-central1, or us-east1. Any subsequent WordPress instances I create, Iāll use the N1āf1-micro for between $4-6/month.
- I rely on the crew at Bitnami to create curated packages to deploy WordPress. More specifically, I use the WordPress with NGINX and SSL Certified by Bitnami and Automattic [Link to Google Cloud Marketplace]
Confirm youāre deploying into the correct project
In the Google Cloud Console, I make sure Iām within the Google Cloud Project I created for this WordPress installation, then navigate to the WordPress with NGINX and SSL Certified by Bitnami and Automattic within Google Cloud Marketplace. Youāll see a fairly prominent āLaunchā button. This Launches a configuration page, not the actual instance, so click-through.

On the configuration page, there are several things to change. I make sure thereās some metadata in the name, and that Iām using the cheapest deployment available, a combination of deployment zone and machine type.
- Deployment name
I add a name for the instance incorporating the name of my blog and the date Iām deploying the instance: blogname-YYYY-MM-DD. That way, I know exactly when I deployed the VM and this instance of WordPress at a glance.
- Zone
For the free tier, you currently need to be in us-west1, us-central1, or us-east1. The latter two are the cheaper regions if youāre outside of the-free tier.
- Machine Type
The free tier currently covers a single e2-micro machine
Series – E2
Machine type – e2-micro
You can see the estimated monthly cost to the right of the configurations. These prices are as of June 2022. For your first VM in the free tier, use an e2-micro. Subsequently, I use Series N1, f1-micro for between $4-6/month. If you ever have performance issues, you can just use a migration process to re-deploy to a large instance.

The process of creating the instance will proceed, and youāll have an output which includes the current IP address of the instance and the initial, temporary username and password.

Instance configuration
There are a few things to tweak in the installation before we migrate our current blog content over to it. Apply any WordPress updates, install additional plugins, and make your ephemeral external IP address static. After that, point a domain name for the blog at the address, configure secure connections, and configure WordPress to use the domain name as the blogās name rather than the IP address.
Change the Admin user and password
You can see from the last figure, that there was a user/password generated from the deployment. Add your own account and make it an admin. Choose a strong password that you wonāt forget or that you store in a password service (I use LastPass or Google Password Manager in Chrome/Android).
After youāve logged out and in successfully as the new admin user, remove the user created by the deployment process.
Apply WordPress Updates
- Go to the updates page on your WordPress Dashboard http://<instance-ip-address>/wp-admin/update-core.php Normally, youād want to back up your WordPress instance before making major upgrades, but this instance is empty. If thereās any problems, just delete the VM and start over.
- Upgrade WordPress version if thereās one available (for example, Iām upgrading WordPress 5.9.3 to 6.0)
- Upgrade the plugins
- Upgrade the themes
Basic Plugins
There are a few plugins I like to use which arenāt part of Bitnamiās initial installation, so I install them at this time:
- Broken Link Checker – Lets me see and correct broken links in my site
- Image Source Control Lite – Makes sure Iām crediting all the images I use
- ImageInject – Search and use free images
Chose a Basic Theme
At this point, I like the clean, classic look of the official WordPress āTwenty Fifteenā theme. Iāve never been one to spend much time customizing this kind of thing. Thereās plenty of time to do that later. Any time you spend here is just delaying your writing.
Convert your VMās dynamic/ephemeral IP address into one thatās statically assigned to your site
Your WordPress site was deployed on a VM with an external (internet-facing) IP address that Google Cloud calls āephemeral.ā That is, it might change, at any given reboot of the VM. What we want is a āstaticā IP address, one which is assigned to the VM as long as we want it to be.
Hereās a link to the official GCP documentation on promoting your ephemeral IP address static.
- Go to the External IP Addresses page at the Google Cloud Console.
- Make sure youāre in the correct Project for your WordPress instance
- On your VMās current ephemeral IP address row (it should have the name of the VM in the āin use byā column), click āReserveā
- Give a meaningful name for the newly static IP address. I generally use the VM name with ā-staticā at the end.
Make a DNS entry for your static IP address
If youāve already registered for your siteās domain name, follow your registrarās instructions on providing an āAā record for your siteās domain name that points at the static IP address that you just promoted.
Example using Google Domains
I happen to use Google Domains as my registry for convenience. I registered the vjourneyman.com for $12/year. Hereās instructions on how to buy a domain name using Google Domains. But use whatever domain registrar youāre comfortable with.
After I own the domain, I navigate to the DNS section.

Then I created an āAā entry for both vjourneyman.com and all the secondary domain names with an entry for ā*.vjourneyman.comā, and an explicit secondary domain record in case someone uses www.vjourneyman.com

It might take a few minutes for the new entry to propagate out to the world. You can check using a public DNS service like DNS Checker. This could theoretically take hours, but as long as you can locally resolve your domain name to the IP address, then youāre good to move on.
Configure WordPress to use Domains instead of IP Addresses
From the deployment process, WordPress has been hard-coded to use the machineās IP address instead of a domain name. Now that weāve reserved the IP address for the use of this machine and have registered the domain name and pointed it at the IP address, we can change WordPress to refer to itself through the links it shows by domain name instead of by IP address.
This is where weāll need comfort with the Linux shell. Youāll need to launch an SSH connection to your VM (Google makes this easy from the console)
Here is the Bitnami documentation page for configuring the WordPress domain name. Weāre deploying a self-contained image, so using Approach A to change the domain name.
sudo vi /opt/bitnami/wordpress/wp-config.php
Within the file, replace:
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/');
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/');
With:
define('WP_SITEURL', 'http://$DOMAIN/');
define('WP_HOME', 'http://$DOMAIN/');
Where āDOMAINā is your siteās actual domain name.
Optional, but Best Practice: Enable Secure Connections to the site with https
Modern web browsers try to connect to every site using an encrypted connection (https). This is something we can support on our blog using Secure Sockets Layer (SSL) and the free third party certificate authority, āLets Encrypt.ā
Generate And Install A Let’s Encrypt SSL Certificate
This is where weāll need comfort with the Linux shell again. Since weāre using a Bitnami VM, we can use Bitnamiās instructions creating and registering an SSL certificate. Iāve directly linked to āApproach A: Using system packages.ā, but you can check for yourself which approach you should use depending on the build of the VM. Youāll need to launch an SSH connection to your VM (Google makes this easy from the console:
To make sure which approach you should be using:
test ! -f "/opt/bitnami/common/bin/openssl" && echo "Approach A: Using system packages." || echo "Approach B: Self-contained installation."
Again, Iām using Approach A.
-
Install the Lego client
cd /tmp curl -Ls https://api.github.com/repos/xenolf/lego/releases/latest | grep browser_download_url | grep linux_amd64 | cut -d '"' -f 4 | wget -i - tar xf lego*_linux_amd64.tar.gz sudo mkdir -p /opt/bitnami/letsencrypt sudo mv lego /opt/bitnami/letsencrypt/lego
-
Generate A Letās Encrypt Certificate For Your Domain This step depends on DNS entries correctly pointing to your blogās IP address.
-
Turn off Bitnami services
sudo /opt/bitnami/ctlscript.sh stop
-
Request a certificate for all the domains that someone might get your site by. Iāve included both the primary domain and www in this code. Assign values for your domain and email address!
EMAIL=āā DOMAIN=āā sudo /opt/bitnami/letsencrypt/lego --tls --email="$EMAIL" --domains="$DOMAIN" --domains="www.$DOMAIN" --path="/opt/bitnami/letsencrypt" run
- Configure The Web Server To Use The Letās Encrypt Certificate
-
Link the certificates to where the web server can access them. Weāre using NGINX for this installation, Approach A, so follow those instructions.
sudo mv /opt/bitnami/nginx/conf/bitnami/certs/server.crt /opt/bitnami/nginx/conf/bitnami/certs/server.crt.old sudo mv /opt/bitnami/nginx/conf/bitnami/certs/server.key /opt/bitnami/nginx/conf/bitnami/certs/server.key.old sudo mv /opt/bitnami/nginx/conf/bitnami/certs/server.csr /opt/bitnami/nginx/conf/bitnami/certs/server.csr.old sudo ln -sf /opt/bitnami/letsencrypt/certificates/$DOMAIN.key /opt/bitnami/nginx/conf/bitnami/certs/server.key sudo ln -sf /opt/bitnami/letsencrypt/certificates/$DOMAIN.crt /opt/bitnami/nginx/conf/bitnami/certs/server.crt sudo chown root:root /opt/bitnami/nginx/conf/bitnami/certs/server* sudo chmod 600 /opt/bitnami/nginx/conf/bitnami/certs/server*
-
Restart Bitnami services
sudo /opt/bitnami/ctlscript.sh start
- Test the configuration
- Can you go to your blog using https in the URL?
- Do you see the padlock by the domain name in the browser window, indicating that the connection is secure?
Assuming that everything went well, you now have secure https access to your site set up!
- Set up automatic renewals of the certificate
Create a script to automatically renew the certificate:
sudo mkdir -p /opt/bitnami/letsencrypt/scripts
sudo nano /opt/bitnami/letsencrypt/scripts/renew-certificate.sh
The contents of the script should be:
#!/bin/bash
sudo /opt/bitnami/ctlscript.sh stop nginx
sudo /opt/bitnami/letsencrypt/lego --tls --email="EMAIL" --domains="DOMAIN" --path="/opt/bitnami/letsencrypt" renew --days 90
sudo /opt/bitnami/ctlscript.sh start nginx
Make sure you put your email address and domain name in for the placeholders!
Make it executable:
sudo chmod +x /opt/bitnami/letsencrypt/scripts/renew-certificate.sh
Open the crontab editor:
sudo crontab -e
Add the following entry to periodically run the renewal:
0 0 1 * * /opt/bitnami/letsencrypt/scripts/renew-certificate.sh 2> /dev/null
Now renewals should be automated!
Get Publishing
- Write
- Edit
- Publish
- Repeat
In general, I do my writing outside of WordPress, using Google Docs. I write plain text using Markdown, and copy/paste the content into a [ordPress Markdown Block. Hereās instructions on Enabling Markdown blocks in WordPress . I add any images I might have captured to the post, then schedule publishing.
Set Up Backups
I use the UpdraftPlus WordPress Plugin for backups, namely because it can, with my authorization, place the backup files inside my Google Drive. And it does so for free. You might think that if Iām writing my posts in Google Docs, thereās no reason to backup. Youād be wrong. While itās technically possible to re-create your posts, itās incredibly painful, especially as you write more. Just set up backups to a personal Drive.
Optional but Best Practice: Set up Budget Alerts for the Project
I mentioned before that a Google Cloud Project is a really good abstraction to report on, especially to create cost warnings. For our purposes, weāre planning on running this WordPress blog in the free tier, so any spending over $5 (for example) would warrant a warning. So letās set that up.
Hereās the subsection on Google Cloudās official documentation on Budgets which deals with actually creating a budget (bypassing a lot of the enterprise/business concern about permissions and roles).
- Create the budget Go to Billing ā Budgets on the Google Cloud console. Thereās a āCreate Budgetā button along the top.

- Set the scope of the budget
- Name the budget something meaningful. I use the name of the blog and the budget. āvJourneyman $10ā
- Weāre looking for an alert every month, so time range is āMonthlyā
- We want to alert only the project that houses WordPress, so select that project from the Project dropdown.
- Then select āNEXTā

- Set the details on the Budget Amount
- The default should be to āSpecified Amountā.
- Weāre going to have a $10 budget and have an alert emailed when half of it is used.
- Select āNEXTā

- Set the actions
- The defaults should work here. Weāre being alerted when 50%, 90%, and 100% of our budget is consumed.
- The way weāre being alerted is emails sent to the billing admins and users.
- Select āFINISHā

Congratulations, your budget setup is all done!
Conclusion
I hope this article has been helpful in getting you closer to launching your blog. Hopefully youāll agree with me that WordPress in Google Cloud is both faster and cheaper! If you have any feedback, such as problems following a specific step, Iād love to hear it.
Most importantly, get writing sooner rather than later. If you have problems getting this setup up and running, donāt let that stop you from writing. Write in a Google Doc so you can copy/paste into your blog later. Get writing!
Leave a Reply