Installing Nikola on Ubuntu

Nikola is a static site and blog generator written in Python that I’ve been using for a good while now. This blog post describes how to install Nikola on Ubuntu 14.04 or newer. Now, this may look like a long winded way to install Nikola, given that .deb package exist, but in my opinion it is the correct way to install Nikola on Ubuntu.

Installing Python

First you’ll need Python.

sudo apt-get install cython3 libpython3.4 python3.4 python3.4-dev python3.4-minimal

Now install the Python “package” management utilities.

sudo apt-get install python-setuptools python-virtualenv python-pip virtualenvwrapper

The Snakepit

Create a “Snakepit” directory for storing all the virtualenvs.

  mkdir ~/Snakepit

Create a virtualenv for Nikola

The following will create a new virtualenv called nikola based on Python 3.4.

virtualenv -p /usr/bin/python3.4 ~/Snakepit/nikola-773

Working on a virtualenv

To activate the virtualenv do the following.

source ~/Snakepit/nikola-773/bin/activate

Your shell prompt will change while a virtualenv is being worked on to indicate which virtualenv is currently active.

While working on a virtualenv you can pip install what you need or manually install any Python libraries safe in the knowledge you will not adversely damage any other virtualenvs or the global packages in the process. Very useful for developing a new branch which may have different library requirements than the master/head.

When you are finished working in a virtualenv you can deactivate it by simply executing deactivate.

Install Nikola requirements

Nikola requires some additional packages.

sudo apt-get install liblcms2-dev libfreetype6-dev libjpeg8-dev \
libopenjp2-7-dev libtiff5-dev libwebp-dev libxslt1-dev libxml2-dev \
libyaml-dev libzmq-dev zlib1g-dev

Some of the content optimisation filters require additional packages.

sudo apt-get install closure-compiler jpegoptim optipng yui-compressor

Install Tidy 5. (optional)

sudo apt-get -y remove libtidy-0.99-0 tidy
wget -O /tmp/tidy5.deb
sudo dpkg -i /tmp/tidy5.deb
sudo ln -s /usr/bin/tidy /usr/local/bin/tidy5
rm /tmp/tidy5.deb

What are these requirements for?

The following are required to build pillow, the Python imaging library.

  • liblcms2-dev
  • libfreetype6-dev
  • libjpeg8-dev
  • libopenjp2-7-dev
  • libtiff5-dev
  • libwebp-dev
  • zlib1g-dev

The following are required to build lxml, a Python XML library.

  • libxml2-dev
  • libxslt1-dev

The following are required to build python-coveralls.

  • libyaml-dev

The following are required to build pyzmq.

  • libzmq-dev

Install Nikola

First install Cython, which will ensure some of the packages required by Nikola use all the available optimisations.

pip install --upgrade Cython

Install all of Nikola.

pip install --upgrade "Nikola[extras,tests]"

Create a site

After installing Nikola, you should create a site. A site is a collection of all assets needed to render your website, including configuration, posts, pages, images, and all other files and customizations.

To create a site, you need to run:

nikola init <directory_name>

A wizard will guide your initial setup The --demo option can be used to populate your site with some example content. If you do not want the wizard, use the --quiet argument.

Nikola is now installed and and initial site is setup. nikola help and the Nikola Handbook will assist you from here.

Installing Willie IRC Bot on Debian

Willie is an IRC bot written in Python that I’ve recently started using. This blog post describes how to install Willie on Debian and as usual I will be using virtualenv to isolate this Python application from the rest of the system.

Installing Python

First you’ll need Python.

sudo apt-get install libpython2.7 python2.7 python2.7-dev python2.7-minimal

The following will also be required to enable all the features Willie supports.

sudo apt-get install enchant python2.7-dev libxslt1-dev libxml2-dev

Remove any apt installed Python packages that we are about to replace. The versions of these packages in the Debian repositories soon get stale.

sudo apt-get purge python-setuptools python-virtualenv python-pip python-profiler

Install pip.

sudo python2.7

Use pip to install virtualenv.

sudo pip install virtualenv --upgrade

The Snakepit

Create a “Snakepit” directory for storing all the Python virtual environments.

mkdir ~/Snakepit

Create a virtualenv for Willie

The following will create a new virtualenv called willie using Python 2.7 as the interpreter.

virtualenv -p /usr/bin/python2.7 ~/Snakepit/willie

Working on a virtualenv

Activate the virtualenv for Willie.

source ~/Snakepit/willie/bin/activate

Your shell prompt will change, something like (willie)[email protected]:~$, while a virtualenv is being worked on to indicate which virtualenv is currently active.

While working on a virtualenv you can pip install what you need or manually install any Python libraries safe in the knowledge you will not upset any other virtualenvs or the global packages in the process. Very useful for developing a new branch which may have different library requirements than the current stable release.

When you are finished working in a virtualenv you can deactivate it by simply executing deactivate.

Install Willie

I’ve decided to use Python 2.7 to run Willie and therefore have to install backports.ssl_match_hostname which is not required if you use Python 3.3.

pip install willie backports.ssl_match_hostname

Additional functionality

Willie has no external dependencies, besides Python. However, some of the modules do have external dependencies. So install the following Python modules so that I can make use of everything Willie can do.

pip install feedparser pytz lxml praw pyenchant pygeoip ipython --upgrade

Configure Willie

I am not going to explain to how to configure Willie because all that good stuff is very well documented by the project.

But for reference, my default.cfg looks something like this:

nick = nicofyourbot
user = nicofyourbot
name = Give You Bot A Name
host =
use_ssl = true
verify_ssl = true
port = 6697
owner = nicofthebotowner
channels = #example
nickserv_password = ************
prefix = \.
timeout = 120

userdb_type = sqlite
userdb_file = /home/username/.willie/willie.db

Willie as a daemon

From this point on I assume you’ve completed the first run configuration of Willie and have .willie/default.cfg in your home directory.

Add the following to /etc/init.d/willie.

# Provides: willie
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Should-Start: $network
# Should-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Willie IRC Bot.
# Description: Start and stops the Willie IRC bot for a given user.

# NOTE! Replace with the user you want to run Willie.

HOMEDIR=$(getent passwd $willie_USER | awk -F: '{print $6}')

startd() {
    if [ -f ${CONFIG} ]; then
        echo "Starting Willie for $willie_USER"
        start-stop-daemon -c $willie_USER -u $willie_USER -x $DAEMON -S -- --config ${CONFIG} --fork --quiet
        echo "Couldn't start Willie for $willie_USER (no $CONFIG found)"

stopd() {
    echo "Stopping Willie for $willie_USER"
    willie_PID=$(pgrep -fu $willie_USER $DAEMON)
    if [ -z "$willie_PID" ]; then
        echo "Willie for USER $willie_USER: not running."
        kill -15 $willie_PID

status() {
    willie_PID=$(pgrep -fu $willie_USER $DAEMON)
    if [ -z "$willie_PID" ]; then
        echo "Willie for USER $willie_USER: not running."
        echo "Willie for USER $willie_USER: running (pid $willie_PID)"

case "$1" in
    start) startd ;;
    stop) stopd ;;
    restart|reload|force-reload) stopd && startd ;;
    status) status ;;
    *) echo "Usage: /etc/init.d/willie {start|stop|reload|force-reload|restart|status}"
       exit 1

exit 0

Set the permissions.

sudo chmod +x /etc/init.d/willie

Check that you can start/stop Willie.

sudo /etc/init.d/willie start
sudo /etc/init.d/willie status
sudo /etc/init.d/willie stop

Add willie to the startup/shutdown sequence.

sudo update-rc.d willie defaults

And that’s it. Willie is now running as a daemon inside a virtualenv.

ZNC IRC proxy

I have been using the BIP IRC proxy that maintains a persistent connection(s) to a list of IRC channels. However, I’ve heard good things about ZNC and decided to give it a try.

The purpose of an IRC proxy, or bouncer, is that you can then point your IRC clients to them to maintain a transparent connection from multiple clients and playback the conversations that took place while you were away.

Installing ZNC

The ZNC package for Debian Wheezy are very old, so I decide to install from source.

Install required packages

We first need to make sure we have all the packages required to build ZNC.

sudo apt-get install build-essential libssl-dev libperl-dev pkg-config

Compile ZNC

Now download and compile ZNC.

tar zxvf znc-1.4.tar.gz
cd znc-1.4
./configure --with-openssl
sudo make install

Create a user

Create a separate ZNC user so that ZNC does not need to run as root:

sudo groupadd znc
sudo adduser --system --home /var/lib/znc --group znc

Configuring ZNC

You can use the interactive wizard to configure ZNC which really help create the initial configuration.

sudo -u znc /usr/local/bin/znc --datadir=/var/lib/znc --makeconf

Here is a transcript of how I answered the initial configuration questions.

[ .. ] Checking for list of available modules...
[ >> ] ok
[ ** ] Building new config
[ ** ]
[ ** ] First let's start with some global settings...
[ ** ]
[ ?? ] What port would you like ZNC to listen on? (1025 to 65535): 7778
[ ?? ] Would you like ZNC to listen using SSL? (yes/no) [no]: yes
[ ?? ] Would you like ZNC to listen using both IPv4 and IPv6? (yes/no) [yes]:
[ .. ] Verifying the listener...
[ >> ] ok
[ ** ] Unable to locate pem file: [/var/lib/znc/znc.pem], creating it
[ .. ] Writing Pem file [/var/lib/znc/znc.pem]...
[ >> ] ok
[ ** ]
[ ** ] -- Global Modules --
[ ** ]
[ ** ] +-----------+----------------------------------------------------------+
[ ** ] | Name      | Description                                              |
[ ** ] +-----------+----------------------------------------------------------+
[ ** ] | partyline | Internal channels and queries for users connected to znc |
[ ** ] | webadmin  | Web based administration module                          |
[ ** ] +-----------+----------------------------------------------------------+
[ ** ] And 10 other (uncommon) modules. You can enable those later.
[ ** ]
[ ?? ] Load global module <partyline>? (yes/no) [no]: yes
[ ?? ] Load global module <webadmin>? (yes/no) [no]: yes
[ ** ]
[ ** ] Now we need to set up a user...
[ ** ]
[ ?? ] Username (AlphaNumeric): yournick
[ ?? ] Enter Password:
[ ?? ] Confirm Password:
[ ?? ] Would you like this user to be an admin? (yes/no) [yes]:
[ ?? ] Nick [yournick]:
[ ?? ] Alt Nick [yournick_]:
[ ?? ] Ident [yournick]:
[ ?? ] Real Name [Got ZNC?]: Your Name
[ ?? ] Bind Host (optional):
[ ?? ] Number of lines to buffer per channel [50]: 1024
[ ?? ] Would you like to clear channel buffers after replay? (yes/no) [yes]:
[ ?? ] Default channel modes [+stn]:
[ ** ]
[ ** ] -- User Modules --
[ ** ]
[ ** ] +--------------+------------------------------------------------------------------------------------------+
[ ** ] | Name         | Description                                                                              |
[ ** ] +--------------+------------------------------------------------------------------------------------------+
[ ** ] | chansaver    | Keep config up-to-date when user joins/parts                                             |
[ ** ] | controlpanel | Dynamic configuration through IRC. Allows editing only yourself if you're not ZNC admin. |
[ ** ] | perform      | Keeps a list of commands to be executed when ZNC connects to IRC.                        |
[ ** ] | webadmin     | Web based administration module                                                          |
[ ** ] +--------------+------------------------------------------------------------------------------------------+
[ ** ] And 21 other (uncommon) modules. You can enable those later.
[ ** ]
[ ?? ] Load module <chansaver>? (yes/no) [no]: yes
[ ?? ] Load module <controlpanel>? (yes/no) [no]: tes
[ ?? ] Load module <controlpanel>? (yes/no) [no]: yes
[ ?? ] Load module <perform>? (yes/no) [no]: yes
[ ?? ] Load module <webadmin>? (yes/no) [no]: yes
[ ** ]
[ ?? ] Would you like to set up a network? (yes/no) [no]:
[ ** ]
[ ?? ] Would you like to set up another user? (yes/no) [no]:
[ .. ] Writing config [/var/lib/znc/configs/znc.conf]...
[ >> ] ok
[ ** ]
[ ** ]To connect to this ZNC you need to connect to it as your IRC server
[ ** ]using the port that you supplied.  You have to supply your login info
[ ** ]as the IRC server password like this: user/network:pass.
[ ** ]
[ ** ]Try something like this in your IRC client...
[ ** ]/server <znc_server_ip> +7778 flexiondotorg:<pass>
[ ** ]And this in your browser...
[ ** ]https://<znc_server_ip>:7778/
[ ** ]
[ ?? ] Launch ZNC now? (yes/no) [yes]: no

Running ZNV as a daemon

Here is a /etc/init.d/znc for Debian based on this installation method:

#! /bin/sh
# Provides:          znc
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: ZNC IRC bouncer
# Description:       ZNC is an IRC bouncer

DESC="ZNC daemon"

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

# Function that starts the daemon/service
    # Return
    #   0 if daemon has been started
    #   1 if daemon was already running
    #   2 if daemon could not be started
    if [ ! -d $PIDDIR ]
        mkdir $PIDDIR
    chown $USER:$GROUP $PIDDIR
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test --chuid $USER > /dev/null || return 1
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --chuid $USER -- $DAEMON_ARGS > /dev/null || return 2

# Function that stops the daemon/service
    # Return
    #   0 if daemon has been stopped
    #   1 if daemon was already stopped
    #   2 if daemon could not be stopped
    #   other if a failure occurred
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME --chuid $USER
    [ "$RETVAL" = 2 ] && return 2
    # Wait for children to finish too if this is a daemon that forks
    # and if the daemon is only ever run from this initscript.
    # If the above conditions are not satisfied then add some other code
    # that waits for the process to drop all resources that could be
    # needed by services started subsequently.  A last resort is to
    # sleep for some time.
    start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON --chuid $USER
    [ "$?" = 2 ] && return 2
    # Many daemons don't delete their pidfiles when they exit.
    rm -f $PIDFILE
    return "$RETVAL"

# Function that sends a SIGHUP to the daemon/service
do_reload() {
    start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME --chuid $USER
    return 0

case "$1" in
    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
    case "$?" in
        0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
        2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
    case "$?" in
        0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
        2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
    log_daemon_msg "Reloading $DESC" "$NAME"
    log_end_msg $?
    log_daemon_msg "Restarting $DESC" "$NAME"
    case "$?" in
        case "$?" in
            0) log_end_msg 0 ;;
            1) log_end_msg 1 ;; # Old process is still running
            *) log_end_msg 1 ;; # Failed to start
        # Failed to stop
        log_end_msg 1
    echo "Usage: $SCRIPTNAME {status|start|stop|reload|restart}" >&2
    exit 3

After you’ve created the script, you must give it the proper permissions to run and add the script to the startup/shutdown sequence.

sudo chmod 755 /etc/init.d/znc
sudo update-rc.d znc defaults

Start the service:

sudo service znc start

Stop the service:

sudo service znc stop

Web configuration

I love that ZNC comes bundled with a web based configuration tool. Just login to to add users, add networks to users and to add channels to networks. Really simple stuff.

IRC client configuration

I use HexChat, but other IRC clients are available. Just add a new Network to HexChat for your ZNC server, use the username, suffixed with the network name you configured in ZNC, and your ZNC password.


I much prefer ZNC to BIP.

  • I really like the web and IRC configuration but I still have the option to configure the config files directly.
  • ZNC is far less cryptic with regard to setting up IRC client connections and user management is much better implemented.
  • When I add a new channel to an existing network in ZNC it automatically appears in my connected clients without the need to restart anything.
  • ZNC’s IRC backlogs don’t have the confusing double time stamps present in BIP and ZNC is much faster re-establishing connections to my multiple IRC network and channels.
  • Most importantly, ZNC has been far more stable than BIP.


Monitorix on Debian

I have a few Debian servers that run at home and on VPSs. I wanted to add some basic systems monitoring to them, but didn’t want anything too complicated to look after. I found Monitorix.

Monitorix is a free, open source, lightweight system monitoring tool designed to monitor as many services and system resources as possible. It has been created to be used under production Linux/UNIX servers, but due to its simplicity and small size can be used on embedded devices as well.

Install Monitorix

This install has been tested on Debian Squeeze and Wheezy. First install the dependencies.

sudo apt-get install rrdtool perl libwww-perl libmailtools-perl \
libmime-lite-perl librrds-perl libdbi-perl libxml-simple-perl \
libhttp-server-simple-perl libconfig-general-perl libio-socket-ssl-perl

Now Monitorix itself.

wget -c "" -O monitorix_3.5.1-izzy1_all.deb
sudo dpkg -i monitorix_3.5.1-izzy1_all.deb

At this point Monitorix is installed and running. Point your browser to and enjoy!

Configuring Monitorix

Everything in /etc/monitorix/monitorix.conf is comprehensively documented, just get tweaking.

Each time you update the configuration Monitorix will require a restart.

sudo service monitorix restart

nginx status

If you run nginx then you’ll want to drop the following into /etc/nginx/conf.d/status.conf so that Monitorix can monitor nginx.

server {
    listen localhost:80;
    location /nginx_status {
        stub_status on;
        access_log off;
        deny all;

subSonic on Debian

Last year I removed all my music from Google Play Music and created my own subSonic server. I really like subSonic but don’t use it a huge amount, mostly for syncing some music to my phone prior to going on holiday or business. Therefore, I’ve made a single one time donation to the project rather than the ongoing monthly usage fee.

Installing subSonic on Debian

This is how I install subSonic on Debian Wheezy.

Install Tomcat.

sudo apt-get install tomcat7

Install subSonic.

apt-get install ffmpeg
sudo mkdir /var/subsonic
sudo chown tomcat7: /var/subsonic
sudo wget -c
sudo cp subsonic.war /var/lib/tomcat7/webapps

Restart Tomcat.

sudo service tomcat7 restart

Login to subSonic by visiting and login with the credentials admin and admin. Make sure you change the password straight away.

Right, that is it. You can stop here and start filling subSonic with your music.

subSonic clients

On the rare occasions that I listen to music via subSonic I use UltraSonic for Android and Clementine on my Arch Linux workstations.


Headless cloudprint server on Debian for MFC-7360N

I have a Brother MFC-7360N printer at home and there is also one at work. I wanted to to get Cloudprint working with Android devices rather than use the Android app Brother provide, which is great when it works but deeply frustrating (for my wife) when it doesn’t.

What I describe below is how to Cloudprint enable “Classic printers” using Debian Wheezy.

Install CUPS

Install CUPS and the Cloudprint requirements.

sudo apt-get install cups python-cups python-daemon python-pkg-resources

Install the MFC-7360N Drivers

I used the URL below to access the .deb files required.

If you’re running a 64-bit Debian, then install ia32-libs first.

sudo apt-get install ia32-libs

Download and install the MFC-7360N drivers.

wget -c
wget -c
sudo dpkg -i --force-all mfc7360nlpr-2.1.0-1.i386.deb
sudo dpkg -i --force-all cupswrapperMFC7360N-2.0.4-2.i386.deb

Configure CUPS

Edit the CUPS configuration file commonly located in /etc/cups/cupsd.conf and make the section that looks like:

# Only listen for connections from the local machine.
Listen localhost:631
Listen /var/run/cups/cups.sock

look like this:

# Listen on all interfaces
Port 631
Listen /var/run/cups/cups.sock

Modify the Apache specific directives to allow connections from everywhere as well. Find the follow section in /etc/cups/cupsd.conf:

<Location />
# Restrict access to the server...
  Order allow,deny

# Restrict access to the admin pages...
<Location /admin>
  Order allow,deny

# Restrict access to the configuration files...
<Location /admin/conf>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny

Add Allow All after each Order allow,deny so it looks like this:

<Location />
# Restrict access to the server...
  Order allow,deny
  Allow All

# Restrict access to the admin pages...
<Location /admin>
  Order allow,deny
  Allow All

# Restrict access to the configuration files...
<Location /admin/conf>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny
  Allow All

Add the MFC-7360N to CUPS.

If your MFC-7360N is connected to your server via USB then you should be all set. Login to the CUPS administration interface on http://yourserver:631 and modify the MFC7360N printer (if one was created when the drivers where installed) then make sure you can print a test page via CUPS before proceeding.

Install Cloudprint and Cloudprint service

wget -c
wget -c
sudo dpkg -i cloudprint_0.11-5.1_all.deb
sudo dpkg -i cloudprint-service_0.11-5.1_all.deb


Google accounts with 2 step verification enabled need to use an application-specific password.

Authenticate cloudprintd.

sudo service cloudprintd login

You should see something like this.

Accounts with 2 factor authentication require an application-specific password
Google username: [email protected]
Added Printer MFC7360N

Start the Cloudprint daemon.

sudo service cloudprintd start

If everything is working correctly you should see your printer the following page:

Printing from mobile devices


Add the Google Cloud Print app to Android devices and you’ll be able to configure your printer preferences and print from Android..

Chrome and Chromium

When printing from within Google Chrome and Chromium you can now select Cloudprint as the destination and choose your printer.


Humax Foxsat HDR Custom Firmware

I’ve had the notes kicking around for absolutely ages. I haven’t checked to see if this stuff is still accurate because during the last 12 months or so our viewing habbits have changed and we almost exclusively watch streamed content now.

That said, my father-in-law gave us a Humax Foxsat HDR Freesat digital recorder as a thank you for some work I did for him. It turns out the Humax Foxsat HDR is quite hackable.

Hard Disk Upgrade

I contributed to the topic below. The Humax firmware only supports disks up to 1TB but the hackers method works for 2TB drives, possibly bigger but I haven’t tried. I’ve upgraded mine and my father-in-laws to 2TB without any problems.

Custom Firmware

These are the topics that discuss the custom firmware itself and includes the downloads. Once the custom firmware is installed and it’s advanced interface has been enabled you can enable several add-ons such as Samba, Mediatomb, ssh, ftp, etc.

Web Interface

This is the topic about the web interface. No download required it is bundled in the custom firmware above.

Channel Editor

The channel editor is installed and configured via the web interface and is one of my favourite add-ons. It also allows you to enable non-freesat channels in the normal guide.

Non Freesat channels

We get our broadcasts from Astra 2A / Astra 2B / Astra 2D / Eurobird 1 (28.2°E). Other free to air channels are available and KingOfSat lists them all. These channels can only be added via the Humax setup menus, but can then be presented in the normal EPG using the Channel Editor above.

Decrypt HD recordings

I never actually tried this, but what follows might be useful.

OTA updates

This is not so relevant now, since Humax haven’t released an OTA update for some time.

I have not yet found a way to prevent automatic over the air updates from being automatically applied. When an over the air update is applied the Humax still works, but the web interface and all the add-ons stop working. The can be solved by waiting for the custom firmware to be updated (which happen remarkably quickly) and then re-flashing the custom firmware. All the add-ons should start working again.

Integrating Dropbox photo syncing with Open Media Vault and Plex

I’ve installed Open Media Vault on a HP ProLiant MicroServer G7 N54L and use it as media server for the house. OpenMediaVault (OMV) is a network attached storage (NAS) solution based on Debian Linux. At the time of writing OMV 0.5.x is based on Debian 6.0 (Squeeze).

I use a free Dropbox account to sync photos from mine and my wife’s Android phones and wanted to automate to import of these photo upload into Plex, which is also running on Open Media Vault.

Installing Dropbox on Open Media Vault 0.5.x

I looked for a Dropbox Plugin for Open Media Vault and found this:

Sadly, at the time of writing, it is unfinished and I didn’t have the time to go and learn the Open Media Vault plugin API.

The Open Media Vault forum does include a Dropbox HOW-TO which is very similar to how I’ve run Dropbox on headless Linux servers in the past. So, I decided to adapt my existing notes to Open Media Vault.

Create a Dropbox Share

Create a Dropbox share via the OMV WebUI.

  • Access Right Management -> Shared Folders

I gave my the name “Dropbox”. I know, very original.

Installing Dropbox on a headless server

Download the latest Dropbox stable release for 32-bit or 64-bit.

wget -O dropbox.tar.gz ""
wget -O dropbox.tar.gz ""

Extract the archive and install Dropbox in /opt.

tar -xvzf dropbox.tar.gz
sudo mv ~/.dropbox-dist /opt/dropbox
sudo find /opt/dropbox/ -type f -exec chmod 644 {} \;
sudo chmod 755 /opt/dropbox/dropboxd
sudo chmod 755 /opt/dropbox/dropbox
sudo ln -s /opt/dropbox/dropboxd /usr/local/bin/dropboxd

Run dropboxd.


You should see output like this:

This client is not linked to any account... Please visit to link this machine.

Visit the URL, login with your Dropbox account and link the account. You should see the following.

Client successfully linked, Welcome Web!

dropboxd will now create a ~/Dropbox folder and start synchronizing. Stop dropboxd with CTRL+C.

Symlink the Dropbox share

Login to the OMV server as root and sym-link the Dropbox share you created earlier to the Dropbox directory in the root home directory.

mv ~/Dropbox ~/Dropbox-old
ln -s /media/<UUID>/Dropbox Dropbox
rsync -av -W --progress ~/Dropbox-old/ ~/Dropbox/


To run Dropbox as daemon with init.d. Create /etc/init.d/dropbox with the following content.

# Provides: dropbox
# Required-Start: $local_fs $remote_fs $network $syslog $named
# Required-Stop: $local_fs $remote_fs $network $syslog $named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# X-Interactive: false
# Short-Description: dropbox service


start() {
    echo "Starting dropbox..."
    for dbuser in $DROPBOX_USERS; do
        HOMEDIR=`getent passwd $dbuser | cut -d: -f6`
        if [ -x $DAEMON ]; then
            HOME="$HOMEDIR" start-stop-daemon -b -o -c $dbuser -S -u $dbuser -x $DAEMON

stop() {
    echo "Stopping dropbox..."
    for dbuser in $DROPBOX_USERS; do
        HOMEDIR=`getent passwd $dbuser | cut -d: -f6`
        if [ -x $HOMEDIR/$DAEMON ]; then
            start-stop-daemon -o -c $dbuser -K -u $dbuser -x $DAEMON

status() {
    for dbuser in $DROPBOX_USERS; do
        dbpid=`pgrep -u $dbuser dropbox`
        if [ -z $dbpid ] ; then
            echo "dropboxd for USER $dbuser: not running."
            echo "dropboxd for USER $dbuser: running (pid $dbpid)"

case "$1" in
        echo "Usage: /etc/init.d/dropbox {start|stop|reload|force-reload|restart|status}"
        exit 1

exit 0

Enable the init.d script.

sudo chmod +x /etc/init.d/dropbox
sudo update-rc.d dropbox defaults

Starting and Stopping the Dropbox daemon

Use /etc/init.d/dropbox start to start and /etc/init.d/dropbox stop to stop.

Dropbox client

It is recommended to download the official Dropbox client to configure Dropbox and get its status.

wget "" -O dropbox
chmod 755 dropbox
sudo mv dropbox /usr/local/bin/

You can check on Dropbox status by running the following.

dropbox status

For usage instructions run dropbox help.

Photo importing

So, the reason for doing all this is that I now have a Dropbox instance running on my home file server and everyday it runs a script, that I wrote, to automatically import new photos into a directory that Plex monitors. I’ll post details about my photo sorting script, Phort, at a later date.


OpenMediaVault on Debian

At the time of writing OpenMediaVault 0.6 is pre-release. But it is possible to install OpenMediaVault on Debian Wheezy in order to get some testing done.

Install Debian Wheezy on your target VM or test server. Go with the defaults until the ‘Software selection’ dialogue. Make sure everything is unselected, like this:

[ ] Debian desktop environment
[ ] Web server
[ ] Print server
[ ] SQL database
[ ] DNS Server
[ ] File server
[ ] Mail server
[ ] SSH server
[ ] Laptop
[ ] Standard system utilities

After the install is complete, reboot and login to the new Debian system as root.

Update the repository sources and add the contrib and non-free repositories.

nano /etc/apt/sources.list

It should look something like this:

deb wheezy main contrib non-free
deb-src wheezy main contrib non-free

deb wheezy/updates main contrib non-free
deb-src wheezy/updates main contrib non-free

# wheezy-updates, previously known as 'volatile'
deb wheezy-updates main contrib non-free
deb-src wheezy-updates main contrib non-free

Now add the OpenMediaVault repository.

echo "deb kralizec main" > /etc/apt/sources.list.d/openmediavault.list


apt-get update

Install the OpenMediaVault repository key and Postfix.

apt-get install openmediavault-keyring postfix
  • When the ‘Postfix Configuration’ dialogue is displayed choose No configuration.

Update again and install OpenMediaVault.

apt-get update
apt-get install openmediavault
  • When the ‘Configuring mdadm’ dialogue is displayed enter none.
  • Do you want to start MD arrays automatically? YES
  • When the ‘ProFTPD configuration’ dialogue is displayed choose standalone.

Initialise OpenMediaVault and reboot.


After the reboot you should be able to connect to the OpenMediaVault WebUI and login as admin with the password of openmediavault.

That’s it. Get testing.

Setting up BitSync on Debian

I’ve replaced Dropbox with BitTorrent Sync. In order to do this I’ve have btsync running on a VPS (2CPU, 2GB, 400GB), my home server and assorted Arch Linux workstations.

I had a couple of reasons for migrating away from Dropbox.

  • Dropbox was costing $100 per year.
  • Dropbox encryption model is weak and I have data security/privacy.

The VPS I am running BitTorrent Sync on costs $50 per year and provides four times the storage. I run btsync on a VPS so that there is always a server “in the cloud” that is available to sync with so that my setup emulates what Dropbox used to do.

All my servers are running Debian and this is how I install btsync on Debian.

sh -c "$(curl -fsSL"
sudo apt-get install btsync

This is how I respond to the prompts:

  • Do you want to define a default BitTorrent Sync instance? : YES
  • BitTorrent Sync Daemon Credentials: yourusername
  • BitTorrent Sync Daemon Group: yourusername
  • Niceness of the BitTorrent Sync Daemon: 0
  • On which portnumber should BitTorrent Sync listen? 0
  • BitTorrent Sync Listen Port: 12345
  • Do you want BitTorrent Sync to request port mapping via UPNP? NO
  • Download Bandwith Limit: 0
  • Upload Bandwith Limit: 0
  • Web Interface Bind IP Address:
  • Web Interface Listen Port: 8888
  • The username for accessing the web interface: yourusername
  • The password for accessing the web interface: yourpassword

As you’ll see, I don’t use UPNP on my VPS. I elect a specific port (not actually 12345 by the way) and open that port up with ufw. I also only allow access to the WebUI port from another server I own which reverse proxies via nginx.

btsync works really well, I have it syncing hundreds of thousands of files that amount to several hundred gigabytes of data. On my Arch Linux workstations I use the brilliant btsync-gui and BitTorrent Sync is also available for Android.

That said, I still use a free Dropbox account to sync photos from mine and my wife’s Android phones. I have a Dropbox instance running on my home file server and everyday it runs a script to automatically import these photos into Plex.

Such a shame, that at the time of writing, btsync is closed source :-( Maybe that will change but if it doesn’t SyncThing may well be the answer when it has matured a little.

Flattr this