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

Section 1. 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 24.04 LTS, Ubuntu 22.04 LTS and Ubuntu 20.04 LTS. Unless specified, all commands apply for these Ubuntu versions.

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

  • 4GB of RAM

  • 10GB 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 15 requires Python 3.8 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 (Ubuntu 20.04 LTS comes with Python 3.8. Ubuntu 22.04 LTS comes with Python 3.10. So there is no need to install Python 3):

sudo apt install build-essential \
  libpq-dev python3-dev

Add the universe repository:

sudo add-apt-repository universe

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 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 -i -u postgres
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

# exit postgres user
exit

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.

Virtual Environment (venv) Preparation

Virtual environments 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.

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 venv). Otherwise, the installation will fail!

Create a virtual environment:

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

Note that you can use whatever name for your virtual environment. Just don’t forget to replace “venv_mysite” with the name you selected when activating the virtual environment.

Activate your virtual environment:

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

You can “deactivate” the venv using:

deactivate

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

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

Virtual Environment on macOS

The command used to create a virtual environment on macOS is the same:

python3 -m venv venv_mysite

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

Creating a New Tendenci Project

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

source /srv/venv_mysite/bin/activate

First of all, upgrade pip, setuptools and wheel

pip install --upgrade pip setuptools wheel

Install Tendenci package:

pip install tendenci --upgrade

Create a new Tendenci project:

sudo mkdir /var/www/ && cd /var/www/
sudo chown "$(id -u -n)" /var/www/
tendenci startproject mysite

Create a directory for the log files that specified in the conf/settings.py for set_app_log_filename and set_debug_log_filename:

sudo mkdir /var/log/mysite

Set up some permissions:

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

Configuring the Site

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.miniwebtool.com/django-secret-key-generator/>

For live sites, add a list of domain names that this Tendenci site can serve to the ALLOWED_HOSTS setting. For testing, the default should be sufficient.

Update the DATABASES 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. Default: ‘US/Central’. A list of time zone names can be found at: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.

Setting up the Site

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

mkdir /var/www/mysite/themes/juniper
# replace 3.10 with your python version
cp -r /srv/venv_mysite/lib/python3.10/site-packages/tendenci/themes/juniper/* /var/www/mysite/themes/juniper/

Initialize the database and load some default data:

cd /var/www/mysite/
python manage.py initial_migrate
python manage.py deploy

python manage.py load_tendenci_defaults
python manage.py update_dashboard_stats
python manage.py rebuild_index --noinput

Set the “Site URL” setting appropriately. Or you can update it later in web interface https://<your-domain-name>/settings/site/global/#id_siteurl:

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

Create an administrator login:

python manage.py createsuperuser

To change the theme (optional if you have your own theme):

python manage.py set_theme <theme name>

Testing

Start Tendenci:

source /srv/venv_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.

Section 2. 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>=15,<16

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

-e /srv/tendenci-git/

Run pip install again:

source /srv/venv_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.

Section 3. Live Site Setup

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

Additional Installation

Install additional system dependencies:

sudo apt install nginx memcached libmemcached-dev

Install additional Python dependencies:

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

Once memcached has been installed, comment out or remove the DummyCache in your conf/settings.py.

CACHES['default']['BACKEND'] = 'django.core.cache.backends.dummy.DummyCache'

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.

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:

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

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

# Owner/group on /srv/venv_mysite/ should already be your normal user account
# Tendenci needs read/search/execute but not write
sudo chmod -R o+rX-w /srv/venv_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/
sudo chmod -R -x+X,g-w,o-rwx /var/www/mysite/
sudo chmod -R ug-x+rwX,o-rwx /var/www/mysite/media/ /var/www/mysite/themes/
sudo 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/venv_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

You’ll need to issue the start and enable commands to start the service and make it run automatically on boot.

To start the service manually:

sudo systemctl start mysite

To start the service automatically on boot:

sudo systemctl enable mysite

If you changed the configuration file, you can restart the service with:

sudo systemctl restart mysite

or issue the reload command:

sudo systemctl reload mysite

To stop the service:

sudo systemctl stop mysite

To disable the service from starting on boot:

sudo systemctl disable mysite

To check the status of the service:

sudo systemctl status 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/venv_mysite/bin/python /var/www/mysite/manage.py run_nightly_commands
10 */6 * * * /srv/venv_mysite/bin/python /var/www/mysite/manage.py process_unindexed

You may also want to check out the Post Installation Checklist.

How far will it 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.

Multiple Sites

To install multiple sites on a single server:

  • Create a unique user and database in PostgreSQL for each site.

  • A unique venv may optionally be created for each site, but is not required. If using multiple virtualenvs, be sure to source the correct venv before running any python or pip commands.

  • You can follow the installation steps above but skip the “System Preparation” part, replace “mysite” with the site name you choose.

  • Configure an additional Systemd Unit file and NGINX configuration file for each site, as well as 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 conf/settings.py.

  • A separate memcached instance for each Tendenci site may optionally be used, but is not required.