Configuration and installation of mediawiki on FreeBSD

Introduction

Mediawiki is a PHP web application for running a wiki. Probably the most well-known example of a wiki is the online encyclopedia wikipedia. My goal for this project is to learn how to set up mediawiki and to make a prototype wiki for my workplace.

To run mediawiki, several things are required;

All programs are installed using the excellent FreeBSD ports system.

Installing and configuring the nginx webserver

Since the article contents are retrieved from a database by a PHP program, the main purpose of the webserver is to re-write URIs from a form that looks good to what the mediawiki application expects, and then hand them over to the PHP process. So URI rewriting is arguably the most important tast of the server.

For this reason, and because it has a small memory footprint and it is fast, the nginx webserver is chosen. This has a lot of modules that can be compiled in available. Only the ones that were enabled are shown below.

# cd /usr/ports/www/nginx
# make install clean
 ┌────────────────────────────────────────────────────────────────────┐
 │                    Options for nginx 0.8.53_1                      │     
 │ ┌────────────────────────────────────────────────────────────────┐ │     
 │ │[X] FILE_AIO                  Enable file aio                   │ │     
 │ │[X] HTTP_MODULE               Enable HTTP module                │ │     
 │ │[X] HTTP_CACHE_MODULE         Enable http_cache module          │ │     
 │ │[X] HTTP_DAV_MODULE           Enable http_webdav module         │ │     
 │ │[X] HTTP_REWRITE_MODULE       Enable http_rewrite module        │ │     
 │ │[X] HTTP_STATUS_MODULE        Enable http_stub_status module    │ │     
 ├─└────────────────────────────────────────────────────────────────┘─┤     
 │                       [  OK  ]       Cancel                        │     
 └────────────────────────────────────────────────────────────────────┘     

The “Options” screen above only shows the activated options. All other options are off.

On my machine, I’ve configured two virtual sersers: www.erewhon.net and wiki.erewhon.net. In /etc/hosts and in my [named][] configuration I’ve made both resolve to the IP address of my desktop. The first is for showing my normal static website.

Nginx wants to use /var/tmp/nginx, and the FreeBSD startup script complains when it doesn’t exist. I use periodic(8) to keep the temporary directories clean, so I’ve had to add an exception for this directory to /etc/periodic.conf;

daily_clean_tmps_enable="YES"
daily_clean_tmps_dirs="/tmp /var/tmp"
daily_clean_tmps_ignore="$daily_clean_tmps_ignore nginx"

Below is the configuration file that I’m using for nginx.

# -*- text -*-
# file: /usr/local/etc/nginx/nginx.conf
# host: slackbox.erewhon.net
# Time-stamp: <2010-11-28 19:05:05 rsmith>
# $Id: e99488e958fba97a51d553369f9c1ed557b93ad8 $

user  www www;
worker_processes  1;

error_log  /var/log/nginx/error.log  info;

events {
    worker_connections  512;
}

http {
    include mime.types;
    default_type application/octet-stream;
    access_log /var/log/nginx/localhost.access.log;
    sendfile on;
    keepalive_timeout 65;
    server {
        server_name www.erewhon.net;
        root /home/rsmith/WWW;
        index index.html;
        location ~ \.git {
            deny all;
        }
        location ~ tools {
            deny all;
        }
        error_page  404 /404.html;
                location = /404.html {
            root /usr/local/www;
        }
        # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root /usr/local/www/nginx-dist;
        }
    }
    server {
        server_name wiki.erewhon.net;
        root /home/www/mediawiki;
        if (!-e $request_filename) {
            rewrite ^/wiki/?$ /index.php?title=Main_Page last;
            rewrite ^/wiki/(.+)$ /index.php?title=$1 last;
        }
        location ~ \.php {
            include fastcgi_params;
            fastcgi_pass  127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }
}

Installing and configuring PHP

Install the latest version from ports. As with nginx, only the chosen options are shown.

# cd /usr/ports/lang/php5
# make install clean
 ┌────────────────────────────────────────────────────────────────────┐
 │                     Options for php5 5.3.3_2                       │
 │ ┌────────────────────────────────────────────────────────────────┐ │
 │ │ [X] CLI        Build CLI version                               │ │
 │ │ [X] CGI        Build CGI version                               │ │
 │ │ [X] FPM        Build FPM version (experimental)                │ │
 │ │ [X] SUHOSIN    Enable Suhosin protection system                │ │
 ├─└────────────────────────────────────────────────────────────────┘─┤
 │                       [  OK  ]       Cancel                        │
 └────────────────────────────────────────────────────────────────────┘

PHP is configured with the /usr/local/etc/php.ini file. This was begun by stripping the comments (which start with ‘;’) from the file /usr/local/etc/php.ini-production. Then the following directives were changed or added;

error_log = /var/log/php-errors.log
default_charset = "utf-8"
date.timezone = Europe/Amsterdam
url_rewriter.tags = "a=href,area=href,frame=src,input=src"

The behavior of the FastCGI Process Manager (php-fpm) is controlled by the file /usr/local/etc/php-fpm.conf. This was started by removing the comments from the supplied default version, and changing the following;

error_log = /var/log/php-fpm.log
log_level = notice
+listen.allowed_clients = 127.0.0.1
pm.max_children = 30
pm.start_servers = 5

Installing and configuring postgresql

Install the latest version from ports;

# cd /usr/ports/databases/postgresql90-server
# make install clean
 ┌────────────────────────────────────────────────────────────────────┐
 │              Options for postgresql-server 9.0.1_2                 │
 │ ┌────────────────────────────────────────────────────────────────┐ │
 │ │[X] XML               Build with XML data type (server)         │ │
 │ │[X] TZDATA            Use internal timezone database (server)   │ │
 │ │[X] GSSAPI            BUild with GSSAPI support                 │ │
 │ │[X] ICU               Use ICU 3.x for unicode collation (server)│ │
 │ │[X] INTDATE           Builds with 64-bit date/time type (server)│ │
 ├─└────────────────────────────────────────────────────────────────┘─┤
 │                       [  OK  ]       Cancel                        │
 └────────────────────────────────────────────────────────────────────┘
# /usr/ports/databases/postgresql90-client
# make install clean

The installation procedure will create a user and group called pgsql in /etc/master.passwd and /etc/group. If you use revision control for your configuration files, check in these changes.

Next I added the following to /etc/rc.conf.

postgresql_data="/home/pgsql/"
postgresql_flags="-w -s -m fast"
postgresql_initdb_flags="--encoding=utf-8 --lc-collate=C"
postgresql_class="default"

Now it is time to create the directory for and initialize the databases.

# mkdir /home/pgsql
# chown pgsql:pgsql /home/pgsql
# /usr/local/etc/rc.d/postgresql oneinitdb

The configuration file for this database is found in /home/pgsql/postgresql.conf. The access control to the server is configured by /home/pgsql/pg_hba.conf. I used the default postgresql.conf but stripped out all the comment lines.

The access control /home/pgsql/pg_hba.conf needed to be updated, because by default all local connections to the database server are trusted, which is not a good thing from a safety perspective:

# file: /home/pgsql/pg_hba.conf
# host: slackbox.erewhon.net
# Time-stamp: <2010-11-28 15:27:51 rsmith>
# $Id: 2880d43e48ea5337b2a30c2bbb705a37150c99ea $
# TYPE  DATABASE        USER            CIDR-ADDRESS            METHOD
local   wikidb      wikiuser                md5
local   postgres    pgsql                   trust
# IPv4 local connections:
host    wikidb      wikiuser    127.0.0.1/32        md5

After that it was time to set up the roles and databases. Fire up the postgres daemon, and then use psql as shown below;

# /usr/local/etc/rc.d/postgresql onestart
> psql postgres pgsql
postgres=# alter role pgsql with password 'XXXXXXXXXXXX';
postgres=# create role wikiuser with login password 'YYYYYYYYYY';
postgres=# create database wikidb with owner wikiuser;
postgres=# \q

The first order of business is to set a password for the pgsql user. This user has complete power, so we should not let anybody just log in as this user.

Then we create the role wikiuser, and the database wikidb. We set a password for wikiuser. Write down the usernames and passwords. You’ll need them when setting up the wiki!

Remember to change the access to the postgres database from trust to md5 in /home/pgsql/pg_hba.conf at this point! Access to this database should be restricted to those that know the password.

Starting up the prequisites for mediawiki

Normally daemons in FrssBSD are started from /etc/rc.conf. But since I might not want to start them up every time, I’m using the following sequence of commands to start up mediawiki;

# /usr/local/etc/rc.d/postgresql onestart
# /usr/local/etc/rc.d/php-fpm onestart
# /usr/local/etc/rc.d/nginx onestart

Stopping them is done in the opposite order and using the onestop argument instead.

Configuring mediawiki

Initial site creation

Surf to http://wiki.erewhon.net/mediawiki/config/index.php. Fill in the fields on the form. Choose a good random password for the wiki administrator. Fill in the database user wikiuser, the password you specified when you configured the database and the database name wikidb, and press the ‘Install’ button.

Now move the file config/LocalSettings.php to its parent directory, and add the following four lines to the end of the file. These are necessary to make the site work correctly.

$wgScriptPath       = "";
$wgArticlePath      = "/wiki/$1";  # Virtual path. 
$wgUsePathInfo = true;        # Enable use of pretty URLs
$wgStylePath        = "/skins";

Also, change $wgEnableUploads to true.

Additional configuration

After doing some reading, I added the following extra settings to /home/www/mediawiki/LocalSettings.php;

# Allow upload of PDF files.
$wgFileExtensions[] = 'pdf';
# Automatically promote users to confirmed.
$wgAutopromote = array(
    'autoconfirmed' => array( '&',
        array( APCOND_EDITCOUNT, &$wgAutoConfirmCount ),
        array( APCOND_AGE, &$wgAutoConfirmAge ),
    ),
    'emailconfirmed' => APCOND_EMAILCONFIRMED,
);
# Prevent new user registrations except by sysops.
$wgGroupPermissions['*']['createaccount'] = false;
# Prevent anonymous editing.
$wgGroupPermissions['*']['edit'] = false;
# Anonymous users can't create pages
$wgGroupPermissions['*']['createpage'] = false;

Adding users

I added a normal user before changing the configuration as shown above. Logging in as the administrator, I added administrator rights to my new user-id.