====== 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=””**''
===== 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 :
$ cp -r taiga-back/media
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 taiga-back/media
===== Upgrading =====
FIXME
===== Management =====
User management on Taiga is not built in, instead you have the option of managing users via the [[https://taigaio.github.io/taiga-doc/dist/api.html|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.((https://gist.github.com/Brachamul/f41ee36ae2b127b99fdfd1e81d4b9f6e))
>>> 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
====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;
}