ݺߣ

ݺߣShare a Scribd company logo
Managing 600+ Single Installs
• 26,000+ Students
• 4500+ Faculty and Staff
• Teeny-tiny web team
• Over 600 single site installs
Canada’s Capital University
About
Carleton
michael.corkum@carleton.ca
@mikecorkum
How did we get here?
How It
Started
michael.corkum@carleton.ca
@mikecorkum
Y U NO
MULTI
SITE?
michael.corkum@carleton.ca
@mikecorkum
The
Rogue
michael.corkum@carleton.ca
@mikecorkum
Function
Of Doom!
michael.corkum@carleton.ca
@mikecorkum
echo_text(‘What am I doing?’);
When you feel bad about your skill
level, remember that someone
thought this was a good idea…
Function
Of Doom!
michael.corkum@carleton.ca
@mikecorkum
echo_text(‘What am I doing?’);
When you feel bad about your skill
level, remember that someone
thought this was a good idea…
function echo_text( $text ) {
echo $text;
}
When I
Started
michael.corkum@carleton.ca
@mikecorkum
• Manual updates to plugins and core
via FTP
• Random plugins
• Simple architecture
• No version control
Total time to update: 5-7 days
Goals
are fun…
michael.corkum@carleton.ca
@mikecorkum
Better network architecture
Make updates fast and easy
Make all sites portable
Track site information
When I
Started
michael.corkum@carleton.ca
@mikecorkum
Sometimes real life isn’t
cutting edge…
Network Overview
Network
Overview
michael.corkum@carleton.ca
@mikecorkum
Updating Code
Updates
michael.corkum@carleton.ca
@mikecorkum
ln -s
michael.corkum@carleton.ca
@mikecorkum
https://2016.wpcampus.org/schedule/introducing-wordpress-multitenancy/
ln -s
michael.corkum@carleton.ca
@mikecorkum
https://2016.wpcampus.org/schedule/introducing-wordpress-multitenancy/
ln -s
michael.corkum@carleton.ca
@mikecorkum
https://2016.wpcampus.org/schedule/introducing-wordpress-multitenancy/
Huh?
michael.corkum@carleton.ca
@mikecorkum
The term "software multitenancy" refers
to a software architecture in which a
single instance of software runs on a
server and serves multiple tenants. A
tenant is a group of users who share a
common access with specific privileges
to the software instance.
WP Folder
Theme Folder
Plugin Folder
SERVER ROOT
/wp
/wp-content/themes
/wp-content/plugins
INSTALL
/wp
/wp-content/themes
/wp-content/plugins
INSTALL
Huh?
michael.corkum@carleton.ca
@mikecorkum
What’s a Multitenancy?
Each
Install
michael.corkum@carleton.ca
@mikecorkum
index.php
Config File
WordPress (symlink)
Themes (symlink)
Plugins (symlink)
Each
Install
michael.corkum@carleton.ca
@mikecorkum
index.php
Config File
WordPress (symlink)
Themes (symlink)
Plugins (symlink)
Case study: Carleton University – managing 600+ single installs
Code
Updates
michael.corkum@carleton.ca
@mikecorkum
https://roots.io/using-composer-with-wordpress/
MySQL
MySQL:
Always
Down
michael.corkum@carleton.ca
@mikecorkum
MySQL:
Always
Down
michael.corkum@carleton.ca
@mikecorkum
https://github.com/stuttter/ludicrousdb
$wpdb->add_database(array(
'host' => 'localhost',
'user' => 'user',
'password' => 'password',
'name' => ‘db_name',
'write' => 1,
'read' => 0,
));
$wpdb->add_database(array(
'host' => 'localhost',
'user' => 'user',
'password' => 'password',
'name' => ‘db_name',
'write' => 0,
'read' => 1,
'timeout' => 0.2,
));
https://wordpress.org/plugins/hyperdb/
Portable Sites
Dynamic
Config
michael.corkum@carleton.ca
@mikecorkum
URLs
define( 'CURRENT_HOST', $_SERVER['HTTP_HOST'] );
define( 'WP_HOME', 'https://' . CURRENT_HOST );
define( 'WP_SITEURL', 'https://' . CURRENT_HOST . '/wp' );
if ( CURRENT_HOST !== PRODUCTION_CURRENT_SITE ) {
ob_start( function ( $page ) {
return str_replace(
array(
PRODUCTION_CURRENT_SITE,
STAGING_CURRENT_SITE,
DEV_CURRENT_SITE,
LOCAL_CURRENT_HOST,
),
CURRENT_HOST,
$page
);
});
}
https://scotty-t.com/2012/01/18/wordpress-in-dev-qa-and-prod/
define( 'PRODUCTION_CURRENT_SITE', 'carleton.ca/dev' );
define( 'STAGING_CURRENT_SITE', 'stage.carleton.ca/dev' );
define( 'DEV_CURRENT_SITE', 'dev.carleton.ca/dev' );
define( 'LOCAL_CURRENT_HOST', 'local.carleton.ca/dev' );
Dynamic
Config
michael.corkum@carleton.ca
@mikecorkum
Differences per environment
$is_staging = ( STAGING_CURRENT_SITE === CURRENT_HOST );
$is_dev = ( DEV_CURRENT_SITE === CURRENT_HOST );
$is_local = ( LOCAL_CURRENT_HOST === CURRENT_HOST );
$wp_debug = false;
$wp_debug_log = false;
$wp_cache = true;
$is_redis_disabled = false;
if ( $is_staging ) {
$wp_debug = true;
$wp_debug_log = true;
$wp_cache = true;
$is_redis_disabled = false;
} elseif ( $is_dev || $is_local ) {
$wp_debug = true;
$wp_debug_log = true;
$wp_cache = false;
$is_redis_disabled = false;
}
define( 'WP_DEBUG', $wp_debug );
define( 'WP_DEBUG_LOG', $wp_debug_log );
define( 'WP_DEBUG_DISPLAY', $wp_debug_display );
define( 'WP_CACHE', $wp_cache );
define( 'WP_REDIS_DISABLED', $is_redis_disabled );
Dynamic
Config
michael.corkum@carleton.ca
@mikecorkum
Databases
$database_config = 'prod.php';
if ( $is_staging ) {
$database_config = 'staging.php';
} elseif ( $is_dev ) {
$database_config = 'dev.php';
} elseif ( $is_local ) {
$database_config = 'local.php';
}
require_once( $database_config );
$wpdb->add_database(array(
'host' => DB_PROD_HOST,
'user' => DB_PROD_USER_NAME,
'password' => DB_PROD_USER_PASS,
'name' => DB_PROD_USER_TABLE_PASS,
'write' => 1,
'read' => 0,
));
define( 'DB_PROD_HOST', 'db.carleton.ca' );
define( 'DB_PROD_USER_NAME', 'username' );
define( 'DB_PROD_USER_PASS', 'password' );
define( 'DB_PROD_USER_TABLE', 'table_name' );
Dynamic
Config
michael.corkum@carleton.ca
@mikecorkum
.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^composer.(lock|json)$ - [F,L]
RewriteRule ^composer.dev.(lock|json)$ - [F,L]
RewriteRule ^vendor/.*$ - [F,L]
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{ENV:URI} ^$
RewriteRule ^(.*)$ - [ENV=URI:$1]
RewriteCond %{ENV:BASE} ^$
RewriteCond %{ENV:URI}::%{REQUEST_URI} ^(.*)::(.*?)1$
RewriteRule ^ - [ENV=BASE:%2]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . %{ENV:BASE}index.php [L,QSA]
</IfModule>
Update
Time
20 Seconds Per Server
michael.corkum@carleton.ca
@mikecorkum
Tracking Installs
Site
Manager
michael.corkum@carleton.ca
@mikecorkum
Site
Manager
michael.corkum@carleton.ca
@mikecorkum
What’s Next?
What’s
Next?
michael.corkum@carleton.ca
@mikecorkum
MOAR SYMLINKS!!!!!!!!
Simplification of Multitenancy
Continuous Integration
Ravens Design System
THANK YOU!

More Related Content

Case study: Carleton University – managing 600+ single installs