Удельта

Пошаговая инструкция · Самостоятельная установка

Как установить OpenProject на Ubuntu с Docker Compose

Пошаговая инструкция для самостоятельной установки. Установим OpenProject Community Edition для команды: настроим отдельный домен, защищённый вход, почту, первый проект и копии базы с вложениями.

Запуск первого проекта на рабочем столе с макетом, этапами и папкой вложений

Что подготовить и как читать инструкцию #

Используем официальный Compose, где сайт, фоновые обработчики, PostgreSQL и кеш запускаются отдельными контейнерами. Это рекомендованный разработчиком Docker-вариант для дальнейшего обслуживания. Одноконтейнерный образ удобен для знакомства, но здесь он не нужен: нам важно отдельно копировать базу и обновлять компоненты. Возможности системы описаны на странице OpenProject.

Для небольшой команды начальная оценка — 4 vCPU, 8 ГБ RAM и SSD от 80 ГБ с запасом для вложений и базы. Сверьте её с руководством выбора сервера OpenProject: число активных проектов, документов и одновременных пользователей важнее общего числа зарегистрированных людей.

Команды выполняйте в терминале сервера после подключения по SSH, если шаг не указывает другое место. sudo даёт команде права администратора. Действия в браузере выполняйте на своём компьютере. Домены, IP-адреса и значения ВАШ_ПАРОЛЬ из примеров заменяйте своими до выполнения команды.

Двигайтесь по одному шагу и проверяйте результат перед следующим. Блок с <<EOF или другим именем завершения копируйте целиком: он записывает содержимое одного файла. При работе в nano сохраняйте файл клавишами Ctrl+O, Enter и выходите Ctrl+X. Если прервали SSH-сеанс, снова перейдите в указанный каталог; переменные предыдущего сеанса потребуется задать заново.

HTTPS оформляется через официальный Certbot; Nginx и сертификаты обслуживаются на хосте.

Шаг 1. Скачайте официальный комплект #

Создадим каталог и получим Compose из ветки stable/17. Это описание согласованного набора сервисов: веб-приложения, обработчика задач и базы.

Скачайте официальный комплект
sudo install -d -o "$USER" -g "$(id -gn)" -m 750 /opt/openproject
git clone --depth=1 --branch=stable/17 https://github.com/opf/openproject-docker-compose.git /opt/openproject
cd /opt/openproject

Клонирование завершилось; текущий каталог — /opt/openproject.

Шаг 2. Сохраните ревизию и файл настроек #

Запишем ревизию скачанных файлов для восстановления этой установки и создадим рабочий .env. Каталог assets должен принадлежать UID 1000 — пользователю контейнера, который пишет вложения.

Сохраните ревизию и файл настроек
git rev-parse HEAD > deployment-commit.txt
cp .env.example .env
chmod 600 .env
sudo install -d -o 1000 -g 1000 -m 750 /var/openproject/assets

deployment-commit.txt и .env существуют; каталог assets создан с указанным владельцем.

Шаг 3. Подготовьте три разных секрета #

Выполните генератор три раза. Результаты предназначены для SECRET_KEY_BASE, COLLABORATIVE_SERVER_SECRET и POSTGRES_PASSWORD. Hex-строка удобна в строке подключения: её не нужно кодировать как URL.

Подготовьте три разных секрета
openssl rand -hex 32
openssl rand -hex 32
openssl rand -hex 32

Сохранены три разных значения; ни одно не является словом REPLACE.

Шаг 4. Заполните .env #

Откройте nano .env и измените указанные строки по образцу. Пароль POSTGRES_PASSWORD и пароль внутри DATABASE_URL должны совпасть. HOST__NAME — домен без https://, PORT привязывает внутренний сайт к localhost, wss:// нужен совместному редактору. Остальные настройки файла сохраните.

Заполните .env
TAG=17.9.1-slim
OPENPROJECT_HOST__NAME=projects.example.com
OPENPROJECT_HTTPS=true
PORT=127.0.0.1:8080
SECRET_KEY_BASE=REPLACE_WITH_RANDOM_APP_SECRET
COLLABORATIVE_SERVER_URL=wss://projects.example.com/hocuspocus
COLLABORATIVE_SERVER_SECRET=REPLACE_WITH_RANDOM_COLLAB_SECRET
POSTGRES_VERSION=17
POSTGRES_PASSWORD=REPLACE_WITH_RANDOM_DB_PASSWORD
DATABASE_URL=postgres://postgres:REPLACE_WITH_RANDOM_DB_PASSWORD@db/openproject?pool=20&encoding=unicode&reconnect=true
OPDATA=/var/openproject/assets
PGDATA=/var/lib/postgresql/data

Все REPLACE заменены. .env содержит ваш домен и три сохранённых секрета.

Шаг 5. Установите Nginx и Certbot #

В этой схеме HTTPS завершает Nginx. Контейнеры слушают внутренний порт, а Nginx на хосте обслуживает HTTPS. Используем Certbot из snap; не смешивайте его с пакетом Certbot из apt.

Установите Nginx и Certbot
sudo apt update
sudo apt install nginx snapd

Пакеты установлены; ваш домен указывает на сервер, 80/443 разрешены у провайдера.

Шаг 6. Установите Certbot из snap #

Плагин Nginx включён в официальный snap Certbot. Используем один способ установки: если Certbot уже установлен через apt, не ставьте поверх него вторую версию; сначала разберите имеющуюся настройку. Для чистого сервера выполните команду ниже.

Установите Certbot из snap
sudo snap install --classic certbot

Certbot установлен. Дальше вызывайте /snap/bin/certbot: путь не зависит от наличия другой команды certbot в PATH.

Шаг 7. Проверьте описание сервисов #

Вернёмся в каталог приложения и попросим Compose прочитать YAML и переменные. Это проверка конфигурации, ещё без запуска.

Проверьте описание сервисов
cd /opt/openproject
sudo docker compose config --quiet

config --quiet завершился без сообщений об ошибках.

Шаг 8. Запустите сервисы OpenProject #

Первый запуск также собирает нужные образы и подготавливает базу. Дождитесь завершения, не запускайте вторую установку параллельно.

Запустите сервисы OpenProject
sudo docker compose up -d --build --pull always

Команда завершилась успешно; перейдите к журналу подготовки.

Шаг 9. Проверьте подготовку базы #

ps покажет сервисы, а журнал seeder — подготовку данных. Seeder может завершиться после успешного выполнения; постоянно работающие web и worker не должны перезапускаться.

Проверьте подготовку базы
sudo docker compose ps
sudo docker compose logs --tail=80 seeder web worker

В журналах нет ошибки подключения к базе; web и worker работают.

Шаг 10. Создайте сайт для проверки домена #

Ниже временный сайт обслуживает только файлы проверки Certbot. Во всём шаблоне замените projects.example.com своим доменом.

Создайте сайт для проверки домена
sudo install -d -m 755 /var/www/acme
sudo tee /etc/nginx/sites-available/openproject >/dev/null <<'NGINX'
server {
    listen 80;
    server_name projects.example.com;
    root /var/www/acme;
    location /.well-known/acme-challenge/ { try_files $uri =404; }
    location / { return 404; }
}
NGINX
sudo ln -sfn /etc/nginx/sites-available/openproject /etc/nginx/sites-enabled/openproject

Конфигурация записана и подключена в sites-enabled.

Шаг 11. Примените временный сайт #

Сначала выполните nginx -t. Только после successful выполните reload. Это правило действует при каждом изменении Nginx.

Примените временный сайт
sudo nginx -t && sudo systemctl reload nginx

Nginx принял конфигурацию; при ошибке продолжать к сертификату нельзя.

Шаг 12. Получите сертификат #

Certbot обращается к вашему домену через HTTP-сайт. Почта нужна для уведомлений; она не создаёт пользователя OpenProject.

Сертификат выпускается через webroot, поэтому deploy-hook перечитывает Nginx после успешного продления. Certbot сохраняет этот параметр для следующих запусков; это нужно, чтобы Nginx начал выдавать новый сертификат.

Получите сертификат
sudo /snap/bin/certbot certonly --webroot -w /var/www/acme \
  -d projects.example.com --email admin@example.com --agree-tos --deploy-hook "systemctl reload nginx"

Сертификат выпущен для вашего домена.

Шаг 13. Запишите HTTPS-конфигурацию #

Заменим временный сайт полным шаблоном. Он передаёт запросы локальному порту 8080 и поддерживает WebSocket для совместного редактора. Замените домен во всех строках, включая пути сертификатов.

Запишите HTTPS-конфигурацию
sudo tee /etc/nginx/sites-available/openproject >/dev/null <<'NGINX'
map $http_upgrade $openproject_connection {
    default upgrade;
    '' close;
}
server {
    listen 80;
    server_name projects.example.com;
    location /.well-known/acme-challenge/ {
        root /var/www/acme;
        try_files $uri =404;
    }
    location / { return 301 https://$host$request_uri; }
}
server {
    listen 443 ssl;
    server_name projects.example.com;
    ssl_certificate /etc/letsencrypt/live/projects.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/projects.example.com/privkey.pem;
    client_max_body_size 100M;
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $openproject_connection;
        proxy_read_timeout 3600s;
    }
}
NGINX

Файл сохранён; upstream остаётся локальным.

Шаг 14. Примените HTTPS и проверьте продление #

После успешного nginx -t перечитайте настройки. Dry-run проверяет, что сертификат сможет продлеваться по тому же маршруту.

Примените HTTPS и проверьте продление
sudo nginx -t && sudo systemctl reload nginx
sudo /snap/bin/certbot renew --dry-run
systemctl list-timers --all 'snap.certbot.renew*'

Все три команды успешны. Ошибку продления разберите до приглашения команды.

У таймера snap.certbot.renew есть следующий запуск. Не закрывайте TCP 80: проверка домена при продлении использует тот же webroot.

Шаг 15. Смените начальный пароль #

Откройте https://projects.example.com. Для первого входа используйте начальные реквизиты из официального комплекта, обычно admin/admin; сразу смените пароль на уникальный. Если ваша версия показывает другой порядок, следуйте её журналу подготовки.

Вход с новым паролем работает, стандартный пароль больше не подходит.

Шаг 16. Создайте проект и первую задачу #

Создайте небольшой тестовый проект. Добавьте задачу с названием, сроком и исполнителем; сохраните и откройте её повторно. Так проверяем запись в базу, а не только загрузку страницы.

Задача сохранилась и появляется в списке работ проекта.

Шаг 17. Подключите почту и второго пользователя #

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

Приглашение пришло; участник видит проект и может выполнить разрешённое действие, но не управляет сервером.

Шаг 18. Проверьте внешний доступ и фоновые задачи #

В каталоге установки проверим сервисы, журнал, HTTPS и слушающие порты. Порт 8080 должен быть привязан к 127.0.0.1; вход снаружи идёт через 443.

Проверьте внешний доступ и фоновые задачи
cd /opt/openproject
sudo docker compose ps
sudo docker compose logs --since=15m web worker cron db hocuspocus
curl -I https://projects.example.com/
sudo ss -lntp | grep -E ':(80|443|8080)[[:space:]]'

Нет повторных рестартов, HTTP-ответ успешен, 8080 не слушает внешний интерфейс.

Шаг 19. Подготовьте штатную копию #

Предупредите пользователей о перерыве. Внешние данные не удаляем: down без -v останавливает сервисы, затем собираем официальный вспомогательный образ backup.

Подготовьте штатную копию
cd /opt/openproject
sudo docker compose down
sudo docker compose -f docker-compose.yml -f docker-compose.control.yml build

Остановка и сборка завершились успешно; тома данных сохранены.

Шаг 20. Создайте резервную копию #

Запустим штатный backup из управляющего Compose. Найдите результат в каталоге копий, указанном его выводом, и перенесите в закрытое внешнее хранилище. Ошибка backup означает, что пригодной копии пока нет.

Создайте резервную копию
sudo docker compose -f docker-compose.yml -f docker-compose.control.yml run --rm backup

Копия включает базу и вложения. Проверьте её восстановление на отдельном сервере до первого большого обновления.

Шаг 21. Верните приложение в работу #

Снова запустите основные сервисы. Откройте тестовую задачу и вложение, убедитесь, что обработчик задач работает. Новые версии вводите после копии и проверки release notes.

Верните приложение в работу
sudo docker compose up -d

Проект доступен, задача и вложение на месте.

Если результат шага отличается #

Вернитесь к проверке того шага, на котором появилась ошибка. Первая ошибка в выводе обычно полезнее последних строк: последующие команды могли не получить нужный файл или работающую службу. Не повторяйте установку целиком поверх частично настроенного приложения.

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

Обсудить установку и настройку

Материал был полезен?

Сообщить об ошибке или задать вопрос редакции

Сообщение увидит редакция. Не указывайте пароли и личные данные. Текст удаляется через 180 дней.

О материале

ИнфраструктураРуководствоЗадача: установитьУровень: практикаOpenProject

Последнее обновление:

Обсуждение

Комментарии проходят подтверждение адреса и проверку редакцией.