Google Cloud Platform: Basic Dev-Ops For WordPress & Compute Engine

A WordPress site is easy to launch and surprisingly easy to neglect. The real operational work begins after installation: applying updates without breaking checkout, keeping database backups off the server, diagnosing slow pages, and knowing how to recover when a deployment fails.
Google Cloud Platform gives you the building blocks for that work, but it does not turn a virtual machine into a managed WordPress service. You still need a deliberate approach to security, releases, monitoring, and recovery.
This guide uses a 2019-era setup; tools, interfaces, and supported software versions may have changed since then.
We will use Google Compute Engine to build a modest WordPress environment, then add the basic DevOps practices that make it maintainable. The goal is not a complicated enterprise architecture. It is a site you can update confidently and restore when something goes wrong.
Understand the architecture before creating resources
Compute Engine provides virtual machines with configurable CPU, memory, disks, and networking. Unlike a platform service that manages much of the runtime for you, a Compute Engine VM leaves operating-system and application administration in your hands.
For a small site, a reasonable starting point is:
- One Ubuntu 18.04 LTS VM running Apache, PHP, and MySQL.
- A persistent boot disk containing the application and database.
- A reserved external IP address and a domain name.
- Cloud Storage for off-server backups.
- Stackdriver Monitoring and Logging for operational visibility.
This is a single-server architecture, not a highly available one. A VM failure or maintenance interruption can take the site offline. Compute Engine also does not automatically scale a standalone WordPress installation when traffic increases.
Cloud SQL is an optional next step. It moves database infrastructure management into a managed service, but adds cost, connectivity configuration, and migration work. Start with the simplest architecture that meets your recovery and availability requirements.
1. Prepare the project and access controls
Create a GCP project, attach a billing account, and enable the Compute Engine API. Use Cloud Shell for the following commands; it includes the Google Cloud SDK and an authenticated session.
Replace the example values before running anything:
export PROJECT_ID="your-project-id"
export ZONE="us-central1-a"
export REGION="us-central1"
gcloud config set project "$PROJECT_ID"
gcloud services enable compute.googleapis.com
Choose a region close to your visitors and, if applicable, compatible with your data-location requirements.
Establish a few guardrails
Create a billing budget with notifications. Budget alerts are warnings, not spending caps: resources continue running after a threshold is reached.
Give each administrator an individual account and only the IAM permissions needed for their work. Avoid shared credentials and broad Owner access for routine maintenance.
The VM itself should not inherit unnecessary access to your cloud resources. Our initial example runs without a service account; you can attach a dedicated, narrowly permissioned account later for backups and monitoring.
2. Create a VM and restrict its network exposure
Reserve an address so DNS does not depend on an ephemeral IP:
gcloud compute addresses create wordpress-ip \
--region="$REGION"
export WP_IP=$(gcloud compute addresses describe wordpress-ip \
--region="$REGION" --format='get(address)')
gcloud compute instances create wordpress-1 \
--zone="$ZONE" \
--machine-type=n1-standard-1 \
--image-family=ubuntu-1804-lts \
--image-project=ubuntu-os-cloud \
--boot-disk-size=20GB \
--address="$WP_IP" \
--tags=wordpress-web \
--no-service-account \
--no-scopes
This example assumes the project has a default VPC network. If it does not, create a VPC and subnet first and specify them when creating the VM.
Allow public web traffic:
gcloud compute firewall-rules create wordpress-web \
--network=default \
--allow=tcp:80,tcp:443 \
--source-ranges=0.0.0.0/0 \
--target-tags=wordpress-web
Audit existing firewall rules as well. Default networks may already permit SSH from anywhere. Restrict SSH to trusted administrator addresses or configure Identity-Aware Proxy access; adding a restrictive rule does not cancel an existing broad allow rule.
Do not expose MySQL port 3306 publicly. For this single-server setup, the database should accept only local connections.
Connect using the console SSH button or gcloud compute ssh wordpress-1 --zone="$ZONE", provided your chosen SSH access policy permits that connection. Run the installation commands below on the VM, not in Cloud Shell.
3. Install the WordPress runtime
Update the operating system and install a basic Apache stack:
sudo apt update
sudo apt upgrade -y
sudo apt install -y apache2 mysql-server curl unzip \
php libapache2-mod-php php-mysql php-curl php-gd \
php-mbstring php-xml php-zip
sudo systemctl enable apache2 mysql
sudo mysql_secure_installation
Reboot if package updates require it, then reconnect. These package choices reflect Ubuntu 18.04 in 2019, not a recommendation to deploy obsolete runtimes today.
Create a dedicated database user
Open MySQL with sudo mysql, then run the following with a unique password:
CREATE DATABASE wordpress
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wordpress'@'localhost'
IDENTIFIED BY 'REPLACE_WITH_A_LONG_UNIQUE_PASSWORD';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'localhost';
EXIT;
WordPress should never connect as the MySQL root user. Keep database credentials out of Git, deployment logs, and shell scripts shared with others.
Download WordPress from its official distribution endpoint:
cd /tmp
curl -fLO https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
sudo mkdir -p /var/www/wordpress
sudo cp -a wordpress/. /var/www/wordpress/
sudo chown -R root:www-data /var/www/wordpress
sudo find /var/www/wordpress -type d -exec chmod 755 {} \;
sudo find /var/www/wordpress -type f -exec chmod 644 {} \;
sudo mkdir -p /var/www/wordpress/wp-content/uploads
sudo chown -R www-data:www-data \
/var/www/wordpress/wp-content/uploads
The latest endpoint changes over time. For repeatable deployments, record the installed version and retain the exact release artifact rather than downloading an unspecified version on every deployment.
Create wp-config.php from wp-config-sample.php, enter the database details, and generate unique authentication keys and salts using WordPress.org's salt service. Make the configuration readable by Apache but not world-readable:
sudo chown root:www-data /var/www/wordpress/wp-config.php
sudo chmod 640 /var/www/wordpress/wp-config.php
This ownership model deliberately prevents dashboard-based code updates. Apply core, plugin, and theme updates through a controlled administrator deployment process instead; otherwise, security updates can be silently neglected.
4. Configure Apache, DNS, and HTTPS
Create /etc/apache2/sites-available/wordpress.conf:
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/wordpress
<Directory /var/www/wordpress>
Options -Indexes +FollowSymLinks
AllowOverride FileInfo
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/wordpress-error.log
CustomLog ${APACHE_LOG_DIR}/wordpress-access.log combined
</VirtualHost>
Enable the site and rewrite support:
sudo a2enmod rewrite
sudo a2ensite wordpress
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl reload apache2
Create a DNS A record pointing example.com to the reserved IP. Once DNS resolves correctly, install Certbot using its Ubuntu/Apache instructions appropriate to the period, then run:
sudo certbot --apache -d example.com
sudo certbot renew --dry-run
Confirm that automatic renewal is scheduled and select HTTP-to-HTTPS redirection. Complete the WordPress installer over HTTPS, using a unique administrator username and strong password. During initial provisioning, restrict web access to your address so a stranger cannot complete the installer first.
Because Apache cannot write the application directory, saving permalink settings may require manually installing the rewrite rules WordPress displays into .htaccess.
5. Make deployments repeatable
A basic DevOps workflow separates application code, configuration, and changing site data.
Keep custom themes, plugins, and deployment scripts in Git. Exclude wp-config.php, database exports, caches, and uploaded media. Document the WordPress core version and third-party plugin versions alongside your release instructions.
Use this release sequence:
- Restore a recent backup into an isolated staging environment.
- Disable outbound email, payment actions, and indexing there.
- Apply the proposed code and dependency updates.
- Test login, forms, media uploads, permalinks, and critical business flows.
- Back up production and deploy the tested release.
- Check the public site and logs immediately afterward.
Cloud Build can automate packaging and testing once the manual process is reliable. Give its deployment identity only the permissions it needs; do not solve deployment failures by granting project-wide Owner access.
A Git rollback reverses code, not database migrations. If a plugin changes its schema, recovery may require restoring matching database and code versions. Plan that rollback before deploying, including what happens to orders or comments created afterward.
6. Back up data, and prove you can restore it
A useful WordPress backup includes the database, uploads, configuration, and enough version information to reconstruct the code.
For MySQL tables using InnoDB, a logical export can use:
mysqldump --defaults-extra-file=/root/.wordpress-backup.cnf \
--single-transaction --quick wordpress \
| gzip > /var/backups/wordpress.sql.gz
Run this as root with a root-readable credentials file. In an automated script, enable set -o pipefail, use timestamped filenames, check failures, and alert when a backup is missing. Transactional exports do not guarantee consistency for nontransactional tables or concurrent schema changes.
Copy backups to a private Cloud Storage bucket using a dedicated VM service account with narrowly scoped bucket permissions and appropriate VM access scopes. Apply retention or lifecycle rules and verify uploads succeeded. The only backup must not live on the disk it protects.
Persistent disk snapshots are useful for machine recovery, but live snapshots alone are not a complete application-consistency strategy. Coordinate database and filesystem backups, briefly pausing writes when consistency requires it.
Regularly restore into a separate VM. Check that WordPress starts, media loads, and expected records exist. Record the recovery steps and elapsed time.
7. Monitor, maintain, and scale deliberately
In 2019, GCP's operational monitoring tools are branded Stackdriver. Configure uptime checks and alerts, then install the relevant monitoring and logging agents with the required service-account permissions. Basic VM metrics do not reveal every application failure or guest-memory problem.
Watch disk capacity, memory pressure, CPU, HTTP errors, and database behavior. Keep sensitive form data and credentials out of logs, and control log retention.
Create a short maintenance checklist:
- Apply operating-system and WordPress security updates promptly.
- Remove unused plugins, themes, accounts, and cloud resources.
- Verify backups, certificate renewal, and alert delivery.
- Review costs for disks, snapshots, traffic, and abandoned staging VMs.
Before adding servers, investigate slow plugins, oversized images, database queries, and caching. Never cache personalized account or checkout pages indiscriminately.
Moving to multiple VMs requires shared media handling, coordinated releases, a shared database, and suitable caching or session behavior. A load balancer alone does not make independent WordPress installations consistent.
Takeaway
Compute Engine gives WordPress flexibility, not automatic operational care. Start with restricted access, HTTPS, repeatable releases, monitored backups, and a tested recovery procedure. Those habits matter more than a complicated architecture, and provide a sound foundation when the site eventually needs one.
Conversation (0)
No comments yet. Start the conversation.
Join the conversation
Create a free member account to comment.