community.aegirproject.org
Injecting into site vhosts
Aegir provides some hook functions in its API, one of which allows you to inject extra configuration snippets into your Apache vhost files for sites.
When would I want to do this?
A good example for this is when you may need to inject a custom Rewrite rule that goes beyond what the Aegir Aliases 'redirection' feature provides.
Or, perhaps you have to inject some htpasswd mod_auth password protection for your site, or perhaps a CustomLog definition.
Typically you'd just add what you need to the vhost file, but the problem is that Aegir manages these vhosts, and on every Verify task, will rewrite the config from a template, blowing away your changes in the process. Ouch!
Fortunately there is a very easy and elegant solution to this problem to save your configurations persistently across Verify tasks and the like, by means of invoking the Provision hook provision_apache_vhost_config()
A simple example
In this example I'll inject a simple 'ErrorLog' apache definition into a vhost to save the site error logs to a file.
- Create a file in
~aegir/.drush
calledmig5.drush.inc
- Add this snippet of PHP to the file:
<?php
function mig5_provision_apache_vhost_config($uri, $data) {
return "ErrorLog /var/aegir/" . $uri . ".error.log";
} - Install a site or verify an existing one
Check your site's vhost config file (in /var/aegir/config/server_master/apache/vhost.d/
) and you'll see the line has been injected into the '#Extra configuration' area of the vhost
<VirtualHost *:80>
DocumentRoot /var/aegir/hostmaster-HEAD
ServerName 1.mig5-forge.net
SetEnv db_type mysqli
SetEnv db_name 1mig5forgenet
SetEnv db_user 1mig5forgenet
SetEnv db_passwd X7KzsFhxhp
SetEnv db_host tardis
SetEnv db_port 3306
# Extra configuration from modules:
ErrorLog /var/aegir/1.mig5-forge.net.error.log
# Error handler for Drupal > 4.6.7
<Directory "/var/aegir/hostmaster-HEAD/sites/1.mig5-forge.net/files">
SetHandler This_is_a_Drupal_security_line_do_not_remove
</Directory>
</VirtualHost>
It's that simple! You can see that via the hook, we pass $uri and the drush data to the function, allowing me to abstract the site url so that each site will get its own error log. You could do extra PHP conditionals to ensure certain data only gets inserted into certain sites of a specific name.
To inject multiple lines instead of one, use an array, i.e
<?php
function mig5_provision_apache_vhost_config($uri, $data) {
return array("ErrorLog /var/aegir/" . $uri . ".error.log", "LogLevel warn");
}
The key point of this is that the file ~aegir/.drush/mig5.drush.inc
file will never be touched by Aegir, so you can rest assured your changes will be respected.
- Login or register to post comments
- Print entire section
- Talk
Overriding site-specific PHP values
Sometimes it is useful to override certain PHP values on a per-site basis, but changes to php.ini
are generally server-wide. Depending on the value you want to override, a couple of options present themselves.
First, let's consider where PHP values can be changed. http://www.php.net/manual/en/ini.list.php lists php.ini
directives, and under the "Changeable" column, indicates where a configuration setting may be set. If your value shows either PHP_INI_USER
or PHP_INI_ALL
, then the easiest way to change this value would be using ini_set()
in a local.settings.php
:
<?php
@ini_set('memory_limit', '128M');
?>
On the other hand, if the changes mode is either PHP_INI_PERDIR
or PHP_INI_SYSTEM
, php_ini()
won't work. In this case, the solution is to inject the value into the vhost. Since vhosts are managed by Aegir, manually adding an override to /var/aegir/config/server_master/apache/vhost.d/<uri>
would get blown away the next time that the site is verified.
As described in Injecting into site vhosts, we can inject values into vhosts using a Drush hook. For example, to raise the file upload size limit on http://ergonlogic.com, I added the following code in /var/aegir/.drush/ergonlogiccom.drush.inc
:
<?php
function ergonlogiccom_provision_apache_vhost_config($uri, $data) {
if ($uri == "ergonlogic.com") {
drush_log("Overriding PHP file size values. See .drush/ergonlogiccom.drush.inc");
return array("php_value upload_max_filesize 100M", "php_value post_max_size 200M");
}
}
?>
This results in the insertion of the following lines into /var/aegir/config/server_master/apache/vhost.d/ergonlogic.com
:
php_value upload_max_filesize 100M
php_value post_max_size 200M
Also, in the verify task log I get the following informative message:
Overriding PHP file size values. See .drush/ergonlogiccom.drush.inc
One challenge this technique may present is inspecting the values of the parameters passed into this function. It appears that the Hostmaster site doesn't get bootstrapped, and so common debugging tools (such as devel.module's dd()) aren't available. However drush_log() is, and when called, will push arbitrary messages back into your Aegir site's verify task log.
So sticking the following into the function above can help:
<?php
drush_log("$uri: " . print_r($uri));
?>
#1
Hello, I am trying to find a way to redirect all users of my website to https instead of http. I am trying to follow the "More Advanced example" at the bottom of the documentation, but I really don't have much php experience so I don't want to mess it up. Would this work to redirect all access from the http version to https instead? I have a feeling I might need something different in the $rval[] = "RewriteCond %{HTTPS_HOST} !^example.com$ [NC]"; line, to make it about the https instead of example.com, but I'm not sure. Any thoughts or help? Thank you!
<?php
function aliasredirects_provision_apache_vhost_config($uri, $data) {
// the uri to check here is the name of the site in Aegir
if ($uri === "example.com") {
$rval[] = "";
$rval[] = "# Forces redirect to one uri";
$rval[] = "RewriteEngine On";
// if not https
$rval[] = "RewriteCond %{HTTPS_HOST} !^example.com$ [NC]";
// rewrite to example.com with a 301 redirect
$rval[] = "RewriteRule ^(.*)$ https://example.com$1 [R=301,L]";
$rval[] = "";
return $rval;
}
}
?>
#2
I think I've gotten closer with some more research. This is what i have now:
<?php
function aliasredirects_provision_apache_vhost_config($uri, $data) {
// the uri to check here is the name of the site in Aegir
if ($uri === "example.com") {
$rval[] = "";
$rval[] = "RewriteEngine On";
$rval[] = "RewriteCond %{HTTPS} !=on";
$rval[] = "RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]";
$rval[] = "";
return $rval;
}
}
?>
#3
OK! This works now! Just make sure that your file is called aliasredirects.drush.inc (the first part needs to be the same as your function, at least that is what seemed to get it to work for me).
<?php
function aliasredirects_provision_apache_vhost_config($uri, $data) {
// the uri to check here is the name of the site in Aegir
if ($uri === "example.com") {
$rval[] = "";
$rval[] = "RewriteEngine On";
// check to see if https is not on first
$rval[] = "RewriteCond %{HTTPS} !=on";
// rewrite to https with a 301 redirect
$rval[] = "RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]";
$rval[] = "";
return $rval;
}
}
?>
#4
We have (at the moment unstable) modules to allow custom entries in settings.php and vhosts from the site settings page.
See: Hosting injections
and: Provision hosting injections