diff --git a/src/freedombone-app-smilodon b/src/freedombone-app-smilodon
new file mode 100755
index 0000000000000000000000000000000000000000..d0d9037053022163245fea88af80ef93045b8fe3
--- /dev/null
+++ b/src/freedombone-app-smilodon
@@ -0,0 +1,357 @@
+#!/bin/bash
+#
+# .---.                  .              .
+# |                      |              |
+# |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
+# |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
+# '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
+#
+#                    Freedom in the Cloud
+#
+# Smilodon ActivityPub app
+#
+# License
+# =======
+#
+# Copyright (C) 2017 Bob Mottram <bob@freedombone.net>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+VARIANTS='full full-vim social'
+
+IN_DEFAULT_INSTALL=0
+SHOW_ON_ABOUT=1
+SHOW_ICANN_ADDRESS_ON_ABOUT=0
+
+SMILODON_REPO="https://github.com/bashrc/smilodon"
+SMILODON_COMMIT='22072cfbd9bdbdd6f4bb5ab440d8f468e38a912a'
+SMILODON_ADMIN_PASSWORD=
+SMILODON_ONION_PORT=8054
+SMILODON_PATH=/etc/smilodon
+SMILODON_SECRET_KEY=
+
+smilodon_variables=(SMILODON_REPO
+                    SMILODON_ADMIN_PASSWORD
+                    USB_MOUNT
+                    SMILODON_SECRET_KEY
+                    MY_EMAIL_ADDRESS
+                    MY_USERNAME)
+
+function logging_on_smilodon {
+    echo -n ''
+}
+
+function logging_off_smilodon {
+    echo -n ''
+}
+
+function remove_user_smilodon {
+    remove_username="$1"
+}
+
+function add_user_smilodon {
+    new_username="$1"
+    new_user_password="$2"
+    echo '0'
+}
+
+function install_interactive_smilodon {
+    echo -n ''
+    APP_INSTALLED=1
+}
+
+function change_password_smilodon {
+    curr_username="$1"
+    new_user_password="$2"
+
+    #${PROJECT_NAME}-pass -u "$curr_username" -a smilodon -p "$new_user_password"
+}
+
+function smilodon_create_database {
+    if [ -f $IMAGE_PASSWORD_FILE ]; then
+        SMILODON_ADMIN_PASSWORD="$(printf `cat $IMAGE_PASSWORD_FILE`)"
+    else
+        if [ ! $SMILODON_ADMIN_PASSWORD ]; then
+            SMILODON_ADMIN_PASSWORD="$(create_password ${MINIMUM_PASSWORD_LENGTH})"
+        fi
+    fi
+    if [ ! $SMILODON_ADMIN_PASSWORD ]; then
+        return
+    fi
+
+    function_check create_database_mongodb
+    create_database_mongodb smilodon "$SMILODON_ADMIN_PASSWORD" smilodon
+}
+
+function reconfigure_smilodon {
+    echo -n ''
+}
+
+function upgrade_smilodon {
+    CURR_SMILODON_COMMIT=$(get_completion_param "smilodon commit")
+    if [[ "$CURR_SMILODON_COMMIT" == "$SMILODON_COMMIT" ]]; then
+        return
+    fi
+
+    if [[ $(app_is_installed smilodon) == "1" ]]; then
+        systemctl stop smilodon
+        function_check set_repo_commit
+        set_repo_commit $SMILODON_PATH "smilodon commit" "$SMILODON_COMMIT" $SMILODON_REPO
+        chown -R smilodon:smilodon $SMILODON_PATH
+        systemctl start smilodon
+    fi
+
+}
+
+function backup_local_smilodon {
+    if [ -d $SMILODON_PATH ]; then
+        systemctl stop smilodon
+
+        USE_MONGODB=1
+        function_check backup_database_to_usb
+        backup_database_to_usb smilodon
+
+        backup_directory_to_usb $SMILODON_PATH smilodon
+
+        systemctl start smilodon
+    fi
+}
+
+function restore_local_smilodon {
+    temp_restore_dir=/root/tempsmilodon
+
+    systemctl stop smilodon
+
+    function_check smilodon_create_database
+    smilodon_create_database
+
+    USE_MONGODB=1
+    restore_database smilodon
+
+    if [ -d ${SMILODON_PATH} ]; then
+        if [ -d $temp_restore_dir${SMILODON_PATH} ]; then
+            if [ -d $temp_restore_dir${SMILODON_PATH} ]; then
+                rm -rf ${SMILODON_PATH}
+                mv $temp_restore_dir$SMILODON_PATH ${SMILODON_PATH}/
+            else
+                cp -r $temp_restore_dir/* ${SMILODON_PATH}/
+            fi
+            if [ ! "$?" = "0" ]; then
+                function_check backup_unmount_drive
+                backup_unmount_drive
+                systemctl start smilodon
+                exit 528823
+            fi
+            chown -R smilodon:smilodon ${SMILODON_PATH}
+        fi
+    fi
+
+    if [ -d $USB_MOUNT/backup/smilodon ]; then
+        chown -R smilodon:smilodon ${SMILODON_PATH}
+        if [ -d $temp_restore_dir ]; then
+            rm -rf $temp_restore_dir
+        fi
+    fi
+
+    systemctl start smilodon
+}
+
+function backup_remote_smilodon {
+    if [ -d $SMILODON_PATH ]; then
+        function_check suspend_site
+        suspend_site smilodon
+
+        systemctl stop smilodon
+
+        USE_MONGODB=1
+        function_check backup_database_to_friend
+        backup_database_to_friend smilodon
+
+        function_check backup_directory_to_friend
+        backup_directory_to_friend $SMILODON_PATH smilodon
+
+        systemctl start smilodon
+
+        function_check restart_site
+        restart_site
+    else
+        echo $"Smilodon domain specified but not found in $SMILODON_PATH"
+    fi
+}
+
+function restore_remote_smilodon {
+    temp_restore_dir=/root/tempsmilodon
+    if grep -q "smilodon domain" $COMPLETION_FILE; then
+        echo $"Restoring smilodon"
+        systemctl stop smilodon
+
+        function_check restore_database_from_friend
+
+        function_check smilodon_create_database
+        smilodon_create_database
+
+        USE_MONGODB=1
+        restore_database_from_friend smilodon
+
+        if [ -d $SMILODON_PATH ]; then
+            if [ -d $temp_restore_dir$SMILODON_PATH ]; then
+                rm -rf $SMILODON_PATH
+                mv $temp_restore_dir$SMILODON_PATH ${SMILODON_PATH}/
+            else
+                cp -r $temp_restore_dir/* ${SMILODON_PATH}/
+            fi
+            if [ ! "$?" = "0" ]; then
+                systemctl start smilodon
+                exit 6391643
+            fi
+        fi
+
+        if [ -d $SERVER_DIRECTORY/backup/smilodon ]; then
+            chown -R smilodon:smilodon ${SMILODON_PATH}
+        fi
+        if [ -d /root/tempsmilodon ]; then
+            rm -rf /root/tempsmilodon
+        fi
+
+        systemctl start smilodon
+
+        echo $"Restore of smilodon complete"
+    fi
+}
+
+function remove_smilodon {
+    nginx_dissite smilodon
+
+    systemctl stop smilodon
+    systemctl disable smilodon
+    rm /etc/systemd/system/smilodon.service
+
+    function_check remove_onion_service
+    remove_onion_service smilodon ${SMILODON_ONION_PORT}
+    if [ -f /etc/nginx/sites-available/smilodon ]; then
+        rm /etc/nginx/sites-available/smilodon
+    fi
+
+    groupdel -f smilodon
+    userdel -r smilodon
+
+    if [ -d $SMILODON_PATH ]; then
+        rm -rf $SMILODON_PATH
+    fi
+
+    function_check remove_mongodb_user
+    remove_mongodb_user smilodon
+
+    function_check drop_database_mongodb
+    drop_database_mongodb smilodon
+
+    remove_completion_param install_smilodon
+    sed -i '/smilodon_/d' $COMPLETION_FILE
+}
+
+function install_smilodon {
+    apt-get -yq install python3-pip
+
+    if [ -d $SMILODON_PATH ]; then
+        rm -rf $SMILODON_PATH
+    fi
+
+    if [ -d /repos/smilodon ]; then
+        mkdir $SMILODON_PATH
+        cp -r -p /repos/smilodon/. $SMILODON_PATH
+        cd $SMILODON_PATH
+        git pull
+    else
+        function_check git_clone
+        git_clone $SMILODON_REPO $SMILODON_PATH
+    fi
+
+    if [ ! -d $SMILODON_PATH ]; then
+        echo $'Could not clone smilodon repo'
+        exit 6784783
+    fi
+    cd $SMILODON_PATH
+    git checkout $SMILODON_COMMIT -b $SMILODON_COMMIT
+    set_completion_param "smilodon commit" "$SMILODON_COMMIT"
+
+    groupadd smilodon
+    useradd -c "Smilodon system account" -d $SMILODON_PATH -m -r -g smilodon smilodon
+
+    function_check install_mongodb
+    install_mongodb
+
+    smilodon_create_database
+
+    SMILODON_ONION_HOSTNAME=$(add_onion_service smilodon 80 ${SMILODON_ONION_PORT})
+
+    pip3 install -r requirements.txt
+    if [ ! "$?" = "0" ]; then
+        echo $'Unable to install smilodon dependencies'
+        exit 87352835
+    fi
+
+    echo 'server {' > /etc/nginx/sites-available/smilodon
+    echo "  listen 127.0.0.1:$SMILODON_ONION_PORT;" >> /etc/nginx/sites-available/smilodon
+    echo "  server_name $SMILODON_ONION_HOSTNAME;" >> /etc/nginx/sites-available/smilodon
+    echo '' >> /etc/nginx/sites-available/smilodon
+    echo '  access_log /dev/null;' >> /etc/nginx/sites-available/smilodon
+    echo '  error_log /dev/null;' >> /etc/nginx/sites-available/smilodon
+    echo '' >> /etc/nginx/sites-available/smilodon
+    echo '  location / {' >> /etc/nginx/sites-available/smilodon
+    echo '      proxy_pass http://localhost:5000;' >> /etc/nginx/sites-available/smilodon
+    echo '  }' >> /etc/nginx/sites-available/smilodon
+    echo '' >> /etc/nginx/sites-available/smilodon
+    echo '}' >> /etc/nginx/sites-available/smilodon
+
+    nginx_ensite smilodon
+    systemctl enable mongodb
+    systemctl restart mongodb
+    systemctl restart nginx
+
+    chown -R smilodon:smilodon ${SMILODON_PATH}
+
+    if [ ! $SMILODON_SECRET_KEY ]; then
+        SMILODON_SECRET_KEY="$(create_password 30)$(create_password 30)$(create_password 30)$(create_password 30)"
+    fi
+
+    echo '[Unit]' > /etc/systemd/system/smilodon.service
+    echo 'Description=Smilodon ActivityPub messenger' >> /etc/systemd/system/smilodon.service
+    echo 'After=network.target mongodb.service' >> /etc/systemd/system/smilodon.service
+    echo 'After=tor.service' >> /etc/systemd/system/smilodon.service
+    echo '' >> /etc/systemd/system/smilodon.service
+    echo '[Service]' >> /etc/systemd/system/smilodon.service
+    echo 'User=smilodon' >> /etc/systemd/system/smilodon.service
+    echo 'Group=smilodon' >> /etc/systemd/system/smilodon.service
+    echo "WorkingDirectory=${SMILODON_PATH}/" >> /etc/systemd/system/smilodon.service
+    echo "ExecStart=/usr/bin/python3 run.py" >> /etc/systemd/system/smilodon.service
+    echo "Environment=smilodon_domain_name=$SMILODON_ONION_HOSTNAME" >> /etc/systemd/system/smilodon.service
+    echo "Environment=secret_key='$SMILODON_SECRET_KEY'" >> /etc/systemd/system/smilodon.service
+    echo "Environment=mongodb_username='smilodon'" >> /etc/systemd/system/smilodon.service
+    echo "Environment=mongodb_password='$SMILODON_ADMIN_PASSWORD'" >> /etc/systemd/system/smilodon.service
+    echo "Environment=smilodon_admin_address=$MY_EMAIL_ADDRESS" >> /etc/systemd/system/smilodon.service
+    echo "Environment=MAIL_SERVER='localhost'" >> /etc/systemd/system/smilodon.service
+    echo "Environment=MAIL_PORT=25" >> /etc/systemd/system/smilodon.service
+    echo '' >> /etc/systemd/system/smilodon.service
+    echo '[Install]' >> /etc/systemd/system/smilodon.service
+    echo 'WantedBy=multi-user.target' >> /etc/systemd/system/smilodon.service
+    systemctl enable smilodon
+    systemctl daemon-reload
+    systemctl start smilodon
+
+    ${PROJECT_NAME}-pass -u $MY_USERNAME -a smilodon -p "$SMILODON_ADMIN_PASSWORD"
+
+    APP_INSTALLED=1
+}
+
+# NOTE: deliberately no exit 0
diff --git a/src/freedombone-utils-backup b/src/freedombone-utils-backup
index a66a648055aea5a3c7a557cce735ecd54f886e26..3dc51a0de0a43cc4b63e2084a6a10ff14632b880 100755
--- a/src/freedombone-utils-backup
+++ b/src/freedombone-utils-backup
@@ -236,15 +236,29 @@ function backup_database_local_usb {
         mkdir -p ${local_database_dir}
     fi
     echo $"Obtaining ${1} database backup"
+    database_file_extension='sql'
+    if [ $USE_MONGODB ]; then
+        database_file_extension='mdb'
+        USE_POSTGRESQL=
+    fi
     if [ ! $USE_POSTGRESQL ]; then
-        keep_database_running
-        mysqldump --lock-tables --password="$DATABASE_PASSWORD" ${1} > ${local_database_dir}/${1}.sql
+        if [ ! $USE_MONGODB ]; then
+            USE_MONGODB=
+            USE_POSTGRESQL=
+            keep_database_running
+            mysqldump --lock-tables --password="$DATABASE_PASSWORD" ${1} > ${local_database_dir}/${1}.${database_file_extension}
+        else
+            USE_MONGODB=
+            USE_POSTGRESQL=
+            mongodump --db ${1} --archive=${local_database_dir}/${1}.${database_file_extension} --gzip
+        fi
     else
+        USE_MONGODB=
         USE_POSTGRESQL=
-        sudo -u postgres pg_dump ${1} > ${local_database_dir}/${1}.sql
+        sudo -u postgres pg_dump ${1} > ${local_database_dir}/${1}.${database_file_extension}
     fi
-    if [ -f ${local_database_dir}/${1}.sql ]; then
-        if [ ! -s ${local_database_dir}/${1}.sql ]; then
+    if [ -f ${local_database_dir}/${1}.${database_file_extension} ]; then
+        if [ ! -s ${local_database_dir}/${1}.${database_file_extension} ]; then
             echo $"${1} database could not be saved"
             shred -zu ${local_database_dir}/*
             rm -rf ${local_database_dir}
@@ -552,16 +566,30 @@ function backup_database_remote {
     fi
 
     echo "Obtaining ${1} database backup"
+    database_file_extension='sql'
+    if [ $USE_MONGODB ]; then
+        database_file_extension='mdb'
+        USE_POSTGRESQL=
+    fi
     if [ ! $USE_POSTGRESQL ]; then
-        keep_database_running
-        mysqldump --lock-tables --password="$DATABASE_PASSWORD" ${1} > ${local_database_dir}/${1}.sql
+        if [ ! $USE_MONGODB ]; then
+            USE_MONGODB=
+            USE_POSTGRESQL=
+            keep_database_running
+            mysqldump --lock-tables --password="$DATABASE_PASSWORD" ${1} > ${local_database_dir}/${1}.${database_file_extension}
+        else
+            USE_MONGODB=
+            USE_POSTGRESQL=
+            mongodump --db ${1} --archive=${local_database_dir}/${1}.${database_file_extension} --gzip
+        fi
     else
+        USE_MONGODB=
         USE_POSTGRESQL=
-        sudo -u postgres pg_dump ${1} > ${local_database_dir}/${1}.sql
+        sudo -u postgres pg_dump ${1} > ${local_database_dir}/${1}.${database_file_extension}
     fi
 
-    if [ -f ${local_database_dir}/${1}.sql ]; then
-        if [ ! -s ${local_database_dir}/${1}.sql ]; then
+    if [ -f ${local_database_dir}/${1}.${database_file_extension} ]; then
+        if [ ! -s ${local_database_dir}/${1}.${database_file_extension} ]; then
             echo $"${1} database could not be saved"
             shred -zu ${local_database_dir}/*
             rm -rf ${local_database_dir}
@@ -569,7 +597,7 @@ function backup_database_remote {
             echo $"Unable to export ${1} database" | mail -s $"${PROJECT_NAME} backup to friends" $ADMIN_EMAIL_ADDRESS
             function_check restart_site
             restart_site
-            exit 5738
+            exit 57386728
         fi
     else
         echo $"${1} database could not be dumped"
@@ -578,7 +606,7 @@ function backup_database_remote {
         echo $"Unable to dump ${1} database" | mail -s $"${PROJECT_NAME} backup to friends" $ADMIN_EMAIL_ADDRESS
         function_check restart_site
         restart_site
-        exit 3687
+        exit 36874289
     fi
 }
 
@@ -642,33 +670,47 @@ function restore_database_from_friend {
     RESTORE_SUBDIR="root"
 
     if [ -d $SERVER_DIRECTORY/backup/${1} ]; then
+        database_file_extension='sql'
+        if [ $USE_MONGODB ]; then
+            database_file_extension='mdb'
+            USE_POSTGRESQL=
+        fi
         echo $"Restoring ${1} database"
         local_database_dir=/root/temp${1}data
         restore_directory_from_friend ${local_database_dir} ${1}data
-        database_file=${local_database_dir}/${RESTORE_SUBDIR}/temp${restore_app_name}data/${restore_app_name}.sql
+        database_file=${local_database_dir}/${RESTORE_SUBDIR}/temp${restore_app_name}data/${restore_app_name}.${database_file_extension}
         if [ ! -f $database_file ]; then
-            database_file=${local_database_dir}/${restore_app_name}.sql
+            database_file=${local_database_dir}/${restore_app_name}.${database_file_extension}
         fi
         if [ ! -f $database_file ]; then
             echo $"Unable to restore ${1} database"
             rm -rf ${local_database_dir}
-            exit 503
+            exit 5289252
         fi
         if [ ! $USE_POSTGRESQL ]; then
-            keep_database_running
-            mysqlsuccess=$(mysql -u root --password="$DATABASE_PASSWORD" ${1} -o < ${local_database_dir}/${RESTORE_SUBDIR}/temp${1}data/${1}.sql)
+            if [ ! $USE_MONGODB ]; then
+                USE_MONGODB=
+                USE_POSTGRESQL=
+                keep_database_running
+                mysqlsuccess=$(mysql -u root --password="$DATABASE_PASSWORD" ${restore_app_name} -o < ${database_file})
+            else
+                USE_MONGODB=
+                USE_POSTGRESQL=
+                mongorestore --gzip --archive=${database_file} --db ${restore_app_name}
+            fi
         else
+            USE_MONGODB=
             USE_POSTGRESQL=
-            mysqlsuccess=$(sudo -u postgres pg_restore ${local_database_dir}/${RESTORE_SUBDIR}/temp${1}data/${1}.sql)
+            mysqlsuccess=$(sudo -u postgres pg_restore ${database_file})
         fi
         if [ ! "$?" = "0" ]; then
             echo "$mysqlsuccess"
-            exit 964
+            exit 8735271
         fi
         if [ -d ${local_database_dir}/${RESTORE_SUBDIR}/temp${1}data ]; then
             shred -zu ${local_database_dir}/${RESTORE_SUBDIR}/temp${1}data/*
         else
-            shred -zu ${local_database_dir}/*.sql
+            shred -zu ${local_database_dir}/*.${database_file_extension}
         fi
         rm -rf ${local_database_dir}
         echo $"Restoring ${1} installation"
@@ -695,7 +737,7 @@ function restore_database_from_friend {
                         cp -r $restore_from_dir/* /var/www/${2}/htdocs/
                     fi
                     if [ ! "$?" = "0" ]; then
-                        exit 683
+                        exit 78352682
                     fi
                     if [ -d /etc/letsencrypt/live/${2} ]; then
                         ln -s /etc/letsencrypt/live/${2}/privkey.pem /etc/ssl/private/${2}.key
@@ -725,9 +767,14 @@ function restore_database {
         fi
         function_check restore_directory_from_usb
         restore_directory_from_usb "${local_database_dir}" "${restore_app_name}data"
-        database_file=${local_database_dir}/${RESTORE_SUBDIR}/temp${restore_app_name}data/${restore_app_name}.sql
+        database_file_extension='sql'
+        if [ $USE_MONGODB ]; then
+            database_file_extension='mdb'
+            USE_POSTGRESQL=
+        fi
+        database_file=${local_database_dir}/${RESTORE_SUBDIR}/temp${restore_app_name}data/${restore_app_name}.${database_file_extension}
         if [ ! -f $database_file ]; then
-            database_file=${local_database_dir}/${restore_app_name}.sql
+            database_file=${local_database_dir}/${restore_app_name}.${database_file_extension}
         fi
         if [ ! -f $database_file ]; then
             echo $"Unable to restore ${restore_app_name} database"
@@ -736,12 +783,21 @@ function restore_database {
             set_user_permissions
             function_check backup_unmount_drive
             backup_unmount_drive
-            exit 503
+            exit 7825235
         fi
         if [ ! $USE_POSTGRESQL ]; then
-            keep_database_running
-            mysqlsuccess=$(mysql -u root --password="$DATABASE_PASSWORD" ${restore_app_name} -o < $database_file)
+            if [ ! $USE_MONGODB ]; then
+                USE_MONGODB=
+                USE_POSTGRESQL=
+                keep_database_running
+                mysqlsuccess=$(mysql -u root --password="$DATABASE_PASSWORD" ${restore_app_name} -o < $database_file)
+            else
+                USE_MONGODB=
+                USE_POSTGRESQL=
+                mongorestore --gzip --archive=$database_file --db ${restore_app_name}
+            fi
         else
+            USE_MONGODB=
             USE_POSTGRESQL=
             mysqlsuccess=$(sudo -u postgres pg_restore $database_file)
         fi
@@ -751,12 +807,12 @@ function restore_database {
             set_user_permissions
             function_check set_user_permissions
             backup_unmount_drive
-            exit 964
+            exit 482638995
         fi
         if [ -d ${local_database_dir}/${RESTORE_SUBDIR}/temp${restore_app_name}data ]; then
             shred -zu ${local_database_dir}/${RESTORE_SUBDIR}/temp${restore_app_name}data/*
         else
-            shred -zu ${local_database_dir}/*.sql
+            shred -zu ${local_database_dir}/*.${database_file_extension}
         fi
 
         rm -rf ${local_database_dir}
@@ -789,7 +845,7 @@ function restore_database {
                     if [ ! "$?" = "0" ]; then
                         set_user_permissions
                         backup_unmount_drive
-                        exit 683
+                        exit 78252429
                     fi
                     if [ -d /etc/letsencrypt/live/${restore_app_domain} ]; then
                         ln -s /etc/letsencrypt/live/${restore_app_domain}/privkey.pem /etc/ssl/private/${restore_app_domain}.key
diff --git a/src/freedombone-utils-mongodb b/src/freedombone-utils-mongodb
new file mode 100755
index 0000000000000000000000000000000000000000..7ef83a250837c3d55e6027227e50783a316d4542
--- /dev/null
+++ b/src/freedombone-utils-mongodb
@@ -0,0 +1,116 @@
+#!/bin/bash
+#
+# .---.                  .              .
+# |                      |              |
+# |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
+# |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
+# '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
+#
+#                    Freedom in the Cloud
+#
+# mongodb database functions
+#
+# License
+# =======
+#
+# Copyright (C) 2017 Bob Mottram <bob@freedombone.net>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Set this when calling backup and restore commands
+USE_MONGODB=
+
+function store_original_mongodb_password {
+    if [ ! -f /root/.mongodboriginal ]; then
+        echo $'Storing original mongodb password'
+        ORIGINAL_MONGODB_PASSWORD=$(${PROJECT_NAME}-pass -u root -a mongodb)
+        # We can store this in plaintext because it will soon be of historical interest only
+        echo -n "$ORIGINAL_MONGODB_PASSWORD" > /root/.mongodboriginal
+    fi
+}
+
+function get_mongodb_password {
+    MONGODB_PASSWORD=$(${PROJECT_NAME}-pass -u root -a mongodb)
+    if [[ "$MONGODB_PASSWORD" == *'failed'* ]]; then
+        echo $'Could not obtain mongodb password'
+        exit 7835272
+    fi
+}
+
+function install_mongodb {
+    if [[ $(is_completed $FUNCNAME) == "1" ]]; then
+        return
+    fi
+
+    function_check get_mongodb_password
+    get_mongodb_password
+    if [ ! $MONGODB_PASSWORD ]; then
+        if [ -f $IMAGE_PASSWORD_FILE ]; then
+            MONGODB_PASSWORD="$(printf `cat $IMAGE_PASSWORD_FILE`)"
+        else
+            MONGODB_PASSWORD="$(openssl rand -base64 32 | cut -c1-${MINIMUM_PASSWORD_LENGTH})"
+        fi
+    fi
+    ${PROJECT_NAME}-pass -u root -a mongodb -p "$MONGODB_PASSWORD"
+
+    apt-get -yq install mongodb mongodb-tools
+    apt-get -yq remove --purge apache2-bin*
+    if [ -d /etc/apache2 ]; then
+        rm -rf /etc/apache2
+        echo $'Removed Apache installation after mongodb install'
+    fi
+
+    if [ ! -d /var/lib/mongodb ]; then
+        echo $"ERROR: mongodb does not appear to have installed. $CHECK_MESSAGE"
+        exit 78352
+    fi
+
+    mark_completed $FUNCNAME
+}
+
+function add_mongodb_user {
+    mongodb_username=$1
+    mongodb_password=$2
+
+    mongo admin --eval "db.createUser({user: '$mongodb_username', pwd: '$mongodb_password', roles: [ { role: 'userAdminAnyDatabase', db: 'admin' } ] })"
+}
+
+function remove_mongodb_user {
+    mongodb_username=$1
+    mongo admin --eval "db.removeUser($mongodb_username)"
+}
+
+function drop_database_mongodb {
+    database_name="$1"
+    if [[ "$database_name" == 'admin' ]]; then
+        return
+    fi
+    mongo $database_name --eval "db.runCommand( { dropDatabase: 1 } )"
+}
+
+function initialise_database_mongodb {
+    database_name=$1
+    database_file=$2
+    mongorestore $database_file
+    if [ ! "$?" = "0" ]; then
+        exit 8358365
+    fi
+}
+
+function create_database_mongodb {
+    app_name="$1"
+    app_admin_password="$2"
+    app_admin_username=$3
+    mongo admin --eval "db.createUser({user: '$app_admin_username', pwd: '$app_admin_password', roles: [ { role: 'dbOwner', db: '$app_name' } ] })"
+}