User Tools

Site Tools


webapps:taiga

This is an old revision of the document!


How to Install Taiga on Ubuntu 16.04

Standard Server Initialization

Add a standard user for installing packages and for ssh login. Later the taiga user will be added.

$ sudo adduser lain

Add user to the sudo group

$ sudo usermod -aG sudo lain

Update repositories and upgrade packages

$ sudo apt update;apt upgrade

Reboot to ensure any kernel changes are fully installed

$ sudo reboot

Prerequisites

Taiga consists of three modules and each of them require different packages and third-party packages. This sections collects the required packages for a successful Taiga installation and configuration. In this section we will install all dependencies for all modules, including the optional modules and services. Essential packages:

$ sudo apt-get update
$ sudo apt-get install -y build-essential binutils-doc autoconf flex bison libjpeg-dev
$ sudo apt-get install -y libfreetype6-dev zlib1g-dev libzmq3-dev libgdbm-dev libncurses5-dev
$ sudo apt-get install -y automake libtool libffi-dev curl git tmux gettext
$ sudo apt-get install -y nginx
$ sudo apt-get install -y rabbitmq-server redis-server
$ sudo apt-get install -y circus

The component taiga-back uses postgresql (>= 9.4) as database:

$ sudo apt-get install -y postgresql-9.5 postgresql-contrib-9.5
$ sudo apt-get install -y postgresql-doc-9.5 postgresql-server-dev-9.5

Python (3.5) and virtualenvwrapper must be installed along with a few third-party libraries:

$ sudo apt-get install -y python3 python3-pip python-dev python3-dev python-pip virtualenvwrapper
$ sudo apt-get install -y libxml2-dev libxslt-dev
$ sudo apt-get install -y libssl-dev libffi-dev
virtualenvwrapper helps keeping the system clean of third party libraries, installed with the language package manager by installing these packages in an isolated virtual environment.

Restart the shell or run bash to reload the bash environment with the new virtualenvwrapper variables and functions.

This step is mandatory before continuing the installation! Create a user named taiga, and give it root permissions

$ sudo adduser taiga
$ sudo adduser taiga sudo
$ sudo su taiga
$ cd ~
Do not change to root user. The installation must be done with the taiga user.

Configuring Dependencies

Configure postgresql with the initial user and database:

$ sudo -u postgres createuser taiga
$ sudo -u postgres createdb taiga -O taiga --encoding='utf-8' --locale=en_US.utf8 --template=template0

Generate an alpha numeric password for PASSWORD_FOR_EVENTS. I had an issue with creating a password with symbols, if you do, you can place the password in single or double quotations, and this MAY work. I created an alphanumeric password so there was no issue when submitting the command. Create a user named taiga, and a virtualhost for RabbitMQ (taiga-events)

$ sudo rabbitmqctl add_user taiga PASSWORD_FOR_EVENTS
$ sudo rabbitmqctl add_vhost taiga
$ sudo rabbitmqctl set_permissions -p taiga taiga ".*" ".*" ".*"

Create the logs folder (mandatory)

$ mkdir -p ~/logs

Backend configuration

This section helps configuring the backend (api) Taiga service and its dependencies. Download the code

$ cd ~
$ git clone https://github.com/taigaio/taiga-back.git taiga-back
$ cd taiga-back
$ git checkout stable

Create new virtualenv named taiga

$ mkvirtualenv -p /usr/bin/python3.5 taiga

Install dependencies

$ pip install -r requirements.txt

Populate the database with initial basic data

$ python manage.py migrate --noinput
$ python manage.py loaddata initial_user
$ python manage.py loaddata initial_project_templates
$ python manage.py compilemessages
$ python manage.py collectstatic --noinput

This creates the administrator account. The login credentials are admin with password 123123.

To finish the setup of taiga-back, create the intial configuration file for proper static/media file resolution, optionally with email sending support: Copy-paste the following config into ~/taiga-back/settings/local.py and update it with your own details (FQDN, theveryultratopsecretkey, PASSWORD_FOR_EVENTS):

from .common import *
 
MEDIA_URL = "https://example.com/media/"
STATIC_URL = "https://example.com/static/"
SITES["front"]["scheme"] = "https"
SITES["front"]["domain"] = "example.com"
 
SECRET_KEY = "theveryultratopsecretkey"
 
DEBUG = False
PUBLIC_REGISTER_ENABLED = True
 
DEFAULT_FROM_EMAIL = "no-reply@example.com"
SERVER_EMAIL = DEFAULT_FROM_EMAIL
 
#CELERY_ENABLED = True
 
EVENTS_PUSH_BACKEND = "taiga.events.backends.rabbitmq.EventsPushBackend"
EVENTS_PUSH_BACKEND_OPTIONS = {"url": "amqp://taiga:PASSWORD_FOR_EVENTS@localhost:5672/taiga"}
 
# Uncomment and populate with proper connection parameters
# for enable email sending. EMAIL_HOST_USER should end by @domain.tld
#EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
#EMAIL_USE_TLS = False
#EMAIL_HOST = "localhost"
#EMAIL_HOST_USER = ""
#EMAIL_HOST_PASSWORD = ""
#EMAIL_PORT = 25
 
# Uncomment and populate with proper connection parameters
# for enable github login/singin.
#GITHUB_API_CLIENT_ID = "yourgithubclientid"
#GITHUB_API_CLIENT_SECRET = "yourgithubclientsecret"

Frontend installation

Download the code from Github: Download the code

$ cd ~
$ git clone https://github.com/taigaio/taiga-front-dist.git taiga-front-dist
$ cd taiga-front-dist
$ git checkout stable

Copy the example config file:

$ cp ~/taiga-front-dist/dist/conf.example.json ~/taiga-front-dist/dist/conf.json

Edit the example configuration following the pattern below (replace with your own details):

{
    "api": "https://example.com/api/v1/",
    "eventsUrl": "wss://example.com/events",
    "debug": "true",
    "publicRegisterEnabled": true,
    "feedbackEnabled": true,
    "privacyPolicyUrl": null,
    "termsOfServiceUrl": null,
    "GDPRUrl": null,
    "maxUploadFileSize": null,
    "contribPlugins": []
}
Be careful using copy-paste from browser to avoid http duplication.

Having taiga-front-dist downloaded and configured is insufficient. The next step is to expose the code (in dist directory) under a static file web server. In this tutorial We use nginx as a static file web server and reverse-proxy. The configuration of nginx is explained later.

Events installation

This step is optional and can be skipped

Taiga-events is the Taiga websocket server, it allows taiga-front to show realtime changes in the backlog, taskboard, kanban and issues listing. Taiga-events use rabbitmq (the message broker).

Download taiga-events from Github and install its dependencies: Download the code

$ cd ~
$ git clone https://github.com/taigaio/taiga-events.git taiga-events
$ cd taiga-events

Install nodejs

$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
$ sudo apt-get install -y nodejs

Install the javascript dependencies needed

$ npm install
$ sudo npm install -g coffee-script

Copy and edit the config.json file. Update with your rabbitmq uri and the secret key.

$ cp config.example.json config.json

Your config.json should be like:

{
    "url": "amqp://taiga:PASSWORD_FOR_EVENTS@localhost:5672/taiga",
    "secret": "theveryultratopsecretkey",
    "webSocketServer": {
        "port": 8888
    }
}

The 'secret' in config.json must be the same as the “SECRET_KEY” in ~/taiga-back/settings/local.py

Add taiga-events to circus configuration. Copy-paste the code below into /etc/circus/conf.d/taiga-events.ini

[watcher:taiga-events]
working_dir = /home/taiga/taiga-events
cmd = /usr/bin/coffee
args = index.coffee
uid = taiga
numprocesses = 1
autostart = true
send_hup = true
stdout_stream.class = FileStream
stdout_stream.filename = /home/taiga/logs/taigaevents.stdout.log
stdout_stream.max_bytes = 10485760
stdout_stream.backup_count = 12
stderr_stream.class = FileStream
stderr_stream.filename = /home/taiga/logs/taigaevents.stderr.log
stderr_stream.max_bytes = 10485760
stderr_stream.backup_count = 12

Reload the circusd configurations:

$ sudo service circusd restart
$ sudo service circusd status

Start and Expose Taiga

Before moving further, make sure you installed taiga-back and taiga-front-dist, however, having installed them is insufficient to run Taiga.

taiga-back should run under an application server, which in turn, should be executed and monitored by a process manager. For this task we will use gunicorn and circus respectively.

Both taiga-front-dist and taiga-back must be exposed to the outside using a proxy/static-file web server. For this purpose, Taiga uses nginx.

Circus and gunicorn

Circus is a process manager written by Mozilla and Taiga uses it to execute gunicorn. Circus is not only for executing processes, but it also has utils for monitoring them, collecting logs, and restarting processes if something goes wrong, and also for starting processes on system boot. Initial Taiga configuration for circus in /etc/circus/conf.d/taiga.ini

[watcher:taiga]
working_dir = /home/taiga/taiga-back
cmd = gunicorn
args = -w 3 -t 60 --pythonpath=. -b 127.0.0.1:8001 taiga.wsgi
uid = taiga
numprocesses = 1
autostart = true
send_hup = true
stdout_stream.class = FileStream
stdout_stream.filename = /home/taiga/logs/gunicorn.stdout.log
stdout_stream.max_bytes = 10485760
stdout_stream.backup_count = 4
stderr_stream.class = FileStream
stderr_stream.filename = /home/taiga/logs/gunicorn.stderr.log
stderr_stream.max_bytes = 10485760
stderr_stream.backup_count = 4
 
[env:taiga]
PATH = /home/taiga/.virtualenvs/taiga/bin:$PATH
TERM=rxvt-256color
SHELL=/bin/bash
USER=taiga
LANG=en_US.UTF-8
HOME=/home/taiga
PYTHONPATH=/home/taiga/.virtualenvs/taiga/lib/python3.5/site-packages

Circus stats can generate a high cpu usage without any load you can set statsd in /etc/circus/circusd.conf to false if you don’t need them.

Taiga stores logs on the user home, making them available and immediately accessible when you enter a machine. To make everything work, make sure you have the logs directory created.

Final step is restarting circus:

$ sudo service circusd restart

To verify that the services are running, issue:

$ circusctl status

Nginx

Nginx is used as a static file web server to serve taiga-front-dist and send proxy requests to taiga-back.

Let's Encrypt

For SSL add the EFF's PPA for the Let's Encrypt certbot.

$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt update; sudo apt upgrade
$ sudo apt install python-certbot-nginx
$ sudo certbot --nginx certonly

Cert and Key locations:

/etc/letsencrypt/live/domain.tld/fullchain.pem

/etc/letsencrypt/live/domain.tld/privkey.pem

By default, a generic DH key is used which weakens the key exchange. Generate a non-generic Diffie-Hellman key with OpenSSL, the line in the Nginx configuration file has already been added in the config below.

$ sudo openssl dhparam -dsaparam -out /etc/ssl/dhparam.pem 4096

Remove the default nginx config file to avoid collision with Taiga:

$ sudo rm /etc/nginx/sites-enabled/default

Nginx config

To create a new nginx virtualhost for Taiga, create and edit the /etc/nginx/conf.d/taiga.conf file, as follows: Don’t forget to change server_name from “_” to the FQDM!

server {
    listen 80 default_server;
    server_name _;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl default_server;
    server_name _;

    large_client_header_buffers 4 32k;
    client_max_body_size 50M;
    charset utf-8;

    index index.html;

    # Frontend
    location / {
        root /home/taiga/taiga-front-dist/dist/;
        try_files $uri $uri/ /index.html;
    }

    # Backend
    location /api {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:8001/api;
        proxy_redirect off;
    }

    location /admin {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:8001$request_uri;
        proxy_redirect off;
    }

    # Static files
    location /static {
        alias /home/taiga/taiga-back/static;
    }

    # Media files
    location /media {
        alias /home/taiga/taiga-back/media;
    }

    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
    add_header Public-Key-Pins 'pin-sha256="klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY="; pin-sha256="633lt352PKRXbOwf4xSEa1M517scpD3l5f79xMD9r9Q="; max-age=2592000; includeSubDomains';

    ssl on;
    ssl_certificate /etc/nginx/ssl/example.com/ssl-bundle.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com/example_com.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
    ssl_session_cache shared:SSL:10m;
    ssl_dhparam /etc/ssl/dhparam.pem;
    ssl_stapling on;
    ssl_stapling_verify on;

        # Taiga-events
        location /events {
        proxy_pass http://127.0.0.1:8888/events;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
        }
}

Public Key Pinning

Public key pinning increases the security and effectiveness of SSL. If you open the console on a web browser on a site that does not have the correct key in their web server configuration file, it will produce an error. The following command is used to derive the correct key string for PKP to function properly for the site specified.

$ sudo openssl s_client -servername domain.tld -connect domain.tld:443 | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

This will output some text. Example:

ubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64m:443 | openssl x509 -pubkey -noout | openssl pkey -pu
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
verify return:1
depth=0 C = US, ST = California, L = Los Angeles, O = Internet Corporation for Assigned Names and Numbers, OU = Technology, CN = www.example.org
verify return:1
xmvvalwaPni4IBbhPzFPPMX6JbHlKqua257FmJsWWto=

The last line is a key string that you need to replace in the nginx config at line: add_header Public-Key-Pins 'pin-sha256=”<insert string here>”

Finalization

This documentation differs from the official documentation, where it initially checks that nginx will start without SSL. Instead it leads taiga to coming up with working SSL upon first exposure of nginx to the internet. One last command:

$ sudo reboot

Backups

To backup data from your server you just need to store a copy of the database and attachments files. That is, You just need to make a dump of the database and a copy of taiga-back/media directory.

Create dump:

$ pg_dump taiga > taiga.sql

Copy media to a <dest>:

$ cp -r taiga-back/media <dest>

Then You can restore the backup creating a new database to load the dump and copying the media directory:

$ createdb taiga
$ psql taiga < taiga.sql
$ cp -r <dest> taiga-back/media

Upgrading

FIXME

Management

User management on Taiga is not built in, instead you have the option of managing users via the REST API or from the internal django interface. This section only includes the most basic of functions required to manage users.

Django

Django is web framework for python projects. You can edit everything about a project using the Django Admin Interface. This is run manually on localhost port 8000. There are a few things that are required to allow for it to work. You need a user who is admin and superuser, you will have to edit an existing user to give them these credentials. You will also need to start the Django Admin Interface manually in order to access it. The all requires that you have access to a web browser on the server which means you need to run a desktop environment as well.

Change to the proper directory for interacting with django and launch a shell within the django project environment.

$ cd ~/taiga-back
$ workon taiga
$ python manage.py shell

Copy and paste the following commands one line at a time. If everything works correctly you will get no output from any of the commands.1)

>>> from django.contrib.auth import get_user_model
>>> User = get_user_model()
>>> user = User.objects.get(username="myname")
>>> user.is_admin = True
>>> user.is_superuser = True
>>> user.save()
>>> exit()

Now you can start the Django Admin Interface. The server will run in the current terminal session until you Ctrl-C to stop it.

$ python manage.py runserver

Reset password for any user

$ cd ~/taiga-back
$ workon taiga
$ python manage.py changepassword <user>

Enable/Disable public signup

Set publicRegisterEnabled to false,

$ vim /home/taiga/taiga-front-dist/dist/conf.json

Set PUBLIC_REGISTER_ENABLED to False

$ vim /home/taiga/taiga-back/settings/local.py

To disable API access, add these lines to the nginx config:

location /api/v1/auth/register {
    response 405;
}
webapps/taiga.1580652711.txt.gz · Last modified: 2021/06/18 16:36 (external edit)