Upgrade

Modoboa

Warning

The new version you are going to install may need to modify your database. Before you start, make sure to backup everything!

Most of the time, upgrading your installation to a newer Modoboa version only requires a few actions. In every case, you will need to apply the general procedure first and then check if the version you are installing requires specific actions.

In case you use a dedicated user and/or a virtualenv, do not forget to use them:

> sudo -u <modoboa_user> -i
> source <virtuenv_path>/bin/activate

Then, run the following commands:

> pip install modoboa==<VERSION>
> cd <modoboa_instance_dir>
> python manage.py migrate
> python manage.py collectstatic

Once done, check if the version you are installing requires Specific instructions.

Finally, restart your web server.

Sometimes, you might need to upgrade postfix map files too. To do so, just run the generate_postfix_maps command on the same directory than the one used for installation (/etc/postfix by default).

Make sure to use root privileges and run the following command:

> python manage.py generate_postfix_maps --destdir <directory>

Then, reload postfix.

Extensions

If a new version is available for an extension you’re using, it is recommanded to install it. Upgrading an extensions is pretty and the procedure is almost the same than the one used for Modoboa.

In case you use a dedicated user and/or a virtualenv, do not forget to use them:

> sudo -i <modoboa_user>
> source <virtuenv_path>/bin/activate

Then, run the following commands:

> pip install <EXTENSION>==<VERSION>
> cd <modoboa_instance_dir>
> python manage.py migrate
> python manage.py collectstatic

Finally, restart your web server.

It is a generic upgrade procedure which will be enough most of the time but it is generally a good idea to check the associated documentation.

Rebuild Virtual Environment

Sometimes when upgrading your Operating System (eg from Ubuntu 17.04 to Ubuntu 17.10) your virtual environment running modoboa can get corrupted. Your first response will be to panic but fear not! The solution is in this document.

First things first:

Recover your database password

You will need to recover your database password (if using mysql or postgresql). You will find this in /etc/postfix/sql-aliases.cf or any file with sql-*.cf in the /etc/postfix directory.

Make note of this as you will need it when reconfiguring modoboa.

Reinstall Modoboa

Start out by backup up your modoboa settings file located in the modoboa instance directory (/srv/modoboa/instance/instance/settings.py if you used the default installer configuration). This contains your current configuration.

Next, you want to remove all current modoboa files.

After doing this, follow the manual installation instructions for Modoboa only as everything should be working properly.

After this completes, simply restore your backed up settings file to /srv/instance/instance/settings.py (if you used installer default configuration). You will then need to reinstall your extensions.

You can find which plugins you had in your settings.py file under the MODOBOA_APPS variable.

Instructions to install extensions can also be found here.

Once you have completed this step, you will need to run the following commands:

> (env) $ cd <instance_dir>
> (env) $ python manage.py migrate
> (env) $ python manage.py collectstatic

You will then see a message similar to:

You have requested to collect static files at the destination
location as specified in your settings:

    /srv/modoboa/instance/sitestatic

This will overwrite existing files!
Are you sure you want to do this?

Type 'yes' to continue, or 'no' to cancel:

You will want to answer yes here then simply restart the uwsgi process with service uwsgi restart and you should be up and running again.

Simply log into your modoboa web panel and verify that your extensions and webmail box is working.

Specific instructions

1.9.2

First of all, update postfix map files as follows:

> python manage.py generate_postfix_maps --destdir <path>

Then, modify postfix’s configuration as follows:

smtpd_sender_login_maps =
    <driver>:<path>/sql-sender-login-map.cf

Replace <driver> and <path> by your values.

Finally, reload postfix.

1.9.0

If you want to manage inactive accounts, look at Cleaning inactive accounts.

1.8.3

Edit the settings.py file and replace the following line:

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

by:

BASE_DIR = os.path.realpath(os.path.dirname(os.path.dirname(__file__)))

1.8.0

Modoboa now relies on Django’s builtin password validation system to validate user passwords, instead of django-passwords.

Remove django-passwords from your system:

> sudo -u <modoboa_user> -i
> source <virtuenv_path>/bin/activate
> pip uninstall django-passwords

Edit the settings.py file and remove the following content:

# django-passwords

PASSWORD_MIN_LENGTH = 8

PASSWORD_COMPLEXITY = {
    "UPPER": 1,
    "LOWER": 1,
    "DIGITS": 1
}

Add the following lines:

# Password validation rules
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
    {
        'NAME': 'modoboa.core.password_validation.ComplexityValidator',
        'OPTIONS': {
            'upper': 1,
            'lower': 1,
            'digits': 1,
            'specials': 0
        }
    },
]

1.7.2

API documentation has evolved (because of the upgrade to Django Rest Framework 3.6) and CKeditor is now embedded by default (thanks to the django-ckeditor package). Some configuration changes are required.

Edit your settings.py file and apply the following modifications:

  • Update the INSTALLED_APPS variable as follows:
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.sites',
    'django.contrib.staticfiles',
    'reversion',
    'ckeditor',
    'ckeditor_uploader',
    'rest_framework',
    'rest_framework.authtoken',
)
  • Update the REST_FRAMEWORK variable as follows:
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
}
  • Remove the SWAGGER_SETTINGS variable
  • Add the following content
# CKeditor

CKEDITOR_UPLOAD_PATH = "uploads/"

CKEDITOR_IMAGE_BACKEND = "pillow"

CKEDITOR_RESTRICT_BY_USER = True

CKEDITOR_BROWSE_SHOW_DIRS = True

CKEDITOR_ALLOW_NONIMAGE_FILES = False

CKEDITOR_CONFIGS = {
    'default': {
        'allowedContent': True,
        'toolbar': 'Modoboa',
        'width': None,
        'toolbar_Modoboa': [
            ['Bold', 'Italic', 'Underline'],
            ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
            ['BidiLtr', 'BidiRtl', 'Language'],
            ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent'],
            ['Undo', 'Redo'],
            ['Link', 'Unlink', 'Anchor', '-', 'Smiley'],
            ['TextColor', 'BGColor', '-', 'Source'],
            ['Font', 'FontSize'],
            ['Image', ],
            ['SpellChecker']
        ],
    },
}

Don’t forget to run the following command:

> python manage.py collectstatic

1.7.1

If you used 1.7.0 for a fresh installation, please run the following commands:

> sudo -u <modoboa_user> -i
> source <virtuenv_path>/bin/activate
> cd <modoboa_instance_dir>
> python manage.py load_initial_data

1.7.0

This version requires Django >= 1.10 so you need to make some modifications. It also brings internal API changes which are not backward compatible so installed extensions must be upgraded too.

First of all, deactivate all installed extensions (edit the settings.py file and comment the corresponding lines in MODOBOA_APPS).

Edit the urls.py file of your local instance and replace its content by the following one:

from django.conf.urls import include, url

urlpatterns = [
    url(r'', include('modoboa.urls')),
]

Edit the settings.py and apply the following changes:

  • Add 'modoboa.parameters' to MODOBOA_APPS:
MODOBOA_APPS = (
    'modoboa',
    'modoboa.core',
    'modoboa.lib',
    'modoboa.admin',
    'modoboa.relaydomains',
    'modoboa.limits',
    'modoboa.parameters',
    # Modoboa extensions here.
)
  • Add 'modoboa.core.middleware.LocalConfigMiddleware' to MIDDLEWARE_CLASSES:
 MIDDLEWARE_CLASSES = (
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.locale.LocaleMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'modoboa.core.middleware.LocalConfigMiddleware',
     'modoboa.lib.middleware.AjaxLoginRedirect',
     'modoboa.lib.middleware.CommonExceptionCatcher',
     'modoboa.lib.middleware.RequestCatcherMiddleware',
)
  • Modoboa used to provide a custom authentication backend (modoboa.lib.authbackends.SimpleBackend) but it has been removed. Replace it as follows:
AUTHENTICATION_BACKENDS = (
    # Other backends before...
    'django.contrib.auth.backends.ModelBackend',
)
  • Remove TEMPLATE_CONTEXT_PROCESSORS and replace it by:
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.template.context_processors.i18n',
                'django.template.context_processors.media',
                'django.template.context_processors.static',
                'django.template.context_processors.tz',
                'django.contrib.messages.context_processors.messages',
                'modoboa.core.context_processors.top_notifications',
            ],
            'debug': False,
        },
    },
]

Run the following commands (load virtualenv if you use one):

> sudo -u <modoboa_user> -i
> source <virtuenv_path>/bin/activate
> cd <modoboa_instance_dir>
> python manage.py migrate
> python manage.py collectstatic

Finally, upgrade your extensions and reactivate them.

Name Version
modoboa-amavis 1.1.0
modoboa-dmarc 1.0.0
modoboa-imap-migration 1.1.0
modoboa-pdfcredentials 1.1.0
modoboa-postfix-autoreply 1.2.0
modoboa-radicale 1.1.0
modoboa-sievefilters 1.1.0
modoboa-stats 1.1.0
modoboa-webmail 1.1.0

Command line shortcuts:

$ pip install modoboa-amavis==1.1.0
$ pip install modoboa-dmarc==1.0.0
$ pip install modoboa-imap-migration==1.1.0
$ pip install modoboa-pdfcredentials==1.1.0
$ pip install modoboa-postfix-autoreply==1.2.0
$ pip install modoboa-radicale==1.1.0
$ pip install modoboa-sievefilters==1.1.0
$ pip install modoboa-stats==1.1.0
$ pip install modoboa-webmail==1.1.0

And please make sure you use the latest version of the django-versionfield2 package:

$ pip install -U django-versionfield2

Notes about quota changes and resellers

Reseller users now have a quota option in Resources tab. This is the quota that a reseller can share between all its domains.

There are two quotas for a domain in the new version:

  1. Quota &
  2. Default mailbox quota.

[1]. Quota: quota shared between mailboxes This quota is shared between all the mailboxes of this domain. This value cannot exceed reseller’s quota and hence cannot be 0(unlimited) if reseller has finite quota.

[2]. Default mailbox quota: default quota applied to mailboxes This quota is the default quota applied to new mailboxes. This value cannot exceed Quota[1] and hence cannot be 0(unlimited) if Quota[1] is finite.

1.6.1

First of all, update postfix map files as follows:

> python manage.py generate_postfix_maps --destdir <path> --force-overwrite

Then, modify postfix’s configuration as follows:

smtpd_sender_login_maps =
    <driver>:<path>/sql-sender-login-mailboxes.cf
    <driver>:<path>/sql-sender-login-aliases.cf
    <driver>:<path>/sql-sender-login-mailboxes-extra.cf

Replace <driver> and <path> by your values.

Finally, reload postfix.

This release also deprecates some internal functions. As a result, several extensions has been updated to maintain the compatibility. If you enabled the notification service, you’ll find the list of available updates directly in your Modoboa console.

For the others, here is the list:

Name Version
modoboa-amavis 1.0.10
modoboa-postfix-autoreply 1.1.7
modoboa-radicale 1.0.5
modoboa-stats 1.0.9

Command line shortcut:

$ pip install modoboa-amavis==1.0.10
$ pip install modoboa-postfix-autoreply==1.1.7
$ pip install modoboa-radicale==1.0.5
$ pip install modoboa-stats==1.0.9

1.6.0

Warning

You have to upgrade extensions due to core.User model attribute change (user.group to user.role). Otherwise, you will have an internal error after upgrade. In particular: modoboa-amavisd, modoboa-stats, modoboa-postfix-autoreply are concerned.

An interesting feature brougth by this version is the capability to make different checks about MX records. For example, Modoboa can query main DNSBL providers for every defined domain. With this, you will quickly know if one the domains you manage is listed or not. To activate it, add the following line to your crontab:

*/30 * * * * <optional_virtualenv_path/>python <modoboa_instance_dir>/manage.py modo check_mx

The communication with Modoboa public API has been reworked. Instead of sending direct synchronous queries (for example to check new versions), a cron job has been added. To activate it, add the following line to your crontab:

0 * * * * <optional_virtualenv_path/>python <modoboa_instance_dir>/manage.py communicate_with_public_api

Please also note that public API now uses TLS so you must update your configuration as follows:

MODOBOA_API_URL = 'https://api.modoboa.org/1/'

Finally, it is now possible to declare additional sender addresses on a per-account basis. You need to update your postfix configuration in order to use this functionality. Just edit the main.cf file and change the following parameter:

smtpd_sender_login_maps =
    <driver>:/etc/postfix/sql-sender-login-mailboxes.cf
    <driver>:/etc/postfix/sql-sender-login-aliases.cf
    <driver>:/etc/postfix/sql-sender-login-mailboxes-extra.cf

1.5.0

The API has been greatly improved and a documentation is now available. To enable it, add 'rest_framework_swagger' to the INSTALLED_APPS variable in settings.py as follows:

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.sites',
    'django.contrib.staticfiles',
    'reversion',
    'rest_framework.authtoken',
    'rest_framework_swagger',
)

Then, add the following content into settings.py, just after the REST_FRAMEWORK variable:

SWAGGER_SETTINGS = {
    "is_authenticated": False,
    "api_version": "1.0",
    "exclude_namespaces": [],
    "info": {
        "contact": "contact@modoboa.com",
        "description": ("Modoboa API, requires a valid token."),
        "title": "Modoboa API",
    }
}

You’re done. The documentation is now available at the following address:

http://<your instance address>/docs/api/

Finally, if you find a TEMPLATE_CONTEXT_PROCESSORS variable in your settings.py file, make sure it looks like this:

TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + [
    'modoboa.core.context_processors.top_notifications',
]

1.4.0

Warning

Please make sure to use Modoboa 1.3.5 with an up-to-date database before an upgrade to 1.4.0.

Warning

Do not follow the regular upgrade procedure for this version.

Some extension have been moved back into the main repository. The main reason for that is that using Modoboa without them doesn’t make sense.

First of all, you must rename the following applications listed inside the MODOBOA_APPS variable:

Old name New name
modoboa_admin modoboa.admin
modoboa_admin_limits modoboa.limits
modoboa_admin_relaydomains modoboa.relaydomains

Then, apply the following steps:

  1. Uninstall old extensions:

    $ pip uninstall modoboa-admin modoboa-admin-limits modoboa-admin-relaydomains
    
  2. Install all extension updates using pip (check the Modoboa > Information page)

  3. Manually migrate database:

    $ cd <instance_dir>
    $ python manage.py migrate auth
    $ python manage.py migrate admin 0001 --fake
    $ python manage.py migrate admin
    $ python manage.py migrate limits 0001 --fake
    $ python manage.py migrate relaydomains 0001 --fake
    $ python manage.py migrate
    
  4. Finally, update static files:

    $ python manage.py collectstatic
    

This version also introduces a REST API. To enable it:

  1. Add 'rest_framework.authtoken' to the INSTALLED_APPS variable

  2. Add the following configuration inside settings.py:

    # Rest framework settings
    
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.TokenAuthentication',
        ),
        'DEFAULT_PERMISSION_CLASSES': (
            'rest_framework.permissions.IsAuthenticated',
        )
    }
    
  3. Run the following command:

    $ python manage.py migrate
    

1.3.5

To enhance security, Modoboa now checks the strength of user passwords <https://github.com/dstufft/django-passwords>_.

To use this feature, add the following configuration into the settings.py file:

# django-passwords

PASSWORD_MIN_LENGTH = 8

PASSWORD_COMPLEXITY = {
    "UPPER": 1,
    "LOWER": 1,
    "DIGITS": 1
}

1.3.2

Modoboa now uses the atomic requests mode to preserve database consistency (reference).

To enable it, update the DATABASES variable in settings.py as follows:

DATABASES = {
    "default": {
        # stuff before...
        "ATOMIC_REQUESTS": True
    },
    "amavis": {
        # stuff before...
        "ATOMIC_REQUESTS": True
    }
}

1.3.0

This release does not bring awesome new features but it is a necessary bridge to the future of Modoboa. All extensions now have their own git repository and the deploy process has been updated to reflect this change.

Another important update is the use of Django 1.7. Besides its new features, the migration system has been reworked and is now more robust than before.

Before we begin with the procedure, here is a table showing old extension names and their new name:

Old name New package name New module name
modoboa.extensions.admin modoboa-admin modoboa_admin
modoboa.extensions.limits modoboa-admin-limits modoboa_admin_limits
modoboa.extensions.postfix_autoreply modoboa-postfix-autoreply modoboa_postfix_autoreply
modoboa.extensions.postfix_relay_domains modoboa-admin-relaydomains modoboa_admin_relaydomains
modoboa.extensions.radicale modoboa-radicale modoboa_radicale
modoboa.extensions.sievefilters modoboa-sievefilters modoboa_sievefilters
modoboa.extensions.stats modoboa-stats modoboa_stats
modoboa.extensions.webmail modoboa-webmail modoboa_webmail

Here are the required steps:

  1. Install the extensions using pip (look at the second column in the table above):

    $ pip install <the extensions you want>
    
  2. Remove south from INSTALLED_APPS

  3. Rename old extension names inside MODOBOA_APPS (look at the third column in the table above)

  4. Remove modoboa.lib.middleware.ExtControlMiddleware from MIDDLEWARE_CLASSES

  5. Change DATABASE_ROUTERS to:

    DATABASE_ROUTERS = ["modoboa_amavis.dbrouter.AmavisRouter"]
    
  6. Run the following commands:

    $ cd <modoboa_instance_dir>
    $ python manage.py migrate
    
  7. Reply yes to the question

  8. Run the following commands:

    $ python manage.py load_initial_data
    $ python manage.py collectstatic
    
  9. The cleanup job has been renamed in Django, so you have to modify your crontab entry:

    - 0 0 * * * <modoboa_site>/manage.py cleanup
    + 0 0 * * * <modoboa_site>/manage.py clearsessions
    

1.2.0

A new notification service let administrators know about new Modoboa versions. To activate it, you need to update the TEMPLATE_CONTEXT_PROCESSORS variable like this:

from django.conf import global_settings

TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
  'modoboa.core.context_processors.top_notifications',
)

and to define the new MODOBOA_API_URL variable:

MODOBOA_API_URL = 'http://api.modoboa.org/1/'

The location of external static files has changed. To use them, add a new path to the STATICFILES_DIRS:

# Additional locations of static files
STATICFILES_DIRS = (
  # Put strings here, like "/home/html/static" or "C:/www/django/static".
  # Always use forward slashes, even on Windows.
  # Don't forget to use absolute paths, not relative paths.
  "<path/to/modoboa/install/dir>/bower_components",
)

Run the following commands to define the hostname of your instance:

$ cd <modoboa_instance_dir>
$ python manage.py set_default_site <hostname>

If you plan to use the Radicale extension:

  1. Add 'modoboa.extensions.radicale' to the MODOBOA_APPS variable

  2. Run the following commands:

    $ cd <modoboa_instance_dir>
    $ python manage.py syncdb
    

Warning

You also have to note that the sitestatic directory has moved from <path to your site's dir> to <modoboa's root url> (it’s probably the parent directory). You have to adapt your web server configuration to reflect this change.