MAATRIX / Блог / Odoo на сервере: частые ошибки и решения

Odoo на сервере: частые ошибки и решения

MAATRIX

Odoo на бумаге разворачивается за десять минут: apt install, конфиг, systemd-юнит — и вот уже открывается веб-интерфейс. Проблемы начинаются позже: после первого реального объёма данных, после апдейта модулей, после того как к системе подключилось больше пяти пользователей одновременно. Ниже — конкретные симптомы, с которыми чаще всего сталкиваются на self-hosted Odoo, и что с ними делать, если вы админите сервер сами, а не через официальный Odoo.sh.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Сервис не запускается или сразу падает

Первый шаг всегда один — смотреть логи, а не гадать:

sudo systemctl status odoo
sudo journalctl -u odoo -f --since "10 min ago"

Если systemd пишет code=exited, status=1, но в журнале пусто — скорее всего, Odoo падает раньше, чем успевает открыть свой логгер. Запустите вручную от имени сервисного пользователя, чтобы увидеть полный traceback:

sudo -u odoo /opt/odoo/venv/bin/python3 /opt/odoo/odoo-bin \
  -c /etc/odoo/odoo.conf --stop-after-init

Типичные причины на этом шаге:

  • Порт занят. Error: [Errno 98] Address already in use — старый процесс не завершился (ps aux | grep odoo-bin, kill) или конфликт с другим сервисом на 8069.
  • Права на filestore. Каталог с вложениями (/opt/odoo/.local/share/Odoo/filestore по умолчанию, либо путь из data_dir в конфиге) должен принадлежать пользователю, от которого запущен сервис. После восстановления из бэкапа через tar или scp владельцем часто остаётся root — Odoo падает с невнятной ошибкой доступа при открытии первого вложения.
  • Не тот Python-venv. Если модуль ставили через pip install в системный Python, а сервис использует venv (или наоборот), при старте будет ModuleNotFoundError. Проверьте, что путь в systemd-юните и путь установки зависимостей совпадают.
  • Синтаксическая ошибка в odoo.conf. Опечатка в секции [options] (например, лишний пробел вокруг =) конфиг-парсер иногда проглатывает молча, а параметр просто не применяется — сверяйте значение через --config и вывод -c при ручном запуске.

PostgreSQL: подключение, роль, кодировка

Odoo требует отдельную роль в PostgreSQL с правом создавать базы (для мультибазового режима) — обычной роли для чтения/записи недостаточно:

sudo -u postgres createuser -s -P odoo

Флаг -s даёт superuser в контексте PostgreSQL — это стандартная практика для Odoo (она сама создаёт и удаляет базы через менеджер баз), но на боевом сервере имеет смысл вместо -s выдать точечные права (CREATEDB, без SUPERUSER) и отключить публичный доступ к менеджеру баз через list_db = False в odoo.conf.

Частые сообщения об ошибках и что за ними стоит:

ОшибкаПричинаРешение
FATAL: password authentication failed for user "odoo"Неверный пароль в odoo.conf или pg_hba.conf требует другой методПроверить db_password в конфиге, метод md5/scram-sha-256 в pg_hba.conf
FATAL: role "odoo" does not existРоль не создана или создана под другим именемcreateuser заново, сверить db_user в конфиге
FATAL: database "odoo" does not existOdoo пытается подключиться к несуществующей базе при стартеУказать -d явно или создать базу через createdb -O odoo odoo
too many connections for role "odoo"max_connections в PostgreSQL меньше, чем нужно воркерам OdooПересчитать лимиты (см. следующий раздел)

Отдельно — кодировка. База обязана быть UTF8 с template0, иначе импорт данных с кириллицей или установка некоторых локализованных модулей (например, российской бухгалтерской локализации) будет падать на этапе загрузки демо-данных:

sudo -u postgres createdb -O odoo -T template0 -E UTF8 --lc-collate=C --lc-ctype=en_US.UTF-8 odoo

Если PostgreSQL стоит на том же сервере, что и Odoo, посмотрите частые ошибки настройки самого PostgreSQL — половина проблем с производительностью Odoo на деле упирается в дефолтные параметры СУБД, которые никто не трогал после установки.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Nginx как reverse proxy: 502, вебсокеты, большие файлы

Держать Odoo с открытым портом 8069 наружу — плохая идея: нет term SSL в одном месте, нет кеширования статики, нет нормальных таймаутов. Стандартная схема — Nginx спереди, Odoo слушает только на 127.0.0.1.

Базовый конфиг:

upstream odoo {
    server 127.0.0.1:8069;
}
upstream odoochat {
    server 127.0.0.1:8072;
}

server {
    listen 443 ssl;
    server_name erp.example.com;

    proxy_read_timeout 720s;
    proxy_connect_timeout 720s;
    proxy_send_timeout 720s;
    client_max_body_size 128m;

    location /websocket {
        proxy_pass http://odoochat;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }

    location / {
        proxy_pass http://odoo;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Что чаще всего ломается:

  • 502 Bad Gateway. Либо Odoo ещё не поднялся (проверьте systemctl status odoo), либо upstream указывает не на тот порт. Если ошибка появляется только под нагрузкой — упирается в workers (раздел ниже).
  • Живой чат/уведомления не работают, а сам интерфейс открывается. Забыт блок /websocket с заголовками Upgrade/Connection, либо не запущен gevent-воркер на порту longpolling_port (по умолчанию 8072) — он поднимается автоматически только когда workers > 0 в конфиге.
  • client_max_body_size слишком мал. При импорте больших XLSX-каталогов товаров или загрузке вложений Nginx обрывает запрос с 413 раньше, чем это увидит сама Odoo.
  • Odoo не видит, что запрос пришёл по HTTPS, из-за чего генерирует ссылки на http:// в письмах и портальных ссылках — нужно выставить proxy_mode = True в odoo.conf, иначе заголовок X-Forwarded-Proto игнорируется.

Разбор похожих ситуаций с самим Nginx как reverse proxy — в отдельной статье про частые ошибки Nginx-прокси.

Воркеры и память: почему сервер уходит в OOM

В конфиге по умолчанию workers = 0 — это однопроцессный режим для разработки, без cron-задач и без вебсокетов в отдельном процессе. На боевом сервере обязательно multiprocessing:

[options]
workers = 5
max_cron_threads = 2
limit_memory_soft = 1610612736
limit_memory_hard = 2147483648
limit_time_cpu = 600
limit_time_real = 1200
limit_request = 8192

Число воркеров считается от ядер CPU: workers = (CPU × 2) + 1, но затем эта цифра проверяется на память, а не только на процессор — часто про это забывают. Каждый воркер под нагрузкой может доходить до limit_memory_hard, значит нужно закладывать:

RAM_для_odoo ≈ workers × limit_memory_hard + (max_cron_threads × limit_memory_hard) + память под PostgreSQL

На 4 ядрах и 8 ГБ RAM формула (4×2)+1 = 9 воркеров даст вполне реальный OOM: 9 × 2 ГБ (hard-лимит) — уже за пределами всей памяти сервера, даже без учёта PostgreSQL и cron-потоков. Практичнее считать не от ядер, а от памяти: возьмите доступную RAM за вычетом ~20% на PostgreSQL и систему и делите на limit_memory_hard.

Если процесс убивает ядро — это видно сразу:

dmesg -T | grep -i "killed process"
journalctl -k | grep -i oom

Резкое падение без записи в логах Odoo почти всегда означает именно OOM-killer, а не баг в коде. Быстрый и правильный ответ — не увеличивать limit_memory_hard, а либо снижать число воркеров, либо добавлять RAM. Своп в этой ситуации не спасает: PostgreSQL и Odoo под своп уходят в такие задержки, что интерфейс становится непригоден к работе раньше, чем сервер реально закончит память — но как аварийная подушка на время миграции полезен, см. как правильно настроить swap на VPS.

Обновление модулей: -u all, миграции, конфликты зависимостей

Апдейт модулей — источник половины тикетов после каждого релиза. Стандартная команда:

sudo -u odoo /opt/odoo/venv/bin/python3 /opt/odoo/odoo-bin \
  -c /etc/odoo/odoo.conf -d odoo --update=all --stop-after-init

Что важно учитывать:

  • Останавливайте сервис перед -u из консоли. Если веб-сервис продолжает принимать запросы, пока идёт миграция схемы БД, вы получите гонку блокировок (could not obtain lock on row) и повреждённое состояние установки модуля.
  • --update=all на боевой базе — долго и рискованно. Обновляйте точечно: --update=имя_модуля,имя_модуля2. Полный апдейт имеет смысл только на staging-копии перед миграцией на новую минорную версию.
  • ParseError while loading views после обновления кастомного модуля почти всегда означает, что XML ссылается на поле или view, которого больше нет в зависимом модуле — проверьте depends в манифесте и порядок загрузки.
  • cannot import name X при старте после pip install нового модуля — конфликт версий пакетов между требованиями Odoo и требованиями стороннего аддона. Держите кастомные аддоны в отдельном venv или фиксируйте версии в requirements.txt, не полагаясь на «поставится последняя».
  • Всегда держите staging-копию с той же версией PostgreSQL и тем же набором аддонов — на ней тестируется апдейт до того, как он идёт на прод. Копия дешевле часа простоя ERP, в которой у людей склад и бухгалтерия.

Бэкапы и восстановление: база плюс filestore

Частая ошибка — бэкапить только базу PostgreSQL и забывать про filestore. В Odoo вложения (сканы, PDF, картинки товаров) по умолчанию хранятся не в базе, а на диске — без них восстановленная база откроется, но все документы будут «битыми» ссылками.

Полный бэкап вручную:

sudo -u postgres pg_dump -Fc odoo > /backup/odoo_$(date +%F).dump
tar -czf /backup/odoo_filestore_$(date +%F).tar.gz \
  /opt/odoo/.local/share/Odoo/filestore/odoo

Восстановление:

sudo -u postgres dropdb odoo
sudo -u postgres createdb -O odoo odoo
sudo -u postgres pg_restore -d odoo /backup/odoo_2026-08-20.dump
tar -xzf /backup/odoo_filestore_2026-08-20.tar.gz -C /opt/odoo/.local/share/Odoo/filestore/
sudo chown -R odoo:odoo /opt/odoo/.local/share/Odoo/filestore/odoo

Через встроенный менеджер баз (/web/database/manager) можно бэкапить и восстанавливать без консоли — но только если он не отключён параметром list_db = False. На проде это правильная настройка ради безопасности: страница менеджера баз с открытым мастер-паролем — частая цель автоматического перебора. Компромисс — держать list_db = False в проде, а бэкапы гонять по cron через pg_dump и хранить admin_passwd вне git и вне дефолтного значения из коробки.

Автоматизацию регулярного бэкапа с ротацией и выгрузкой во внешнее хранилище проще один раз настроить через готовый инструмент, чем поддерживать самописный скрипт — см. установку и настройку BorgBackup, он одинаково хорошо бэкапит и дамп базы, и каталог filestore с дедупликацией между инкрементами.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Сколько RAM закладывать под Odoo для 20-30 пользователей?

Ориентир — от 8 ГБ на связку Odoo + PostgreSQL при 4-5 воркерах, но это сильно зависит от установленных модулей (складской учёт и производство тяжелее CRM) и объёма отчётов, которые пользователи гоняют одновременно. Стартуйте с запасом и смотрите dmesg на признаки OOM в первую неделю под реальной нагрузкой.

Можно ли держать Odoo и PostgreSQL на одном сервере?

Для 10-50 пользователей — да, это обычная практика. Для сотен одновременных сессий или тяжёлой аналитики базу разумно выносить на отдельный сервер, чтобы воркеры Odoo и PostgreSQL не конкурировали за одну и ту же память и диск.

Почему после установки российской локализации падает импорт данных?

Чаще всего база создана не в кодировке UTF8 с template0, либо --lc-collate выставлен не на C — локализованные модули с большим объёмом демо- и справочных данных чувствительны к этому больше стандартных.

Нужен ли выделенный сервер под Odoo или хватит VPS?

Для CRM/ERP на 10-30 человек обычно достаточно VPS на 4 ядра / 8 ГБ. Когда счёт пользователей идёт на сотни, а модулей — на десятки одновременно активных, разумнее считать конфигурацию под нагрузку заранее — например, по расчётам в статье про выделенный сервер под CRM на сотни пользователей.

Как понять, что причина медленной работы — не Odoo, а PostgreSQL?

Включите log_min_duration_statement в PostgreSQL и посмотрите, какие запросы Odoo реально тормозят — почти всегда это либо отсутствующие индексы на кастомных полях, либо разросшийся ir.attachment без очистки старых версий.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →