Introduction
In part 1, we went over the architecture and layout of the servers that host websites for me. As the servers come and go as needs require, creating new websites can be challenging. It also becomes very time consuming as you add more servers or roles to the cluster.
The entire Github repo for this cluster is now public! You can view it or grab a copy here.
Requirements
- An understanding of the cluster and its parts, available in Part 1 of this series, available Here.
- An understanding of PHP website hosting.
The Playbook
We will be going over the NewWordpressSite.yml
playbook, available here.
Getting Started
|
|
This section is really easy, it just tells Ansible that the playbook is going to use the first database master server and the first Wordpress admin server.1 The database syncs in real time, so as data is created on the master, the information will be on the other DB servers before the playbook finishes. The playbook will be placing system files and become
makes that easier.
Create the Database
|
|
All of these tasks will happen on the database master server. The playbook first asks for database information: Username, Password, and Database name. If you are using a non interactive session (AWX, Semaphore, cron) you can pass these with --extra-vars
.2
Once the playbook has that information it creates the database and then grants the correct user permissions. The web server will need this information later but we run into an issue. Ansible does not persist variables between hosts in a playbook. I got around this by storing this information as an extra host, it will only exist while the playbook is running.
Web Server Configuration
|
|
For a standard “normal” website, 2 subdomains point to the website, WWW
and @
or blank. The playbook asks for 2 domains to account for this.
If this is the case you put domain.com
for the first question, and www.domain.com
for the second question. If the website exists on a subdomain, like blog
, you answer the first question with blog.domain.com
and leave domain 2 blank. I always have WWW set as a CNAME of @ at the DNS level, but leave this as a backup for flexibility.
The playbook is configuring the web servers , but uses the Wordpress Admin server to do it. This ensures that the public facing web nodes ONLY SERVE WEBSITES. The domain is used as the folder name in our web directory and Nginx virtual host name. The Nginx virtual host uses a template file for domain information.
Remember that this is our shared storage so its already available for all of the web servers to use. We use the domain as that makes maintenance and updates easier(More info in a future blog post).
Just like the Database step, the playbook adds more info to the “dummy” host to use later.
Wordpress Install and Configuration
|
|
This section will use all of the information that was added to the extra host. The playbook downloads the latest version of Wordpress and places it in the websites web root using the domain
variable.
A site specific WP-Config file is generated and placed in the correct location. Wordpress sites need site specific specific Auth Keys and Salts for security. The template generates those as the file is created.
The wordpress sites use Hyper-DB to fully use the highly available database set. The playbook places a db.php file , which is Hyper DB. Then a db-config.php file is placed, containing connection info for the second database. Username, Password, and Name information is the same as the master db host, so we reference that in this file.
Next a Wordpress specific robots.txt file is generated and placed at the web root.
Cleanup
|
|
Now that all the files are in place, the playbook sets permissions on all of them to ensure they are correct. Or you could have issues.
Next a wordpress cron entry is created. Triggering it manually is much faster than having Wordpress check on every page load. To do that a random number is generated, this will be the minute the cron runs every hour.
Spreading the entries out prevents them all happening at once on the WP-Admin server. An entry is created in a master cron file on the shared storage. This file is used by the Wordpress Admin server to keep its cron list up to date.
Finishing up the Web Servers
|
|
Every Wordpress site on the cluster uses a FastCGI based cache to speed up page loads considerably. A directory is needed for this cache. Putting it on the local NVNME storage of the web nodes maximizes its speed. This also reduces strain on the shared storage, keeping it fast. The playbook creates that needed directory and sets correct permissions.
Nginx does not actively watch config directories for files. It checks when it is Started, Restarted, or Reloaded. The playbook created all of the needed files but the web servers do not see them yet, and they are not being used. The playbook reloads Nginx so it picks up the new website without dropping existing traffic.
Finishing up the Wordpress Admin Servers
|
|
Caching is disabled for any page the Wordpress Admin servers would serve, so creating a cache directory is not needed. The cron file the playbook added to is pushed into the Wordpress Admin server’s cron list. Like the Web servers, Nginx has to be reloaded to see the new website.
Next Steps
Once the playbook finishes, open the primary domain in your browser of choice. The domain was already pointed at the cluster’s floating IP, so the Wordpress install page loads. Follow the prompts and log into /wp-admin
for your new site.
Final Notes
When I just used a single Web node and single Database node, creating a new Wordpress site took 30 minutes to 1 hour. Remembering comments, switching back and forth, copy/pasting, it ate up my time.
On average this playbook takes 3 minutes to run and does a better job than I did manually, on a much more complex cluster. This single playbook alone has saved me over 80 hours, in 3 years.
-
Computers start counting at 0 ↩︎