Установка и использование Taiga на Rocky Linux

В данной инструкции мы рассмотрим процесс установки, настройки и использования программы для управления проектами Taiga. Установка будет выполнена на сервер под управлением Rocky Linux (CentOS 8).

Подготовка

В качестве предварительных действий мы настроим время сервера, подсистему безопасности SELinux, брандмауэр и hostname.

1. Время

Настраиваем временную зону:

timedatectl set-timezone Europe/Moscow

* В данном примере мы задаем зону по московскому времени. Список всех доступных зон можно посмотреть командой timedatectl list-timezones .

Устанавливаем утилиту для синхронизации времени, разрешаем запуск демона и стартуем его:

yum install chrony

systemctl enable chronyd —now

2 SELinux

В нашем примере мы просто отключим систему безопасности SELinux:

setenforce 0

sed -i ‘s/^SELINUX=.*/SELINUX=disabled/g’ /etc/selinux/config

3. Настройка брандмауэра

Для работы портала нам нужны порты 80 и 443. Откроем их командой:

firewall-cmd —permanent —add-port={80,443}/tcp

И перезапустим firewalld:

firewall-cmd —reload

4. Имя сервера

Сервер Taiga состоит из нескольких компонентов, которые должны обращаться друг к другу. Чтобы запросы правильно отрабатывали, они должны выполняться с использованием FQDN-имени узла. Для гарантии положительного результата мы должны задать имя серверу и прописать его полное имя в файле hosts.

Начнем с имени сервера:

hostnamectl set-hostname taiga.remontka.com

* в моем примере сервер будет иметь имя taiga.remontka.com .

Теперь откроем файл hosts:

vi /etc/hosts

И добавим строку:

127.0.0.1 taiga.remontka.com

* теперь при обращении с нашего сервера на узел taiga.remontka.com мы будем попадать на локальный сервер по адресу 127.0.0.1 .

Компоненты системы

Для работы системы нам нужно установить:

  • Python и средства для создания виртуального окружения.
  • Веб-сервер. В нашем примере, NGINX.
  • База данных Redis.
  • Брокер очередей RabbitMQ.
  • NodeJS.
  • СУБД PostgreSQL.

Рассмотрим пошагово их установку, запуск и, при необходимости, настройку.

Python

Для установки компонента вводим:

dnf install git python38 python38-devel virtualenv

Обновим менеджер установки пакетов pip:

pip3 install —upgrade pip

Установим virtualenvwrapper:

pip3 install virtualenvwrapper

NGINX

Устанавливаем nginx командой:

dnf install nginx

Запускаем сервис:

systemctl enable nginx —now

Откроем браузер и перейдем по адресу http://<IP-адрес сервера> — мы должны увидеть страницу приветствия:

Страница приветствия NGINX в Rocky Linux

На этом с веб-сервером временно работу заканчиваем.

Redis

Установим redis командой:

dnf install redis

Запустим сервис:

systemctl enable redis —now

Попробуем подключиться к командной консоли базы данных:

redis-cli

Сделаем запрос пинг:

> ping

Мы должны увидеть:

PONG

Сервис работает корректно. Выходим:

> exit

RabbitMQ

Выполняем настройку репозитория командами:

curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash

curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash

Теперь можно устанавливать rabbitmq:

dnf install rabbitmq-server

Стартуем сервис:

systemctl enable rabbitmq-server —now

Создаем учетную запись:

rabbitmqctl add_user taiga taiga_password

* в данном примере мы создадим пользователя taiga с паролем taiga_password . Эти данные мы будем использовать при настройке программного продукта.

Создаем виртуальный хост в RabbitMQ:

rabbitmqctl add_vhost taiga

* в нашем примере мы его назвали taiga .

Даем полный доступ пользователю taiga к созданному виртуальному хосту:

rabbitmqctl set_permissions -p taiga taiga «.*» «.*» «.*»

NodeJS

Устанавливаем NodeJS командой:

dnf install nodejs

Готово — проверяем, сделав запрос на показ версии:

node —version

Мы должны увидеть что-то на подобие:

v10.24.0

Идем дальше.

PostgreSQL

Необходимо установить и настроить СУБД PostgreSQL.

1. Начинаем с установки:

dnf install postgresql-server

Выполним инициализацию базы данных:

postgresql-setup initdb

Разрешаем автозапуск и стартуем сервис:

systemctl enable postgresql —now

2. Заходим в систему под пользователем postgres:

su — postgres

Создаем пользователя в СУБД с именем taiga:

$ createuser -P taiga

Система запросит ввести пароль, который должен использоваться для создаваемой записи:

Enter password for new role:
Enter it again:

* по данной инструкции предполагается, что мы ввели пароль taiga .

Входим в консоль управления postgresql:

$ psql

Создадим базу данных taiga , владелец которой будет созданный пользователь taiga :

# CREATE DATABASE taiga OWNER taiga;

# q

Выходим из системы под пользователем postgres:

exit

3. Открываем на редактирование файл:

vi /var/lib/pgsql/data/pg_hba.conf

Добавляем строку:

# TYPE DATABASE USER ADDRESS METHOD
host taiga taiga 127.0.0.1/32 password

* в данном файле важен порядок следования строк, поэтому, желательно, поместить данную строку под строку с комментарием » # TYPE DATABASE… «.

Перезапускаем сервис postgresql:

systemctl restart postgresql

4. Проверим подключение к СУБД под созданным пользователем:

psql -h 127.0.0.1 -U taiga -W

Система запросит пароль — используем тот, что ввели при создании пользователя (в нашем примере, taiga).

Мы должны подключиться к командной строке sql. Выходим:

=> q

Переходим к установке Taiga.

Установка Taiga

Для нормальной работы сервиса нам нужно установить следующие компоненты:

  • Backend.
  • Events.
  • Frontend.

Приступим.

Backend

Процесс установки разобьем по шагам.

1. Создаем каталог, в котором разместим файлы программного обеспечения:

mkdir /var/www

* может быть так, что данный каталог уже создан в вашей системе.

Перейдем в созданный каталог:

cd /var/www

Скачаем программный продукт с GitHub:

git clone -b stable https://github.com/taigaio/taiga-back.git

2. Установим зависимости для python.

Перейдем в каталог с загруженными файлами:

cd taiga-back

Выполним команду:

pip3 install -r requirements.txt

* команда pip выполнит установку компонентов, список которых представлен в файле requirements.txt .

3. Настроим базу данных.

Открываем конфигурационный файл:

vi settings/common.py

Убедимся в корректности настроек подключения к базе данных:

DATABASES = {
«default»: {
«ENGINE»: «django.db.backends.postgresql»,
«NAME»: «taiga»,
«USER»: «taiga»,
«PASSWORD»: «taiga»,
«HOST»: «127.0.0.1»
}
}

* необходимо ввести пароль, который используется в вашей системе. Также необходима корректировка данных, если мы будем использоваться свои имя базы данных и пользователя.

Выполняем команды по настройке:

python3 manage.py migrate —noinput

python3 manage.py loaddata initial_user

python3 manage.py loaddata initial_project_templates

python3 manage.py compilemessages

python3 manage.py collectstatic —noinput

4. Настроим приложение.

Открываем конфигурационный файл:

vi settings/common.py

Используем следующие значения для настроек:


EVENTS_PUSH_BACKEND = «taiga.events.backends.rabbitmq.EventsPushBackend»
EVENTS_PUSH_BACKEND_OPTIONS = {«url»: «amqp://taiga:taiga_password@localhost:5672/taiga»}

SESSION_COOKIE_SECURE = False

CSRF_COOKIE_SECURE = False

MEDIA_URL = «http://taiga.remontka.com/media/»
STATIC_URL = «http://taiga.remontka.com/static/»

TIME_ZONE = «Europe/Moscow»

* где:

  • EVENTS_PUSH_BACKEND — настройка указывает, какую базу использовать для событийных записей. По умолчанию, postgres. Меняем на rabbitmq.
  • EVENTS_PUSH_BACKEND_OPTIONS — опции подключения к rabbitmq. В данном примере мы используем виртуальный хост taiga, а также имя пользователя taiga и пароль taiga_password.
  • SESSION_COOKIE_SECURE и CSRF_COOKIE_SECURE — на практике, я столкнулся с проблемой авторизации при настройках этих опций по умолчанию. В итоге, мне пришлось данные опции отключить.
  • MEDIA_URL и STATIC_URL — указываем URL до файлов медиа и статики. То есть, указываем адрес, по которому будет доступен наш портал.
  • TIME_ZONE — часовой пояс, который должен использоваться в нашей компании.

5. Запустим и протестируем наш бэкэнд.

Запуск сервера можно выполнить командой:

python3 manage.py runserver

Мы должны увидеть что-то на подобие:

Django version 2.2.19, using settings ‘settings.common’
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Теперь откроем второе окно с сессией SSH и введем команду:

curl http://127.0.0.1:8000/api/v1/

В консоль команда должна выкинуть некоторый текст с данными — сервер работает.

6. Настроим автозапуск сервера. Для этого, мы создадим юнит в systemd.

Создаем системного пользователя taiga:

useradd taiga -r

Делаем владельцем taiga каталога с порталом:

chown -R taiga:taiga /var/www/taiga-back

Создаем файл с настройкой юнита в systemd:

vi /etc/systemd/system/taiga.service

[Unit]
Description=taiga_back
After=network.target

[Service]
User=taiga
Environment=PYTHONUNBUFFERED=true
WorkingDirectory=/var/www/taiga-back
ExecStart=/usr/local/bin/gunicorn —workers 4 —timeout 60 -b 127.0.0.1:8000 taiga.wsgi
Restart=on-failure

[Install]
WantedBy=default.target

Перечитываем конфигурацию systemd:

systemctl daemon-reload

Разрешаем автозапуск сервиса taiga и стартуем его:

systemctl enable taiga —now

7. Выполним финальную проверку.

Смотрим состояние запущенного сервиса:

systemctl status taiga

Мы должны увидеть что-то на подобие:

taiga.service — taiga_back
Loaded: loaded (/etc/systemd/system/taiga.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2021-10-29 18:27:33 MSK; 7s ago
Main PID: 14952 (gunicorn)

Также проверяем, что сервер слушает на порту 8000:

ss -tunlp | grep :8000

Мы увидим что-то на подобие:

tcp LISTEN 0 128 127.0.0.1:8000 0.0.0.0:* users:((«gunicorn»,pid=14960,fd=5),(«gunicorn»,pid=14959,fd=5),(«gunicorn»,pid=14957,fd=5),(«gunicorn»,pid=14955,fd=5),(«gunicorn»,pid=14952,fd=5))

Также попробуем выполнить запрос curl:

curl http://127.0.0.1:8000/api/v1/

Система нам должна вернуть не пустой ответ.

Events

Переходим в каталог для хранения файлов с исходниками:

cd /var/www/

Загружаем taiga-events:

git clone -b stable https://github.com/taigaio/taiga-events.git

Выставляем в качестве владельца файлов созданного пользователя taiga:

chown -R taiga:taiga taiga-events

Переходим в скачанный каталог:

cd taiga-events

Выполним установку зависимостей для NodeJS:

npm install

На основе файла-примера создаем файл с настройками:

cp .env.example .env

И откроем его на редактирование:

vi .env

Приведем опции к такому виду:

RABBITMQ_URL=»taiga:taiga_password@localhost:5672″
SECRET=»aw3+t2r(8(0kkrhg8)gx6i96v5^kv%6cfep9wxfom0%7dy0m9e»
WEB_SOCKET_SERVER_PORT=8888
APP_PORT=3023

* где:

  • RABBITMQ_URL — строка подключения к RABBITMQ. Обратите внимание, что мы используем для подключения логин taiga и пароль taiga_password, которые нужно поменять на те, что используются в вашем случае.
  • SECRET — секрет для подключения к бэкэнду. Посмотреть его можно в конфигурационном файле /var/www/taiga-back/settings/common.py .

Для автоматического запуска сервиса, создаем файл:

vi /etc/systemd/system/taiga-events.service

[Unit]
Description=taiga_events
After=network.target

[Service]
User=taiga
WorkingDirectory=/var/www/taiga-events
ExecStart=npm run start:production
Restart=always
RestartSec=3

[Install]
WantedBy=default.target

Перезапустим конфигурацию systemd и запустим сервис taiga-events:

systemctl daemon-reload

systemctl enable taiga-events —now

Проверить статус его работы можно командой:

systemctl status taiga-events

Frontend

Возвращаемся в каталог /var/www:

cd /var/www/

Копируем файлы для фронтенда:

git clone -b stable https://github.com/taigaio/taiga-front-dist.git

Переходим с загруженный каталог:

cd taiga-front-dist

Создаем конфигурационный файл на основе примера:

cp dist/conf.example.json dist/conf.json

Открываем его на редактирование:

vi dist/conf.json

Меняем URL для подключения к backend:

{
«api»: «http://taiga.remontka.com/api/v1/»,

* в нашем примере используется адрес taiga.remontka.com.

Создаем конфигурационный файл для веб-сервера nginx:

vi /etc/nginx/conf.d/taiga.conf

server {
listen 80;
server_name taiga.remontka.com;

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

access_log /var/log/nginx/taiga_access.log;
error_log /var/log/nginx/taiga_error.log;

# Frontend
location / {
alias /var/www/taiga-front-dist/dist/;
index index.html;
try_files $uri $uri/ index.html =404;
}

# API
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:8000/api/;
proxy_redirect off;
}

# Admin
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:8000/admin/;
proxy_redirect off;
}

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

# Media
location /media/ {
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:8003/;
proxy_redirect off;
}

# Events
location /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;
proxy_pass http://127.0.0.1:8888/events;
}
}

* очень важно использовать server_name по имени, которое мы планируем использовать для подключения к сайту. Это же имя должно быть занесено в файл hosts (делали на этапе подготовки системы).

Проверяем корректность настройки nginx:

nginx -t

И если ошибок нет, перечитываем конфигурацию:

systemctl reload nginx

Можно проверять — заходим на портал по адресу http://taiga.remontka.com/ (вы вводите свой адрес.

В качестве логина вводим admin . Пароль по умолчанию — 123123 .

Готово.

HTTPS

Мы рассмотрим пример настройки Taiga для доступа к порталу по защищенному каналу. Для начала необходимо обновить корневой сертификат сервера. Для этого выполняем действия, описанные в инструкции Обновление корневых сертификатов на Linux .

После нам нужно получить сертификат. Его можно купить или получить от Let’s Encrypt — подробнее в инструкции Получение бесплатного SSL сертификата Let’s Encrypt .

После получения сертификата, открываем наш конфигурационный файл в NGINX:

vi /etc/nginx/conf.d/taiga.conf

И верхнюю часть:

server {
listen 80;
server_name taiga.remontka.com;

… меняем на:

server {
listen 80;
server_name taiga.remontka.com;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2;
ssl_certificate /etc/ssl/taiga.remontka.com/public.pem;
ssl_certificate_key /etc/ssl/taiga.remontka.com/private.key;

server_name taiga.remontka.com;

* мы добавили опцию для прослушивания на 80 порту, которая все запросы будет переводить на порт 443. И мы отредактировали секцию server, чтобы сервер слушал на порту 443. Для корректной работы необходимо указать корректные пути до сертификатов.

После вносим изменение в файл:

vi /var/www/taiga-front-dist/dist/conf.json


«api»: » https ://taiga…

* мы меняем http на https .

Теперь открываем файл:

vi /var/www/taiga-back/settings/common.py

И также меняем url:


MEDIA_URL = » https ://taiga.remontka.com/media/»
STATIC_URL = » https ://taiga.remontka.com/static/»

* мы тоже поменяли http на https .

Проверяем настройки веб-сервера:

nginx -t

Перезагружаем его:

systemctl restart nginx taiga

Пробуем зайти на наш портал. Так как данные могут быть закэшированы, обновляем страницу с использованием комбинации Ctrl + F5 .

LDAP аутентификация

Есть официальные плагины, которые позволят нам настроить аутентификацию с использованием учетных записей LDAP. В данном примере, мы будем использовать в качестве активного каталога — сервер FreeIPA .

Выполняем установку плагина командой:

pip3 install taiga-contrib-ldap-auth

Откроем на редактирование наш конфигурационный файл тайги:

vi /var/www/taiga-back/settings/common.py

Добавим в него:

INSTALLED_APPS += [«taiga_contrib_ldap_auth»]
LDAP_SERVER = ‘ldap://freeipa.remontka.com’
LDAP_PORT = 389
LDAP_BIND_DN = ‘uid=taiga,cn=users,cn=accounts,dc=remontka,dc=ru’
LDAP_BIND_PASSWORD = ‘taiga_ldap_user_pass’
LDAP_SEARCH_BASE = ‘cn=users,cn=accounts,dc=remontka,dc=ru’
LDAP_SEARCH_PROPERTY = ‘uid’
LDAP_SEARCH_SUFFIX = None
LDAP_EMAIL_PROPERTY = ‘mail’
LDAP_FULL_NAME_PROPERTY = ‘displayname’

# NOTE: DON’T INSERT ANYTHING AFTER THIS BLOCK

* где обратите внимание на следующие параметры:

  • INSTALLED_APPS — имя подключаемого плагина.
  • LDAP_SERVER — имя нашего сервера ldap.
  • LDAP_BIND_DN — учетная запись для привязки к FreeIPA. Это должна быть учетная запись с минимальными правами. В данном примере, используется имя taiga. Если вы используете другую реализацию, например Active Directory, то полный путь будет другой, а также uid меняем на samaccountmane.
  • LDAP_BIND_PASSWORD — пароль от учетной записи для привязки к ldap.
  • LDAP_SEARCH_BASE — указываем базовую область поиска всех учетных записей в каталоге.
  • LDAP_SEARCH_PROPERTY — имя атрибута, по которому мы должны искать учетную запись.

* также обратите внимание, что данные строки не нужно вставлять в самый конец конфигурационного файла. Это должно быть сделано выше комментария » NOTE: DON’T INSERT ANYTHING AFTER THIS BLOCK «.

После чего перезапускаем сервис taiga:

systemctl restart taiga

Отправляем запрос на наш бэкенд для проверки авторизации по ldap:

curl -X POST -H «Content-Type: application/json» -d ‘{ «type»: «ldap», «username»: «remontka», «password»: «remontka_user_pass» }’ http://taiga.remontka.com/api/v1/auth; history -d $((HISTCMD-1))

* в данном примере мы отправим запрос от учетной записи с логином remontka и паролем remontka_user_pass . Чтобы запрос, содержащий пароль не сохранился в истории введенных команд, мы удалим его с помощью history -d $((HISTCMD-1)) .

Мы должны увидеть данные о пользователе, которых находится в LDAP.

Теперь открываем файл:

vi /var/www/taiga-front-dist/dist/conf.json

И добавляем:

,
«loginFormType»: «ldap»

* обратите внимание, что параметры добавляются через запятую. Не забываем добавить ее в конец предыдущей строки.

Пробуем зайти в систему под учетными данными LDAP.

Настройка почтовых уведомлений

Мы рассмотрим пример использования локального сервера для отправки почты. Для этого нам нужно установить и настроить MTA, в качестве которого мы будем использовать Postfix. Он может быть и не установлен в нашей системе, поэтому сначала выполним его инсталляцию:

yum install postfix cyrus-sasl-plain

После установки разрешаем автозапуск Postfix:

systemctl enable postfix —now

Открываем конфигурационный файл нашего mta:

vi /etc/postfix/main.cf

Приводим к виду:

inet_interfaces = all

inet_protocols = ipv4

myorigin = remontka.com

* значение для inet_interfaces может быть не только localhost .
* если мы используем IPv6, то менять значение опции inet_protocols не нужно.
* где remontka.com — мой домен, который я буду использовать в инструкции в качестве примера.

Не спешим закрывать конфигурационный файл. Добавляем:

message_size_limit = 52428800
smtp_use_tls = yes

* в данном примере мы задали лимит в 50 Мб .

Для применения настроек перезапустим postfix:

systemctl restart postfix

Проверяем, что у нас в системе в качестве MTA по умолчанию выбран Postfix. Вводим команду:

update-alternatives —config mta

Если мы увидим, что у нас не используется postfix (напротив него должен быть +), то меняем значение:

Selection Command
————————————————
*+ 1 /usr/bin/msmtp
2 /usr/sbin/sendmail.postfix

В нашем примере, выбираем 2:

Enter to keep the current selection[+], or type selection number: 2

Открываем конфигурационный файл для сервера тайги:

vi /var/www/taiga-back/settings/common.py

Приведем опции отправки почты, примерно, к такому виду:

# MAIL OPTIONS
DEFAULT_FROM_EMAIL = «noreply-taiga@remontka.com»
EMAIL_BACKEND = ‘django.core.mail.backends.smtp.EmailBackend’
EMAIL_HOST = ‘localhost’
#EMAIL_USE_TLS = True
#EMAIL_USE_SSL = True
#EMAIL_PORT = 587
#EMAIL_HOST_USER = ‘yourusername@gmail.com’
#EMAIL_HOST_PASSWORD = ‘yourpassword’

Перезапустим сервис:

systemctl restart taiga

Для более корректной отправки почты, рекомендую выполнить настройку DKIM по инструкции Настройка DKIM + Postfix .

EnglishRussianUkrainian