High Availability WooCommerce from scratch with zero DevOps and just in five minutes

Hi! For the sake of your convenience, I have divided my article into three chapters:

  • Chapter 1. "Let's Get It Installed in a Snap". Here I will tell you how to prepare a High Availability infrastructure and how to set up WooCommerce on it. Spoiler: it's really easy if you use proper tools.
  • Chapter 2. "Let's stress it! Is Horizontal Autoscaling good?" Here I will talk about the stress test I ran and the way I adjusted the infrastructure to survive the load. Also, here you can find real costs of a WooCommerce website.
  • COMING SOON! Chapter 3. "Let's stress it once again! Actually, Horizontal Autoscaling is good!" Here I will show how to adjust the infrastructure to make Horizontal Autoscaling work perfectly and compare all the previous setups by RPS and pricing. If you need a brief practical guide, then this is it.

You can repeat any step even without repeating other steps. Moreover, you don't need to install any software on your machine (except for Docker but you already have it, right?), you don't need to run any builds (i.e. set up a development environment), you don't need to do programming.

I believe that IT must be an easy thing in 2022.

So how to prepare a HA infrastructure and set up WooCommerce on it? It's not as challenging as you might think!

Chapter 1. Let's Get It Installed in a Snap

Before We Begin, Make Sure That You Have

  1. WooCommerce Docker image (as a Docker file in a Git repository or a Docker image in a Docker repository). I use this Git repository: https://github.com/wspaws/woocommerce.git and this docker image: plesk/woocommerce
  2. WSP for AWS. This service does most of the work.
  3. GitHub or Google account to log in to the service.

Yep, that's all you actually need.

Setting Up WooCommerce on a High Availability Infrastructure

  1. Log in to WSP for AWS using your GitHub or Google account.
  2. Click Add Application.
  3. Select a Git or Docker image
    • For Git: enter https://github.com/wspaws/woocommerce.git
    • For Docker: enter plesk/woocommerce
  4. Click Connect Repository.
  5. Turn on the Database ("Enable RDS Support") and Filesystem ("Enable EFS support") services.
  6. Click Add and Deploy.

Wait a couple of minutes and it's done. No, seriously, we are done here! Just give it a try. OK, OK, I will explain the steps in details below.


Detailed Tour

Step 1. Logging in

To log in to the service, I go to http://cp.wpcp-demo.io/ and use my GitHub account. I prefer this way, but you can use your Google account as well if that fits you best.

  1. It is completely secure because GitHub is responsible for authentication. And I trust GitHub.
  2. It is convenient because I can't stand long registration forms, I can't stand remembering the password I used for registration, and so on.
  3. And besides, I can revoke my auth via the GitHub interface if I want it.

Free Trial Environment

At first login, WSP for AWS provides me with a Free Trial Environment (which is a piece of the AWS resources used to run your app) for a week. It's usually enough for testing purposes but you can contact the support team via the live chat and ask them to extend the trial period.

For production use, I need to connect my AWS account as a Production Environment. All I have to do it to provide WSP with my AWS Account ID and agree with to grant access. Of course, I can revoke access at any time using AWS Console > Services > IAM > Roles

For now, I don't need a Production Environment so I do not need to connect my AWS account.

Step 2. Adding Application

Use Git Repository

WooCommerce (and WordPress) has no official dockerization so I use this: https://github.com/wspaws/woocommerce.git.

Domain Name and TLS Certificate are Already There

For my task, I'm OK with a technical domain name provided automatically while issuing a free TLS certificate. For production use, I would specify my own domain name for which a free TLS certificate would also be provided.

Setting Up the Database

WooCommerce (as WordPress) needs a Database so I enable the RDS service. RDS is a managed database service, which means that:

  1. I don't need to create it.
  2. I don't need to maintain it.
  3. I don't need to create backups because they are automated (thanks to AWS, I can restore the database to the state of any particular second within the retention period).

I need to pass the Database connection parameters to my WooCommerce application and I can do that using the "ENV: DB smth" fields. These fields contain environment variables that will be filled with the connection parameters. For example, DB_HOST will contain the domain name where my RDS instance is available, and so on.

Now I need to change these names to the ones used by my application. Usually, you can get the list of required environment variables from the documentation of your app or the docker-compose.yml file.

If your application uses a special variable (e.g., a one-liner DSN), you can read more about setting it in the "Environment variables & secrets" section below.

In my case, I don't need to change anything because my version of WooCommerce (https://github.com/wspaws/woocommerce.git) already supports default names (look at the docker-entrypoint.sh, the magic is right there).

Persistent File Storage

I am also going to run WooCommerce using Docker so I need to set up a persistent file storage. Again, you can usually get the volumes/paths from the documentation or the docker-compose.yml file. In my case, I have no need in changing the default value.

Automated Setting Up WORDPRESS_URL via .env File

And the last important thing to remember is that WooCommerce is a WordPress plugin. Therefore, I have to specify the WORDPRESS_URL environment variable. My git repo contains the .env file with the environment variables. WSP loads the file automatically, which is why I don't need to manually enter the variables. As you can see, WSP supports substitutions here.

WORDPRESS_ADMIN_PASSWORD: How to Make It Secure?

When you leave the WORDPRESS_ADMIN_PASSWORD variable with no value, you literally mean "Please generate a random password". But how do you get the auto-generated password afterwards? I'll show it further as well.

Alternatively, I can pass the password securely using the Secrets feature. The Secrets are stored using the encrypted SSM (this is an AWS thing, never mind) mechanic so nobody can see it. Nobody, including me. Security!

Use Docker Image

If I have a Docker image, I can use it as well. The process is very similar to the adding applications using a Git repository. If I were to go this way, I would use the plesk/woocommerce Docker image.

The Database setup is completely the same as in the previous section.

Differences from Git: Persistent File Storage and Environment Variables

WSP examines the Docker image and automatically prefills the "Path" field with the first Volume that your Docker image exposes. Nice!

As Docker images can't contain .env files, WSP AWS can't prefill the "Environment Variables" field. So, I have to manually specify WORDPRESS_URL.

Or my Docker image can use the WSP's default values, which include DOMAIN_NAME. In my case it does, so I don't need to change anything.

Step 3. Build and Deploy (and Check if It Really Works)

For now, I don't need other options so let me just click the Build and Deploy button and sit back waiting for WSP to build the application, configure the infrastructure, and deploy the built app to the configured infrastructure. It takes about 5 minutes and I will get WooCommerce up and running:

Check Persistency

To be sure that everything works fine, I log in to my WooCommerce instance and change these two products (add an image, change texts, etc). Then I go back to WSP and restart the containers by clicking the Redeploy button. When the container is back online, all my changes are still there. So I consider it works well.

Zero Downtime on Restart/Update/Rollback/etc - How Does It Work?

Note that during a restart my application still works, i.e. the downtime is zero seconds. That is because of the HA infrastructure that WSP has set up.

The load balancer routes the traffic to the working container. So while the new container starts, the old container keeps serving users of my applications. When the new container passes the health checks, the load balancer starts to route the traffic to the new container, and then stops the old one.

As you may have already guessed, if the container stops passing the health checks (i.e. the container is considered down), the new one will automatically start. So even if something goes wrong, the downtime will be minimal (it's because Fargate starts a container in a few seconds). The thing I love most is that I don't have to care about all of this jazz. WSP sets it up and it just works!

Get a Generated Admin Password

"Stop!" - you might say. "How did you log in as the admin if your password was generated randomly?"

OK, OK, let me explain. After my WooCommerce is built and deployed, I go to the Application Logs (they are available only to me) and get the generated admin password. Then I add "/wp-admin" to the URL (this is a standard way to get logged in as admin) and log in with the password from the logs.

Despite the logs are available only for authorized users, I don't recommend using this way for production use. Sure thing, many developers use a technique of this kind for development or even staging of environments, which is why I've shown it here. But please, use the Secrets feature (see above) for production instances. And (of course) use strong passwords.

What's next?

I say I got a High Availability WooCommerce installation, but you need proof of its high availability, don't you?

This is the point of the next article. I'm going to put my website under a stress test. A stress test stands for increasing the load until website goes down. The load pattern looks like this:

  • Get a product card.
  • Get three static files.
  • Wait 2-5 seconds.

I'm going to start with 10 simultaneous users that constantly repeat the pattern, and then increase the number of users again and again. Real users act differently but for testing purposes the load pattern is OK.

What's your guess, how many users will kill my website?

And what is more important, how many users would kill your website?

For the sake of your convenience, I have divided my article into three chapters: