В данной инструкции мы рассмотрим процесс установки, настройки и использования программы для управления проектами Taiga. Установка будет выполнена на сервер под управлением Rocky Linux (CentOS 8).
Подготовка системы
Установка и настройка компонентов
Установка и настройка Taiga
Настройка SSL
Аутентификация через LDAP
Настройка уведомлений
Подготовка
В качестве предварительных действий мы настроим время сервера, подсистему безопасности 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-адрес сервера> — мы должны увидеть страницу приветствия:
На этом с веб-сервером временно работу заканчиваем.
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 .