You are here

Fun with Drupal and Symlinks

I happen to have what I think is a pretty ideal multi-site Drupal setup.

A rather annoying problem with Drupal's typical multisite support is that if you are handing sites to various users, they're all running under the same Drupal user, and if one of them wants file or php access, you put each of them at risk for the desires or needs of one single person. This is far from ideal - we want to keep the users separate while retaining the flexibility to give everyone full access to their directory structure.

I have two drupal users, drupal6 and drupal7, which act as repositories for their respective codebases. Each of them have custom skeleton directories built on top of them, and scripts to help automate rapid user setup.

drupal7@trancephalon:~$ ls -l
lrwxrwxrwx  1 drupal7 drupal7      10 Jan  6 06:50 core -> drupal-7.0
drwxr-xr-x  9 drupal7 drupal7    4096 Jan  6 07:01 drupal-7.0
drwxr-xr-x 19 drupal7 drupal7    4096 Jan  8 04:50 modules
drwxr-xr-x 12 drupal7 drupal7    4096 Jan  8 01:32 themes

To install 7.1, for example, I would just untar it to the home directory and point the core symlink at /home/drupal7/drupal-7.1

root@trancephalon:/etc/skeld7/docs# ls -l
lrwxrwxrwx 1 root root   32 Jan  6 06:58 authorize.php -> /home/drupal7/core/authorize.php
lrwxrwxrwx 1 root root   27 Jan  6 06:59 cron.php -> /home/drupal7/core/cron.php
lrwxrwxrwx 1 root root   28 Jan  6 07:04 includes -> /home/drupal7/core/includes/
lrwxrwxrwx 1 root root   28 Jan  6 06:59 index.php -> /home/drupal7/core/index.php
lrwxrwxrwx 1 root root   30 Jan  6 06:59 install.php -> /home/drupal7/core/install.php
lrwxrwxrwx 1 root root   24 Jan  6 07:04 misc -> /home/drupal7/core/misc/
lrwxrwxrwx 1 root root   27 Jan  6 07:06 modules -> /home/drupal7/core/modules/
lrwxrwxrwx 1 root root   28 Jan  6 07:06 profiles -> /home/drupal7/core/profiles/
-rw-r--r-- 1 root root 1540 Jan  8 08:27 robots.txt
lrwxrwxrwx 1 root root   27 Jan  6 07:07 scripts -> /home/drupal7/core/scripts/
drwxr-xr-x 3 root root 4096 Jan  6 06:54 sites
lrwxrwxrwx 1 root root   26 Jan  6 07:06 themes -> /home/drupal7/core/themes/
lrwxrwxrwx 1 root root   29 Jan  6 06:59 update.php -> /home/drupal7/core/update.php
lrwxrwxrwx 1 root root   29 Jan  6 07:00 xmlrpc.php -> /home/drupal7/core/xmlrpc.php

Under sites is a symlink for default, and sites/all has symlinks to the themes and modules directories above.

I have a simple bash script, d7add.sh

#!/bin/sh
if [ $1 ] ; then
  export USERINI="/home/$1/docs/.user.ini"
  /usr/sbin/adduser --disabled-password --conf /etc/d7user.conf --gecos "" $1
  echo "error_log = "/home/$1/php_errors.log"" > $USERINI
  chmod 640 $USERINI
  chown $1:$1 $USERINI
else
  echo "Usage: d7add.sh username"
fi

That automates part of the site generation process. Someday I'll add a domain name to the command line parameters and have it write out the nginx configuration files and start basic setup, too.

Upgrading between major versions is assisted by another script:

#!/bin/sh
rm ~/docs/cron.php
rm ~/docs/index.php
rm ~/docs/install.php
rm ~/docs/update.php
rm ~/docs/xmlrpc.php
ln -sv /home/drupal7/core/authorize.php ~/docs/authorize.php
ln -sv /home/drupal7/core/cron.php ~/docs/cron.php
ln -sv /home/drupal7/core/index.php ~/docs/index.php
ln -sv /home/drupal7/core/install.php ~/docs/install.php
ln -sv /home/drupal7/core/update.php ~/docs/update.php
ln -sv /home/drupal7/core/xmlrpc.php ~/docs/xmlrpc.php
rm ~/docs/includes
rm ~/docs/misc
rm ~/docs/modules
rm ~/docs/profiles
rm ~/docs/scripts
rm ~/docs/themes
rm ~/docs/sites/default
rm ~/docs/sites/all/modules
rm ~/docs/sites/all/themes
ln -sv /home/drupal7/core/includes/ ~/docs/includes
ln -sv /home/drupal7/core/misc/ ~/docs/misc
ln -sv /home/drupal7/core/modules/ ~/docs/modules
ln -sv /home/drupal7/core/profiles/ ~/docs/profiles
ln -sv /home/drupal7/core/scripts/ ~/docs/scripts
ln -sv /home/drupal7/core/themes/ ~/docs/themes
ln -sv /home/drupal7/core/sites/default/ ~/docs/sites/default
ln -sv /home/drupal7/modules/ ~/docs/sites/all/modules
ln -sv /home/drupal7/themes/ ~/docs/sites/all/themes

Which is obviously run from the user's account.

Known Gotcha: PHP will cache the real location of files for a time period specified in the realpath_cache_ttl configuration variable. This will confuse the piss out of most software when moving between major versions, and can potentially be dangerous when moving between minor versions. Either wait the needed amount of time, or restart your php process accordingly.

Aside from that, however, this makes upgrading and downgrading particularly slick. And the sort of thing you could build nicely into a control panel.

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <abbr> <acronym> <address> <bdo> <blockquote> <del> <hr> <img> <ins> <pre> <q> <sub> <sup> <dl> <dt> <dd> <ul> <ol> <li> <h1> <h2> <h3> <h4> <h5> <h6> <table> <caption> <col> <colgroup> <tbody> <td> <tfoot> <th> <thead> <tr> <b> <big> <cite> <code> <dfn> <em> <i> <kbd> <samp> <small> <strong> <tt> <var>
  • Lines and paragraphs break automatically.
  • To post pieces of code, surround them with <code>...</code> tags. For PHP code, you can use <?php ... ?>, which will also colour it based on syntax.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.