Free WordPress on Google Cloud DALL-E 3

Free WordPress on Google Cloud – Cloud Run. Part 2

Spread the love

This is one of the series of the articles about hosting WordPress (any) website on Google Cloud completely (or almost) FREE of charge.

At this stage we should have Cloud Run service (wordpress-apache), not database connection, Compute Engine VM instance (wordpress-sql) with MariaDB database running on it (as a Docker container) and ready for external connections (within custom VCP network).

Cloud Run with Database connection

So let’s update the Cloud Run service a bit (I’m using gcloud beta run, since only beta, at the moment of writing this article, supports VCP network):

gcloud beta run deploy wordpress-apache \
  --image docker.io/wordpress:apache \
  --region us-east1-b \
  --port 80 \
  --concurrency 100 \
  --cpu 1 \
  --memory 512Mi \
  --max-instances 1 \
  --cpu-throttling \
  --allow-unauthenticated \
  --set-env-vars WORDPRESS_DB_HOST=wordpress-sql.us-east1-b.c.wordpress-414215.internal,WORDPRESS_DB_NAME=wordpress,WORDPRESS_DB_USER=wordpress,WORDPRESS_DB_PASSWORD=userpass1234 \
  --network wpnetwork \
  --subnet wpsubnetwork

If you did everything correct, you should see something like:

Deploying Cloud Run service...
Deploying container to Cloud Run service [wordpress-apache] in project [wordpress-414215] region [us-east1]
✓ Deploying... Done.
  ✓ Creating Revision...
  ✓ Routing traffic...
  ✓ Setting IAM Policy...
Done.
Service [wordpress-apache] revision [wordpress-apache-00004-qg9] has been deployed and is serving 100 percent of traffic.
Service URL: https://wordpress-apache-vfbipc7oqa-ue.a.run.app

Open in browser your Service URL and you should see this page:

You can now finish installation of your WordPress and should be able to navigate to admin panel and website frontend of your WordPress.

Cloud Run with Cloud Storage

However you still won’t be able to store permanently any assets, since WordPress will put the files on the container’s filesystem which is stateless.

There are WP plugins which allows you to store the assets on external storages, including Google Cloud Storage.

To be able to use Google Cloud Storage you would need to enable Cloud Storage API. It should be already enabled (along with Cloud Run API enablement), but if not run the following command:

gcloud services enable storage.googleapis.com

Now you can install WP Stateless, or WP Offload Lite plugin and enjoy your WordPress on Cloud Run.

Your custom WordPress Container Image

At this stage you will be able to manage the assets on the external storage (Google Cloud Storage) but not the Themes or Plugins. To keep all installed themes and plugins you would need to add (or delete) the source code of your themes and plugins to/from the code base of your custom WordPress container image, for this you will need to build your custom container image, upload it to Google Artifact Registry repository (or Docker hub) and use it as a source of your container image for Cloud Run service deployment.

Using the custom container image you can change any source file, for example apply the PHP settings you need (for example allow upload more that 2MB files).

Let’s try to build our custom container image from source code.

Create the following folder structure, navigate to the root folder of your project and run the following commands:

mkdir -p docker/wordpress/source

Create Dockerfile file inside wordpress folder with the following content (I moved cloud run --set-env-vars parameter to Dockerfile ENV directives):

FROM wordpress:apache
COPY --chown=www-data:www-data ./source /var/www/html
ENV WORDPRESS_DB_HOST=wordpress-sql.us-east1-b.c.wordpress-414215.internal
ENV WORDPRESS_DB_NAME=wordpress
ENV WORDPRESS_DB_USER=wordpress
ENV WORDPRESS_DB_PASSWORD=userpass2345

Copy the source files of the original wordpress image into wordpress/source folder, you can do it by running the original wordpress:apache image locally on your local machine and mounting your source folder to the container’s /var/www/html folder, so docker will copy all source files into your source folder automatically on container start:

docker run --rm -v ./docker/wordpress/source:/var/www/html wordpress:apache

--rm – will automatically delete container when its stopped/killed
-v – mounts the volumes (source : target) to the container, more details about docker run command you will find here.

You should see the logs of the container, wait its finish and press CTRL+C to stop the container and delete, your source code will be copied to the source folder in the wordpress folder.

So your folder structure should be:

docker
|-conpose.yaml
|-wordpress
 |-Dockerfile
 |-source
  |- ...
  |-[wordpress source files]
  |- ...

Docker Build

You can build your custom images using the Docker, on your local machine. Make sure that the Docker is installed on your local machine, navigate to the root folder of your project and type the following command:

docker build --rm --tag ${image_url}:latest ./docker/wordpress/

Replace ${image_url} by your image URL. At the moment of writing this article, only Google Artifact Registry images or public Docker Hub images can be used in Cloud Run, so the Image URL, in my case, looks like: us-east1-docker.pkg.dev/wordpress-414215/cloud-run-source-deploy/wordpress-apache:latest

After successful build you should push your custom image to Artifact Registry:

docker push us-east1-docker.pkg.dev/wordpress-414215/cloud-run-source-deploy/wordpress-apache:latest

After that you should be able to deploy new Cloud Run service revision using your custom container image:

gcloud beta run deploy wordpress-apache \
  --image us-east1-docker.pkg.dev/wordpress-414215/cloud-run-source-deploy/wordpress-apache:latest \
  --region us-east1 \
  --port 80 \
  --concurrency 100 \
  --cpu 1 \
  --memory 512Mi \
  --max-instances 1 \
  --cpu-throttling \
  --allow-unauthenticated \
  --network wpnetwork \
  --subnet wpsubnetwork

Google Build

You can also build your custom images using the Google Builds. Make sure that the Cloud Build API is enabled, if not run the following command:

gcloud services enable cloudbuild.googleapis.com

There are two options how you can build your custom image for Cloud Run, using the gcloud run deploy command or dedicated command gcloud build, which won’t deploying the new revision of the Cloud Run service, only builds the image and uploads it to Artifact Registry.

To use gcloud run deploy option, type the following command:

gcloud beta run deploy wordpress-apache \
  --source ./docker/wordpress/ \
  --region us-east1 \
  --port 80 \
  --concurrency 100 \
  --cpu 1 \
  --memory 512Mi \
  --max-instances 1 \
  --cpu-throttling \
  --allow-unauthenticated \
  --network wpnetwork \
  --subnet wpsubnetwork

This command will automatically build new container image from source code (docker/wordpress/), upload it to Artifact Registry (automatically creates Artifact Registry repository if does not exists yet) and deploy the new revision of the Cloud Run service.

To use gcloud builds option, type the following command:

gcloud builds submit --tag us-east1-docker.pkg.dev/wordpress-414215/cloud-run-source-deploy/wordpress-apache:latest ./docker/wordpress/

Make sure that the Artifact Registry repository exists, or create it before you run gcloud builds command:

gcloud artifacts repositories create cloud-run-source-deploy \
  --repository-format docker \
  --location us-east1

After you built the container image you should be able to deploy the new revision of the Cloud Run service using your image by running the command:

gcloud beta run deploy wordpress-apache \
  --image us-east1-docker.pkg.dev/wordpress-414215/cloud-run-source-deploy/wordpress-apache:latest \
  --region us-east1 \
  --port 80 \
  --concurrency 100 \
  --cpu 1 \
  --memory 512Mi \
  --max-instances 1 \
  --cpu-throttling \
  --allow-unauthenticated \
  --network wpnetwork \
  --subnet wpsubnetwork

Bear in mind the size of the Artifact Registry repository within the Free Tier limits, at the moment of writing of this article Google gives you only up to 500MB (across all of your projects) to use for free.

After you deployed a new Cloud Run service using the containerized image form Artifact Registry (or from Docker Hub), you should be able to delete anything from your Artifact Registry to save the budget, however you won’t be able to switch between revisions in your Cloud Run service if the used image for the service was from the Artifact Registry and now is deleted.

On this stage your WordPress on Cloud Run installation is complete.

There are a lots of other options how to set up Cloud Run for your WordPress application, for example if you don’t like wordpress on PHP-apache you can setup additional container in your Cloud Run – nginx, which will handle the initial HTTP requests and transfer/forward it to your WordPress container layer (i.e. wordpress on PHP-FPM). Or you can mount Google Cloud Storage directly to your Cloud Run service application, so you won’t need to use WP plugins to store your assets.

The pros of this setup are:

  • You don’t have to worry about the server CPU, RAM, disk resources of your Cloud Run, since it is fully managed by Google Cloud Run itself, and is FREE within the Free Tier limits
  • You don’t have to worry about the external (public) IP address, it is handled by Cloud Run automatically and FREE of charge
  • You don’t have to worry about SSL certificates, it is handled by Cloud Run automatically and FREE of charge
  • Cloud Run is fully scalable, so if needed it can launch multiple instances or your app and if traffic is gone it can also close idle instances to reduce the costs completely automatically for you

The cons of this setup are:

  • There is no out-of-the-box solution for mounting Compute Engine persistent disks to your Cloud Run, which would help a lot with your plugin files and assets files management, however there are some tricks (not part of this story)
  • Cloud Run is stateless, so any file changes won’t be permanently kept but revoked on next Cloud Run service start
  • There is no SQL within the Cloud Run solution, so you need to use external SQL database server, either served on Cloud SQL (paid) or served on Compute Engine VM instance (free within Free Tier limits)
  • In Cloud Run you won’t have direct access to the container(s) of your app, you won’t be able to connect to your container via SSH to check the logs or stop/start some services, however Google Cloud gives you an alternative options, like Cloud Run service LOGS, where you will be able to see the logs of your container

If stateless or serverless is not something you can live with (or your website app can work with) and you need a classical web server capabilities – let’s dive into the Compute Engine possibilities, I’m sure you find it very helpful.