The setup process is broken into three sections. The first section covers required setup needed in all cases. The second section covers optional additional setup for development purposes. The third section covers recommended but optional setup to prepare for running a live site. Steps required for testing are documented separately.

Basic Setup

If you are new to Tendenci, we recommend you setup a copy on your local system before attempting to install on public hosting. This will allow you to experiment with the setup process, with Tendenci itself, with your site design/layout, and with themes before building a real site. We strongly recommend installing Tendenci within a virtual environment, which will enable you to install/run Ubuntu within your existing OS, and will also make it easy to setup/test/discard multiple copies/configurations of Tendenci.

System Requirements

These instructions cover the installation of Tendenci on a system running Ubuntu 18.04 (recommended) and Ubuntu 16.04.

It should technically be possible to install Tendenci on nearly any Linux, Mac, or Windows system, and some partial instructions for installing on macOS are included below. However, we generally recommend installing Tendenci on Ubuntu, and this process has only been thoroughly tested and documented on Ubuntu.

For testing purposes, we recommend using a virtual machine with at least:

  • 2 CPU cores
  • 3GB of RAM
  • 6GB of storage

If necessary, you may be able to run Tendenci on a VM with as little as 1 CPU core, 2GB of RAM, and 3GB of storage, but you will likely find that to be too slow/constrained even for testing purposes.

Please note that Tendenci 11 requires Python 3.6 or newer.

System Preparation

Make sure Ubuntu is up to date before beginning:

sudo apt update
sudo apt dist-upgrade

Also ensure that Ubuntu is configured to automatically install security updates:

sudo apt install unattended-upgrades update-notifier-common
sudo dpkg-reconfigure -plow unattended-upgrades

Install the required system dependencies:

sudo apt install build-essential \
  libevent-dev libpq-dev \
  libjpeg8 libjpeg-dev libfreetype6 libfreetype6-dev

For Ubuntu 18.04, add the universe repository:

sudo add-apt-repository universe

If on for Ubuntu 16.04 (skip if on 18.04), install Python 3.6 (Ubuntu 16.04 comes with Python 3.5. Ubuntu 18.04 has Python 3.6 installed by default.):

sudo add-apt-repository ppa:jonathonf/python-3.6
sudo apt update
sudo apt install python3.6

Install python3.6-dev and pip:

sudo apt install python3.6-dev --upgrade
curl "https://bootstrap.pypa.io/get-pip.py" | python3.6

System Preparation on macOS

In order for images to correctly render, you will need to install the jpeg libraries:

curl -O http://www.ijg.org/files/jpegsrc.v9.tar.gz
tar -xvzf jpegsrc.v9.tar.gz
cd jpeg-9
./configure
make
sudo make install

To remove the files

cd ..
rm -r jpeg-9
rm jpegsrc.v9.tar.gz

You will also need Xcode 4.4.1 or higher (in the app store) and will need to install the Command Line tools it comes with. To install these, open Xcode, click the “Xcode” menu item in the top left of the screen near the Apple logo, then click “Preferences”, then click “Downloads”. Then click install on the line next to Command Line Tools.

Database Preparation

Tendenci is designed for use with PostgreSQL.

It may be technically possible to use Tendenci with other databases, but Tendenci has only been tested with PostgreSQL and is not expected to work with other databases without some significant development effort.

Install PostgreSQL and some required modules:

sudo apt install postgresql postgresql-contrib postgis

Create a user and database for Tendenci in PostgreSQL (Replace DB_USER, DB_PASS and DB_NAME with an appropriate user name, password, and database name):

# switch to the "postgres" user assuming installation above went correctly
sudo -u postgres -s
DB_USER=mysite
echo "DB_USER="$DB_USER
DB_PASS=mysite
echo "DB_PASS="$DB_PASS
DB_NAME=mysite
echo "DB_NAME="$DB_NAME

Verify what you typed is what you intended. Next create your database still as the ‘postgres’ user:

psql -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASS';"
psql -c "ALTER ROLE $DB_USER SET client_encoding TO 'UTF8';"
psql -c "ALTER ROLE $DB_USER SET default_transaction_isolation TO 'read committed';"
psql -c "CREATE DATABASE $DB_NAME WITH OWNER $DB_USER;"
psql -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
psql -d $DB_NAME -c "CREATE EXTENSION postgis;"
psql -d $DB_NAME -c "CREATE EXTENSION postgis_topology;"
psql -d $DB_NAME -c "CREATE EXTENSION fuzzystrmatch;"
psql -d $DB_NAME -c "CREATE EXTENSION postgis_tiger_geocoder;"

# confirm your database was created correctly
psql -l

# deactivate the postgres user reverting back to "root"
exit
# verify path statement reads as your admin Ubuntu user which is by default "root"
whoami
# this should return something like:
root@tendenci:/home/ed# whoami
root

Database Preparation on macOS

To install PostgreSQL on macOS, we recommend using Postgres.app

If you would like a database GUI, we recommend PGAdmin

The commands shown above for creating the database and user on Ubuntu should also work on macOS.

If you are still in “sudo postgres” mode, meaning your command prompt reads “postgres@localhost”, you need to exit from the “sudo postgres” by typing “exit” which should return you to “root” or the admin account.

Virtualenv Preparation

Virtualenv enables a complete Python environment to be stored within a single directory, which helps keep the system clean, and makes it easy to run multiple versions of Python, Python libraries, or Tendenci within a single VM or server. While not strictly required, we recommend using virtualenv with Tendenci.

Please make sure, that you only use root permissions where advised! (Please do NOT sudo or install as root as that defeats the purpose of a virtualenv). Otherwise, the installation will fail!

Prepare a virtualenv for Tendenci:

# whoami - make sure you are NOT "root". If so, type "exit" to back up one level.
sudo apt-get install virtualenv
sudo mkdir -p /srv
sudo chown "$(id -u -n)" /srv/
cd /srv/
python3.6 -m virtualenv -p python3.6 mysite
sudo chown root /srv/

To use the virtualenv, you must “activate” it:

source /srv/mysite/bin/activate
# verify you are in the venv environment you created
which python
/srv/mysite/bin/python

You can “deactivate” the virtualenv using:

deactivate

Activating the virtualenv adjusts your $PATH so that running python, pip, or other commands will run the versions in the virtualenv instead of the versions installed in the base system.

The pip in the virtualenv automatically installs Python libraries into the virtualenv without modifying the base system. The python in the virtualenv automatically uses the Python libraries within the virtualenv instead of any system-level libraries.

Note that you must “activate” the virtualenv every time you open a new terminal or SSH session. If your command prompt does not begin with (mysite), then you have not activated the virtualenv, and any python or pip commands you run will use the system versions of those commands instead of the virtualenv versions, which may have unexpected results.

Maybe also consider virtualenvwrapper in your VM for convenience.

Virtualenv on macOS

To prepare a virtualenv for Tendenci:

virtualenv -p venv

If you have anaconda installed on your machine, you must specify the path to the version of Python that you would like to use:

virtualenv -p /Library/Frameworks/Python.framework/Versions/3.6/bin/python3 venv

The commands shown above for activating/deactivating the virtualenv on Ubuntu should also work on macOS.

Tendenci Installation

If you have not already activated your virtualenv, make sure you do so before continuing:

source /srv/mysite/bin/activate

Install Django:

pip install "Django>=1.11,<2.0"

Create a new Django project based on the Tendenci template:

sudo mkdir /var/www/
sudo chown "$(id -u -n)" /var/www/
cd /var/www/
django-admin.py startproject --template=https://github.com/tendenci/tendenci-project-template/archive/master.zip mysite
sudo chown root /var/www/

Set up some directories appropriately:

chmod -R -x+X /var/www/mysite/media/
mkdir /var/www/mysite/whoosh_index
sudo mkdir /var/log/mysite
sudo chown "$(id -u -n)": /var/log/mysite/

Install Tendenci and its dependencies:

cd /var/www/mysite/
pip install --no-binary psycopg2 -r requirements/dev.txt --upgrade

Tendenci Configuration

Edit /var/www/mysite/conf/settings.py

For testing, uncomment DEBUG = True

Set SECRET_KEY and SITE_SETTINGS_KEY to two different random strings, each at least 50 characters in length. Random strings are conveniently available at <https://www.grc.com/passwords.htm> (Use the “63 random alpha-numeric characters” string, and refresh the page to get an additional string.)

For live sites, set ALLOWED_HOSTS appropriately. For testing, the default should be sufficient.

Configure the database settings using the user name, password, and database name you configured in the “Database Preparation” section above.

Set TIME_ZONE to the local time zone configured on the system running Tendenci.

Tendenci Preparation

Copy “tendenci2018” theme to the themes directory (adjust your path if your virtualenv path is different or you’re running a different python version rather than python 3.6):

mkdir /var/www/mysite/themes/tendenci2018
cp -r /srv/mysite/lib/python3.6/site-packages/tendenci/themes/t7-tendenci2018/* /var/www/mysite/themes/tendenci2018/

Initialize the database and static files:

cd /var/www/mysite/
python manage.py initial_migrate
python manage.py deploy
chmod -R -x+X /var/www/mysite/media/
python manage.py load_tendenci2018_defaults
python manage.py update_dashboard_stats

Set the “Site URL” setting appropriately:

python manage.py set_setting site global siteurl 'https://www.example.com'

Create an administrator login in Tendenci:

python manage.py createsuperuser

To change the theme (optional):

python manage.py set_theme <theme name>

Testing

Start Tendenci:

source /srv/mysite/bin/activate
cd /var/www/mysite/
python manage.py runserver

Then open http://localhost:8000/ in your browser to see your Tendenci site!

Hit CTRL-C to exit from python manage.py runserver

If you only plan to use this Tendenci installation for demonstration / testing purposes, you can stop here. If you intend to do development or run a live site, continue with one of the next two sections.

Development Setup

This section covers additional recommended setup if you plan to do development work on Tendenci itself.

Install and configure git (replace the name and email with appropriate values):

sudo apt-get install git
git config --global user.name "John Doe"
git config --global user.email "john.doe@example.com"

Note

See this Github help article for instructions.

Clone the Tendenci repository:

cd /srv/
git clone https://github.com/tendenci/tendenci.git tendenci-git

Edit /var/www/mysite/requirements/tendenci.txt and comment out tendenci>=8,<9

Edit /var/www/mysite/requirements/common.txt and add:

-e /srv/tendenci-git/

Run pip install again:

source /srv/mysite/bin/activate
cd /var/www/mysite/
pip install -r requirements/dev.txt --upgrade

Apply any database and static media updates that are in the development version of Tendenci but are not yet in the released version of Tendenci:

python manage.py migrate
python manage.py deploy

You can now edit files under /srv/tendenci-git/ and/or run git pull to retrieve the latest changes from GitHub. python manage.py runserver should immediately pick up your changes, so you can view them simply by reloading the page in your browser.

Live Site Setup

This section covers additional recommended setup to prepare for running a live site.

You may want to check the Django documentation and PostgreSQL documentation for database configuration/tuning suggestions.

Additional Configuration

Review the comments and examples in /var/www/mysite/conf/settings.py to determine if any additional settings should be configured for your live site.

How far will it scale?

But first, how far will Tendenci scale?

Scalability is one of Tendenci’s strengths, with memory as your limit. t2 instances at AWS scale, Linode (or similar) offer the best economics for clients with fewer than 10k active users.

There are Tendenci installations with significantly over 100k active users. Those usually self host (for example regulatory reasons) but you should have no problem whatsoever with fewer than 100k users on a large VM with a lot of RAM.

Once you cross 100k people, deployments will almost certainly need a combination of multiple front end servers, central authentication, and a cluster database.

Additional Installation

Install additional system dependencies:

sudo apt install nginx memcached libmemcached-dev

Install additional Python dependencies:

source /srv/mysite/bin/activate
cd /var/www/mysite/
pip install -r requirements/prod.txt --upgrade

Permissions

When using the Systemd configuration below, Tendenci will run as the www-data user. To ensure that Tendenci has appropriate permissions when running as www-data:

chmod -R o+rX /srv/mysite/
sudo chgrp -Rh www-data /var/www/mysite/
chmod -R g+rwX /var/www/mysite/media/ /var/www/mysite/themes/
chmod -R g+rwX /var/www/mysite/whoosh_index/
sudo chown -Rh www-data /var/log/mysite/
chmod -R g+rwX /var/log/mysite/

For security, you should also ensure that there are no unnecessary permissions:

# Owner/group on /srv/mysite/ should already be your normal user account
# Tendenci needs read/search/execute but not write
chmod -R o+rX-w /srv/mysite/
# Owner on /var/www/mysite/ should already be your normal user account,
# group should be www-data
# Tendenci needs read/search but not execute, write is only needed on media, themes, and
# whoosh_index, other users do not need any access
sudo chgrp -Rh www-data /var/www/mysite/
chmod -R -x+X,g-w,o-rwx /var/www/mysite/
chmod -R ug-x+rwX,o-rwx /var/www/mysite/media/ /var/www/mysite/themes/
chmod -R ug-x+rwX,o-rwx /var/www/mysite/whoosh_index/
# Owner on /var/log/mysite/ should be www-data,
# group should be some group that includes your normal user account but not other inappropriate
# users (Ubuntu creates a dedicated group for each user by default, so this command uses that)
# Tendenci and the assigned group need read/write/search but not execute, other users do not
# need any access (The assigned group needs write access so your normal user account can run
# `python manage.py ...`)
sudo chown -Rh www-data:"$(id -u -n)" /var/log/mysite/
sudo chmod -R -x+X,g+rw,o-rwx /var/log/mysite/

Note that these permissions should allow your normal user account to manage/upgrade Tendenci without using sudo, which is safer than performing management/upgrades using sudo.

Systemd Setup

Systemd Unit files should be created in /etc/systemd/system/ with a name of your choice (eg mysite.service). The contents of your unit file should look like this:

[Unit]
Description=Start Tendenci instance
#Requires=nginx.service postgresql.service
#Wants=memcached.service
#Before=nginx.service
#After=postgresql.service

[Service]
WorkingDirectory=/var/www/mysite
PIDFile=/run/mysite.pid
Type=forking
KillMode=process
Restart=on-failure
ExecStart=/srv/mysite/bin/gunicorn                    \
          --user www-data                               \
          --group www-data                              \
          --workers 4                                   \
          --bind=127.0.0.1:8000                         \
          --pid=/run/mysite.pid                       \
          --pythonpath=/var/www/mysite                \
          --access-logfile=/var/log/mysite/access.log \
          --error-logfile=/var/log/mysite/server.log  \
          --capture-output                              \
          --daemon                                      \
         conf.wsgi

[Install]
WantedBy=multi-user.target

To start the service manually:

sudo systemctl start mysite

To start the service automatically on boot:

sudo systemctl enable mysite

logrotate Setup

Create /etc/logrotate.d/mysite containing:

/var/log/mysite/*.log {
  daily
  minsize 100k
  missingok
  rotate 14
  compress
  create 0660 www-data www-data
  sharedscripts
  postrotate
    service mysite restart
  endscript
}

To ensure that the log files remain readable/writable by your normal user account, change the second www-data in create 0660 www-data www-data to a group that includes your normal user account but not other inappropriate users (Ubuntu creates a dedicated group for each user by default with the same name as the associated user, so you can use that here).

NGINX Setup

First, make an NGINX configuration file for the site. This will be created at /etc/nginx/sites-available/mysite and should look like this:

server {
    listen 80;
    server_name localhost;

    charset utf-8;
    keepalive_timeout 65;
    client_max_body_size 30M;
    gzip_types text/css application/javascript text/javascript text/plain text/xml application/xml;
    gzip_vary on;

    root /var/www/mysite/;

    location /static/ {
        access_log off;
        expires 30d;
    }

    location /media/ {
        access_log off;
        expires 30d;
    }

    location ^~ /media/export/ {
        return 404;
    }

    location ~ /themes/([a-zA-Z0-9\-\_]+)/(media|static)/ {
        access_log off;
    }

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:8000/;
    }
}

Be sure to update the server_name domain name and root path appropriately.

Next, create a symlink to the new file and remove the default symlink:

ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/mysite
rm /etc/nginx/sites-enabled/default

Finally, restart the NGINX service:

sudo service nginx restart

EMail Setup (if needed)

You can run Tendenci through AWS SES or any other SMTP relay using python directly via settings.py. As a best practice we recommend ElasticStack with alerts at scale. If you absolutely need a mail server (rkhunter for example), you can install postfix.

sudo apt-get install postfix

During installation, you will see 3 prompts which you must respond to in order to complete the installation. If the server is already configured with a domain name, enter that domain in the prompts. Otherwise, leave the defaults in place.

Configuration of mail servers is difficult. Be careful. Check the docs on Postfix for proper configuration.

memcached Setup

memcached is a service that can be used to speed up access to web pages by caching them in the systems memory for future use.

Tendenci is configured to use memcache automatically once it is installed as described in the “Additional Installation” section above.

If you wish you increase the amount of memory memcache uses, edit /etc/memcached.conf and change the “-m” value from 64 to your desired cache size in MB.

Cron Setup

Tendenci has two management commands that should be run on a regular basis.

run_nightly_commands is used to handle tasks like membership notices, event reminders, and periodic cleanup.

process_unindexed handles search indexing.

Run sudo -u www-data crontab -e and add the following lines:

30   2 * * * /srv/mysite/bin/python /var/www/mysite/manage.py run_nightly_commands
10 */6 * * * /srv/mysite/bin/python /var/www/mysite/manage.py process_unindexed

Multiple Sites

To install multiple sites on a single server:

  • Create a unique user and database in PostgreSQL for each site.
  • A unique virtualenv may optionally be created for each site, but is not required. If using multiple virtualenvs, be sure to source the correct virtualenv before running any python or pip commands.
  • You can skip the pip install "Django" command, but otherwise follow the “Tendenci Installation”, “Tendenci Configuration”, and “Tendenci Preparation” steps above. Change the last parameter of the django-admin.py startproject ... command to create a different /var/www/<project>/ directory for each site, then change /var/www/mysite/ in all of the commands in the instructions to work with the appropriate site.
  • Configure an additional Systemd Unit file and NGINX configuration file for each site, and configure additional cron jobs for each site. Each site will need to run on a different port internally, so change 8000 in the example Systemd and NGINX configurations to a unique port number for each site. Also change the names of any log files in the configuration.
  • A separate memcached instance for each Tendenci site may optionally be used, but is not required.