Платформа управления проектами и портфелями ProProject

Инструкция по установке

Аннотация

В данном документе приведены требования к аппаратному и программному обеспечению, а также описания процессов, необходимых для установки ПО «Платформа управления проектами и портфелями ProProject» (далее — «Система» или «ProProject»), в том числе для загрузки и распаковки дистрибутивов ПО с дальнейшей пошаговой инструкцией по настройке всех компонентов Системы.

Система может быть развёрнута двумя способами:

  • в контейнерном окружении Docker (раздел 3) — рекомендуемый способ: все зависимости (Python, PostgreSQL, Redis, Nginx) поставляются в составе образов, настройка хост-системы минимальна;
  • сборкой из исходных кодов непосредственно на сервере (раздел 4) — для случаев, когда использование контейнеров невозможно или инфраструктура заказчика требует установки сервисов на хост.

Содержание


1. Общие требования

1.1 Требования к аппаратному обеспечению

  • Объём оперативной памяти — не менее 8 ГБ.
  • Свободное место на диске — с запасом на базу данных, загружаемые пользователями файлы и (для контейнерной установки) образы Docker.

1.2 Требования к системному программному обеспечению

  • Ubuntu Linux 22.04 LTS или выше, или аналогичный Debian-совместимый дистрибутив. Для контейнерной установки поддерживается любой Linux-дистрибутив с поддержкой Docker.
  • Python 3.13
  • PostgreSQL 16 (поддерживается версия 14 и выше, рекомендуется 16).
  • Redis 7
  • Nginx
  • Для контейнерной установки (раздел 3) из перечисленного на хосте нужен только Docker — Python, PostgreSQL, Redis и Nginx поставляются в образах.

2. Загрузка и распаковка дистрибутива

Дистрибутив Системы состоит из API (backend) и веб-приложения (frontend).

Ссылка для загрузки дистрибутива:

  • Общий архив (API + веб-приложение): https://disk.360.yandex.ru/d/-jGLQP5I2650TA

Архив proproject-server-master.zip распакуйте в директорию /opt/proproject-server, архив proproject-client-master.zip — в директорию /opt/proproject-client.

Предоставьте права на чтение, запись и изменение файлов в этих директориях пользователю, от имени которого будут запускаться сервисы Системы и скрипты node package manager.


3. Запуск в контейнерах (рекомендуемый способ)

3.1 Требования к окружению

На хост-системе должны быть установлены:

  • Docker Engine 24.0 или выше (либо Docker Desktop);
  • Docker Compose v2 (плагин docker compose, входит в состав современных сборок Docker);
  • GNU make — для запуска готовых команд из Makefile.
$ sudo apt update
$ sudo apt install docker.io docker-compose-v2 make
$ sudo usermod -aG docker $USER    # затем перелогиниться

Примечание. Команды в Makefile вызывают docker-compose (Compose v1, через дефис). Если в вашей системе установлен только плагин Compose v2, создайте псевдоним или выполняйте команды напрямую в форме docker compose -f docker-compose.dev.yml --env-file .env.dev -p proproject-server <команда>:

$ echo 'alias docker-compose="docker compose"' >> ~/.bashrc && source ~/.bashrc

Перед запуском убедитесь, что на хосте свободны порты 8000, 8888, 5432, 6379 (в продуктивном профиле дополнительно 80). Занятый порт приводит к ошибке, описанной в п. 3.9.

3.2 Состав контейнерного окружения

В корне дистрибутива находятся два файла описания окружения:

Файл Назначение Файл переменных
docker-compose.dev.yml режим разработки/демо .env.dev
docker-compose.prod.yml продуктивный режим .env.prod

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

Сервис Назначение Порт на хосте
web API (Django) 8000
websocket сервер веб-сокетов для уведомлений 8888
db PostgreSQL 16 (том postgres_data) 5432
redis Redis 7 (брокер Celery и кэш) 6379
celery_worker обработчик фоновых задач
celery_beat планировщик периодических задач
nginx обратный прокси (только prod) 80

3.3 Подготовка файла настроек

Файл настроек Django в дистрибутив не входит — его нужно создать из шаблона:

$ cd /opt/proproject-server
$ cp core/settings/example_dev_settings.py core/settings/settings.py

Откройте core/settings/settings.py и приведите в соответствие как минимум следующие параметры:

  • SECRET_KEY — задайте собственное уникальное значение (в шаблоне указан демонстрационный ключ, использовать его в продуктиве недопустимо);
  • DEBUGTrue для демо-стенда, False для продуктива;
  • ALLOWED_HOSTS — доменные имена и IP-адреса сервера; для локального запуска добавьте 'localhost', '127.0.0.1', '0.0.0.0';
  • CSRF_TRUSTED_ORIGINS — адреса, с которых разрешены запросы;
  • FRONTEND_URL — адрес веб-приложения (используется в письмах);
  • EMAIL_FILE_PATH — в шаблоне указан путь /home/tigran/emails, действительный только на машине разработчика. Для контейнера укажите путь внутри контейнера, например /app/emails, либо настройте отправку через SMTP (параметры EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD).

Параметры подключения к БД и Redis менять не требуется — они читаются из переменных окружения (см. п. 3.4).

3.4 Подготовка файла переменных окружения

Шаблон файла переменных окружения входит в дистрибутив:

$ cp core/configs/example.env .env.dev     # для режима разработки
$ cp core/configs/example.env .env.prod    # для продуктивного режима

Содержимое файла:

# Режим запуска: dev | prod
ENV=dev

# База данных: переменные используются и контейнером postgres, и Django
POSTGRES_DB=proproject
POSTGRES_USER=proproject
POSTGRES_PASSWORD=укажите_надёжный_пароль
DATABASE_HOST=db
DATABASE_PORT=5432

# Redis
REDIS_HOST=redis
REDIS_PORT=6379

Значения DATABASE_HOST=db и REDIS_HOST=redis — это имена сервисов в сети Docker Compose, менять их не нужно. Обязательно задайте собственный пароль в POSTGRES_PASSWORD.

Файлы .env.dev и .env.prod содержат учётные данные и исключены из системы контроля версий — не передавайте их вместе с исходным кодом.

3.5 Сборка и запуск (режим разработки/демо)

$ make build      # сборка образов
$ make up         # запуск всех контейнеров в фоне
$ make ps         # проверка состояния контейнеров
$ make logs       # просмотр логов (Ctrl+C для выхода)

В режиме ENV=dev контейнер web при старте самостоятельно дожидается готовности БД, применяет миграции и запускает отладочный сервер Django. После запуска API доступен по адресу http://<адрес сервера>:8000, сервер веб-сокетов — на порту 8888.

Признак штатного запуска — в выводе make ps все контейнеры находятся в состоянии Up:

NAME                                STATUS         PORTS
proproject-server-celery_beat-1     Up             8000/tcp
proproject-server-celery_worker-1   Up             8000/tcp
proproject-server-db-1              Up             0.0.0.0:5432->5432/tcp
proproject-server-redis-1           Up             0.0.0.0:6379->6379/tcp
proproject-server-web-1             Up             0.0.0.0:8000->8000/tcp
proproject-server-websocket-1       Up             0.0.0.0:8888->8888/tcp

3.6 Первичная инициализация

Проверка и пересчёт вычисляемых полей моделей, создание учётной записи администратора:

$ docker compose -f docker-compose.dev.yml --env-file .env.dev -p proproject-server exec web python manage.py checkdata
$ docker compose -f docker-compose.dev.yml --env-file .env.dev -p proproject-server exec web python manage.py updatedata
$ docker compose -f docker-compose.dev.yml --env-file .env.dev -p proproject-server exec web python manage.py createsuperuser

Команда checkdata сообщает, какие модели требуют пересчёта; updatedata выполняет пересчёт (можно указать конкретную модель: updatedata <appname>.<modelname>).

Восстановление демонстрационной базы данных из дампа (требует доступа к репозиторию с дампом):

$ make restore-db

3.7 Запуск в продуктивном режиме

$ make build-prod
$ make up-prod
$ make ps-prod
$ make logs-prod

В продуктивном профиле дополнительно поднимается контейнер nginx, публикующий Систему на порту 80.

Важно. При ENV=prod контейнер web запускает gunicorn без автоматического применения миграций и сборки статики — эти шаги выполняются вручную:

$ docker compose -f docker-compose.prod.yml --env-file .env.prod -p proproject-server exec web python manage.py migrate
$ docker compose -f docker-compose.prod.yml --env-file .env.prod -p proproject-server exec web python manage.py collectstatic --noinput

Конфигурация Nginx для контейнерного окружения находится в файле core/configs/dockerfile/nginx/nginx.conf и подключается к контейнеру как том. При публикации Системы в интернет отредактируйте её: укажите server_name, добавьте прослушивание 443 порта и пути к SSL-сертификатам.

Учтите две особенности текущей конфигурации продуктивного профиля:

  • в docker-compose.prod.yml в контейнер Nginx монтируются каталоги ./static и ./media, тогда как Django складывает статику в core/static, а загруженные файлы — в core/upload. Приведите пути в соответствие: замените монтирование на ./core/static:/static и ./core/upload:/media либо переопределите STATIC_ROOT и MEDIA_ROOT в core/settings/settings.py;
  • в секции location /socket файла nginx.conf указан адрес http://localhost:8888 — внутри контейнера Nginx это сам контейнер Nginx. Замените адрес на http://websocket:8888 (имя сервиса веб-сокетов в сети Compose).

3.8 Управление и обслуживание

Команда Действие
make up / make up-prod запуск окружения
make down / make down-prod остановка и удаление контейнеров (данные БД в томе сохраняются)
make restart / make restart-prod перезапуск окружения
make logs / make logs-prod просмотр логов
make ps / make ps-prod состояние контейнеров
make restore-db восстановление БД из дампа
make clean удаление контейнеров, томов и образов, включая базу данных

Внимание. make clean безвозвратно удаляет том с базой данных. Перед выполнением сделайте резервную копию:

$ docker compose -f docker-compose.dev.yml --env-file .env.dev -p proproject-server exec db pg_dump -U proproject proproject > backup.sql

3.9 Типовые проблемы

В логах контейнеров websocket и celery_worker: Error -2 connecting to redis:6379. Name or service not known.

Наиболее частая причина — порт 6379 (или 5432) на хосте уже занят другим процессом или контейнером. Контейнер redis при этом не может опубликовать порт, остаётся не подключённым к сети Compose, и его имя перестаёт разрешаться для остальных контейнеров. Проверить:

$ docker ps --format '{{.Names}}\t{{.Ports}}' | grep 6379
$ sudo lsof -nP -iTCP:6379 -sTCP:LISTEN

Освободите порт (остановите занявший его процесс или измените публикуемый порт в docker-compose.dev.yml, например "6380:6379" — внутри сети Compose порт останется 6379), после чего пересоздайте контейнер: простой перезапуск не помогает, так как Compose переиспользует уже созданный контейнер.

$ docker compose -f docker-compose.dev.yml --env-file .env.dev -p proproject-server rm -sf redis
$ make up

Контейнер web завершается с ошибкой relation "<таблица>" already exists.

База данных находится в промежуточном состоянии после прерванного применения миграций. Если данных в ней нет, пересоздайте базу и запустите окружение заново:

$ docker compose -f docker-compose.dev.yml --env-file .env.dev -p proproject-server exec db \
    psql -U proproject -d postgres -c 'DROP DATABASE proproject;' -c 'CREATE DATABASE proproject OWNER proproject;'
$ make up

Ошибка ModuleNotFoundError или No module named 'core.settings.settings' — не создан файл настроек, см. п. 3.3.


4. Альтернативная установка: сборка из исходных кодов на хост-системе

Данный раздел описывает установку Системы непосредственно на сервер, без использования контейнеров. Все команды выполняются в директории /opt/proproject-server.

4.1 Установка системных зависимостей

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install software-properties-common
$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt install python3.13 python3.13-venv python3.13-dev
$ sudo apt install postgresql-16 postgresql-client-16 gcc libpq-dev nginx redis-server \
                   libldap2-dev libsasl2-dev libssl-dev gettext git

Пакеты libldap2-dev, libsasl2-dev и libssl-dev обязательны — без них не собирается зависимость python-ldap, используемая для аутентификации через LDAP.

4.2 Виртуальное окружение и пакеты Python

$ python3.13 -m venv venv
$ source venv/bin/activate
(venv) $ pip install --upgrade pip
(venv) $ pip install -r requirements.txt
(venv) $ pip install gunicorn

4.3 Создание и настройка базы данных

$ sudo -u postgres psql
CREATE USER <username> WITH ENCRYPTED PASSWORD '<user_password>';
ALTER ROLE <username> SET client_encoding TO 'utf8';
ALTER ROLE <username> SET default_transaction_isolation TO 'read committed';
ALTER ROLE <username> SET timezone TO 'UTC';

CREATE DATABASE <db_name> WITH OWNER <username> ENCODING 'UTF8'
    LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8' TEMPLATE template0;

GRANT ALL PRIVILEGES ON DATABASE <db_name> TO <username>;

Где:

  • <db_name> — имя создаваемой базы данных;
  • <username> — имя пользователя;
  • <user_password> — пароль пользователя (указывается в одинарных кавычках).

Выход из psql — команда \q.

Убедитесь, что служба Redis запущена:

$ sudo systemctl enable --now redis-server

4.4 Создание файла настроек

(venv) $ cp core/settings/example_dev_settings.py core/settings/settings.py

Отредактируйте файл core/settings/settings.py, указав в нём параметры подключения к базе данных (см. п. 4.3). Обязательно измените:

  • SECRET_KEY — уникальное значение;
  • DEBUG = False — для продуктивной установки;
  • ALLOWED_HOSTS, CSRF_TRUSTED_ORIGINS, FRONTEND_URL;
  • DATABASES — либо непосредственно значения, либо через переменные окружения POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD, DATABASE_HOST, DATABASE_PORT;
  • REDIS_HOST / REDIS_PORT — при размещении Redis на другом узле (по умолчанию localhost:6379);
  • параметры почты (EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD, DEFAULT_FROM_EMAIL). В шаблоне используется файловый почтовый бэкенд с путём машины разработчика — для продуктива замените его на SMTP.

Подробнее о параметрах Django: https://docs.djangoproject.com/en/5.2/topics/settings/

4.5 Создание структуры базы данных

(venv) $ ./manage.py migrate
(venv) $ ./manage.py checkdata
(venv) $ ./manage.py updatedata
(venv) $ ./manage.py createsuperuser

4.6 Статические файлы и WSGI

(venv) $ mkdir -p core/static
(venv) $ python manage.py collectstatic
$ cp core/configs/example.wsgi.py core/wsgi.py

Статические файлы собираются в core/static, пользовательские загрузки размещаются в core/upload — эти пути используются в конфигурации Nginx (п. 4.9).

4.7 Конфигурационные файлы сервисов systemd

Система состоит из четырёх служб: API, обработчик задач Celery, планировщик Celery Beat и сервер веб-сокетов.

$ sudo cp core/configs/example.proproject.service             /etc/systemd/system/proproject.service
$ sudo cp core/configs/example.proproject-celery.service      /etc/systemd/system/proproject-celery.service
$ sudo cp core/configs/example.proproject-celery-beat.service /etc/systemd/system/proproject-celery-beat.service
$ sudo cp core/configs/example.proproject-ws.service          /etc/systemd/system/proproject-ws.service

В каждом файле проверьте и при необходимости отредактируйте параметры User, Group, WorkingDirectory и путь в ExecStart — в примерах указан пользователь tigran и каталог /opt/proproject-server. Если параметры подключения к БД и Redis задаются переменными окружения, добавьте их в секцию [Service] директивами Environment=.

4.8 Запуск и проверка сервисов

$ sudo systemctl daemon-reload
$ sudo systemctl enable --now proproject proproject-celery proproject-celery-beat proproject-ws
$ sudo systemctl status proproject proproject-celery proproject-celery-beat proproject-ws

4.9 Настройка Nginx для API

$ sudo cp core/configs/example.proproject-server.conf /etc/nginx/sites-available/proproject-server.conf
$ sudo ln -s /etc/nginx/sites-available/proproject-server.conf /etc/nginx/sites-enabled/

Отредактируйте файл:

  • укажите server_name;
  • пропишите пути к SSL-сертификатам (ssl_certificate, ssl_certificate_key);
  • в директиве listen 443; добавьте признак SSL: listen 443 ssl; — без него Nginx будет обслуживать порт 443 в незашифрованном режиме;
  • проверьте пути в location /static/, location /upload/ и путь к сокету gunicorn в location /.

Применение конфигурации:

$ sudo nginx -t
$ sudo systemctl reload nginx

Обновление уже установленной таким способом Системы выполняется скриптом ./update.sh из корня дистрибутива (обновление кода, зависимостей, миграции и перезапуск служб).


5. Установка веб-приложения (frontend)

5.1 Требования

Для сборки веб-приложения на сервере должен быть установлен Node.js (LTS-версия) с пакетным менеджером npm. Требуемая версия указана в файле package.json дистрибутива клиента.

5.2 Настройка Nginx

Перейдите в директорию /opt/proproject-client и выполните:

$ cp deployment/proproject-client.conf proproject-client.conf

Отредактируйте файл proproject-client.conf:

  • укажите выделенное вам имя сервера (параметр server_name);
  • пропишите пути до SSL-сертификатов;
  • проверьте пути в параметре root и во всех параметрах location.

Активируйте конфигурацию:

$ sudo ln -s /opt/proproject-client/proproject-client.conf /etc/nginx/sites-enabled/
$ sudo nginx -t
$ sudo systemctl restart nginx

5.3 Установка зависимостей и подготовка к сборке

$ cp apps/core-project/environments/example_environment.ts      apps/core-project/environments/environment.ts
$ cp apps/core-project/environments/example_environment.prod.ts apps/core-project/environments/environment.prod.ts

В обоих файлах измените параметры API_BASE_PATH и websocketURL, подставив имя или IP-адрес сервера API.

5.4 Сборка

$ ./update.sh

После окончания работы скрипта сборка завершена.


6. Проверка, регистрация и лицензирование

6.1 Проверка

Перейдите на страницу https://<имя или IP-адрес сервера>/. В случае успешной установки откроется приглашение ввести пользователя и пароль.

6.2 Регистрация в системе

Для регистрации и входа перейдите на страницу https://<имя или IP-адрес сервера>/registration и введите email. На указанный адрес придёт ссылка для установки пароля; после установки пароля откроется главный экран Системы.

Для доставки писем должен быть настроен почтовый бэкенд (см. п. 3.3 и 4.4). Если используется файловый бэкенд, ссылка будет сохранена в файл в каталоге EMAIL_FILE_PATH.

6.3 Лицензирование

Операции изменения данных требуют действующей лицензии: при её отсутствии API возвращает код 402 Payment Required. Исключение — обращения с адресов localhost и 127.0.0.1, что позволяет выполнить первичную настройку локально.

Проверка подписи лицензии выполняется по открытому ключу, путь к которому задаётся параметром LICENSE_PUB_KEY в файле настроек. По умолчанию указан тестовый ключ core/keys/test_public.pem — для продуктивной установки укажите путь к ключу, полученному от поставщика вместе с файлом лицензии.