Stephen Ostermiller's Blog

Install WordPress from apt on Ubuntu to host multiple blog domains

I wanted to run WordPress on my Ubuntu webserver such that:

  • WordPress gets installed and updated through apt
  • It runs multilpe sites that each have their own configuration, plugins and themes

Installing WordPress through apt is the easy part:

sudo apt install wordpress

That creates:

- `/etc/wordpress` which is where it expects `config-<host>.php` files
- `/usr/share/wordpress` where all the files that power WordPress live.

You can create virtual hosts under Apache with DocumentRoot /usr/share/wordpress, but then all of those sites share the same wp-content and .htaccess files. Each site won't have its own plugins, themes, and custom redirects. I needed a way to create a separate document root for each site that use most, but not all, of the common files from /usr/share/wordpress.

I ended up created a document root directory for each site like /var/www/blog.example.com where most of the files link to /usr/share/wordpress:

www-data .htaccess
root     index.php -> /usr/share/wordpress/index.php
root     readme.html -> /usr/share/wordpress/readme.html
root     wp-activate.php -> /usr/share/wordpress/wp-activate.php
root     wp-admin -> /usr/share/wordpress/wp-admin
root     wp-blog-header.php -> /usr/share/wordpress/wp-blog-header.php
root     wp-comments-post.php -> /usr/share/wordpress/wp-comments-post.php
root     wp-config.php -> /usr/share/wordpress/wp-config.php
root     wp-config-sample.php -> /usr/share/wordpress/wp-config-sample.php
www-data wp-content
root     wp-cron.php -> /usr/share/wordpress/wp-cron.php
root     wp-includes -> /usr/share/wordpress/wp-includes
root     wp-links-opml.php -> /usr/share/wordpress/wp-links-opml.php
root     wp-load.php -> /usr/share/wordpress/wp-load.php
root     wp-login.php -> /usr/share/wordpress/wp-login.php
root     wp-mail.php -> /usr/share/wordpress/wp-mail.php
root     wp-settings.php -> /usr/share/wordpress/wp-settings.php
root     wp-signup.php -> /usr/share/wordpress/wp-signup.php
root     wp-trackback.php -> /usr/share/wordpress/wp-trackback.php
root     xmlrpc.php -> /usr/share/wordpress/xmlrpc.php

I created a script to do all that symlinking for me

#!/bin/sh

set -e

directory="$1"

if [ "z$directory" == "z" ]
then
    echo "Specify a directory as an argument"
    exit 1
fi

if [ ! -d "$directory" ]
then
    echo "Not a directory $directory"
    exit 1
fi

if [ ! -e "$directory/wp-content" ]
then
    cp -r /usr/share/wordpress/wp-content "$directory"
    chown -R www-data "$directory/wp-content"
fi

for file in /usr/share/wordpress/*
do
    name="${file##*/}"
    if [ ! -e "$directory/$name" ]
    then
        ln -s "$file" "$directory/$name"
    fi
done

if [ ! -e "$directory/.htaccess" ]
then
    touch "$directory/.htaccess"
    chown www-data "$directory/.htaccess"
fi

The config file for each site is a copy of the sample that gets edited with your database info:

sudo cp /etc/wordpress/config-localhost.php /etc/wordpress/config-blog.example.com.php

You need to create a virtual host for the site under Apache. Like /etc/apache2/sites-available/blog.example.com.conf:

<VirtualHost *:80>
    Servername blog.example.com
    DocumentRoot /var/www/blog.example.com/
    <Directory /var/www/blog.example.com/>
        Options +ExecCGI +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Then enable the virtual host and reload the server:

sudo a2ensite blog.example.com && sudo service apache2 reload

Leave a comment

Your email address will not be published. Required fields are marked *