NocoDB на сервере: частые ошибки и решения
NocoDB превращает обычную PostgreSQL или MySQL в интерфейс уровня Airtable — с таблицами, вьюхами, формами и API из коробки. На бумаге всё просто: поднял контейнер, подключил базу, работай. На практике на собственном VPS вылезает десяток нюансов, которых нет в официальной документации: контейнер падает через сутки, вебхуки не долетают, права на файлы конфликтуют между обновлениями, а миграция между версиями иногда рвёт метаданные. Разберём эти ситуации по порядку — с конкретными командами и конфигами, а не общими советами «перезапустите контейнер».
Содержание
- Базовая установка через Docker Compose
- Контейнер падает или перезапускается по кругу
- Потеря данных и конфликты прав на volume
- Reverse proxy, HTTPS и WebSocket-подключения
- Подключение внешней базы данных: типичные ошибки
- Обновление версии без потери настроек
- Медленный интерфейс при росте числа таблиц и записей
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Базовая установка через Docker Compose
Правильная точка старта — не docker run из README, а полноценный compose-файл с отдельной базой данных и постоянными томами. NocoDB умеет работать на встроенном SQLite, но для сервера, который должен пережить перезагрузку и рост данных, это тупиковый путь — SQLite не выдерживает параллельных запросов при активной работе нескольких пользователей.
services:
nocodb-db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: nocodb
POSTGRES_PASSWORD: change_me_strong
POSTGRES_DB: nocodb
volumes:
- ./pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U nocodb"]
interval: 10s
timeout: 5s
retries: 5
nocodb:
image: nocodb/nocodb:latest
restart: unless-stopped
depends_on:
nocodb-db:
condition: service_healthy
ports:
- "127.0.0.1:8080:8080"
environment:
NC_DB: "pg://nocodb-db:5432?u=nocodb&p=change_me_strong&d=nocodb"
NC_AUTH_JWT_SECRET: замените_на_случайную_строку_32+_символа
NC_PUBLIC_URL: https://nocodb.example.com
volumes:
- ./nc-data:/usr/app/data
Здесь уже заложены три вещи, которые часто забывают: healthcheck для базы (иначе NocoDB стартует раньше PostgreSQL и падает в цикл рестартов), привязка порта только к localhost (наружу пускает reverse proxy) и отдельный volume под /usr/app/data — там хранятся вложения и часть метаданных, не только в базе.
Контейнер падает или перезапускается по кругу
Самая частая жалоба — NocoDB уходит в Restarting (1) через несколько минут после старта. Причины делятся на три группы.
База данных недоступна при старте. Если не указать depends_on с condition: service_healthy, Compose запускает оба контейнера одновременно, NocoDB пытается подключиться к ещё не готовому PostgreSQL, падает с ошибкой подключения и уходит в рестарт-луп. Проверяется командой:
docker compose logs nocodb --tail 50
Если в логах ECONNREFUSED на порт базы — дело в порядке старта, решение — healthcheck, как в примере выше.
Не хватает памяти. NocoDB на Node.js при импорте больших CSV или при построении сложных вьюх может съедать 500 МБ – 1 ГБ оперативной памяти на пике. На VPS с 1 ГБ RAM это заканчивается OOM-killer, который тихо убивает процесс — в системном логе это видно так:
dmesg | grep -i "killed process"
journalctl -k | grep -i oom
Если видите там node — либо увеличивайте память (для рабочей команды с несколькими базами разумный минимум — 2 ГБ), либо добавьте swap как временную подушку:
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
Swap не решает проблему производительности при постоянной нехватке памяти, но спасает от жёстких падений при разовых пиках нагрузки.
Конфликт версии Node внутри образа и старых томов. После обновления образа NocoDB иногда не может прочитать кэш из предыдущей версии в volume nc-data. Симптом — падение сразу после апгрейда с ошибкой парсинга во внутренней БД метаданных. Здесь помогает только откат образа на предыдущий тег и миграция по инструкции ниже, а не удаление тома — в нём ваши данные.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПотеря данных и конфликты прав на volume
NocoDB хранит данные в двух местах одновременно: в подключённой базе (сами таблицы и записи) и в служебной БД метаданных (структура проекта, вьюхи, права пользователей, вложения). Это создаёт риск рассинхронизации, если вы, например, восстанавливаете PostgreSQL из бэкапа, а volume nc-data остаётся старым — NocoDB покажет несуществующие таблицы или наоборот не увидит существующие.
Правило простое: бэкапить нужно оба слоя синхронно, одним снимком по времени.
# бэкап базы данных
docker compose exec nocodb-db pg_dump -U nocodb nocodb > backup_$(date +%F).sql
# бэкап volume с метаданными и вложениями
tar -czf nc-data_$(date +%F).tar.gz ./nc-data
Вторая частая беда — права доступа на файлы после переноса volume между серверами через rsync или scp без флага -a. Контейнер NocoDB работает от непривилегированного пользователя внутри образа, и если владелец файлов на хосте после переноса стал root, при следующем старте контейнер не может писать вложения и тихо роняет загрузку файлов пользователями. Проверка и исправление:
ls -la nc-data
chown -R 1000:1000 nc-data # UID процесса внутри контейнера nocodb/nocodb
Точный UID стоит свериться в актуальном образе (docker compose exec nocodb id), потому что он менялся между релизами — не полагайтесь на 1000 как на константу для всех версий.
Reverse proxy, HTTPS и WebSocket-подключения
NocoDB активно использует WebSocket для realtime-обновлений в интерфейсе (когда несколько человек редактируют одну таблицу). Если reverse proxy не пробрасывает Upgrade-заголовки, интерфейс формально работает, но обновления между вкладками не приходят, а иногда сыплются ошибки в консоли браузера про разрыв соединения.
Рабочий конфиг для nginx:
server {
listen 443 ssl http2;
server_name nocodb.example.com;
ssl_certificate /etc/letsencrypt/live/nocodb.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nocodb.example.com/privkey.pem;
client_max_body_size 50m; # иначе загрузка вложений больше 1 МБ падает с 413
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_header;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600s;
}
}
Три детали, которые чаще всего упускают: client_max_body_size (дефолт nginx — 1 МБ, вложения-картинки в него не влезают), proxy_read_timeout (долгие операции вроде импорта большого CSV обрываются по таймауту прокси раньше, чем успевает ответить NocoDB) и обязательная пара Upgrade/Connection "upgrade" для WebSocket. Если используете Caddy вместо nginx, проброс WebSocket там работает автоматически без ручной настройки заголовков — это одна из причин, почему для быстрого старта Caddy иногда удобнее.
Подключение внешней базы данных: типичные ошибки
Главное преимущество NocoDB — способность работать поверх уже существующей продакшн-базы, не копируя данные. Но именно тут возникает больше всего путаницы.
Неверный формат строки подключения. NocoDB ожидает специфичный синтаксис в NC_DB, отличный от привычного postgresql://:
NC_DB=pg://host:5432?u=user&p=password&d=database
Если пароль содержит спецсимволы (@, #, &), их нужно URL-кодировать, иначе строка парсится неправильно и NocoDB подключается не туда или падает с ошибкой аутентификации, которая выглядит как неверный пароль — хотя пароль верный.
Недостаточные права пользователя БД. Для полноценной работы (создание вьюх, изменение схемы через интерфейс) пользователю нужны права не только на чтение/запись данных, но и на DDL-операции в конкретной схеме:
GRANT ALL PRIVILEGES ON SCHEMA public TO nocodb_user;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO nocodb_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO nocodb_user;
Если хотите дать NocoDB доступ только на чтение к продакшн-базе (частый сценарий — аналитика поверх боевых данных без риска что-то сломать), учтите, что часть функций интерфейса (создание вьюх с сохранением, комментарии к записям) в read-only режиме работать не будет — NocoDB пытается писать служебные метаданные в ту же схему.
Таймауты на медленных запросах к большим таблицам. Если таблица на миллионы строк, дефолтный вид со всеми колонками без индексов по фильтруемым полям вызывает таймаут при первой загрузке. Решение — не в NocoDB, а на стороне PostgreSQL и его индексов: добавьте индексы на поля, по которым чаще всего фильтруете и сортируете во вьюхах.
Обновление версии без потери настроек
NocoDB развивается быстро, и мажорные обновления иногда меняют формат внутренних метаданных. Общая безопасная процедура:
# 1. Синхронный бэкап базы и volume (см. раздел выше) — обязательно перед любым апгрейдом
docker compose exec nocodb-db pg_dump -U nocodb nocodb > backup_pre_upgrade.sql
tar -czf nc-data_pre_upgrade.tar.gz ./nc-data
# 2. Смотрим changelog конкретной версии на предмет breaking changes
# 3. Обновляем тег образа в compose-файле, не latest, а конкретную версию
В compose-файле стоит зафиксировать версию явно (nocodb/nocodb:0.263.5, например), а не тянуть latest — тогда обновление становится осознанным действием, а не случайностью после docker compose pull в рамках другой задачи. Если после апгрейда интерфейс не открывается или показывает ошибку миграции метаданных — откатите тег на предыдущую рабочую версию и восстановите nc-data из бэкапа, сделанного перед апгрейдом, прежде чем разбираться дальше.
Отдельно стоит проверять место на диске перед апгрейдом — миграции метаданных иногда создают временные копии данных, и на почти заполненном диске процесс обрывается на середине, оставляя базу в промежуточном состоянии. Мониторить занятое место можно простым:
df -h /var/lib/docker
Медленный интерфейс при росте числа таблиц и записей
Когда в проекте становится больше 50-100 таблиц или отдельные таблицы разрастаются до сотен тысяч строк, интерфейс NocoDB может заметно тормозить — долго прогружается список таблиц в сайдбаре, вьюхи с фильтрами открываются с задержкой. Это ожидаемое поведение для инструмента такого класса, а не баг конкретно вашей установки, но смягчить можно несколькими способами:
- Выносите редко используемые проекты в отдельные базы вместо накопления всего в одной схеме.
- Для таблиц с большим числом строк создавайте вьюхи с предустановленными фильтрами вместо показа всей таблицы целиком — это снижает нагрузку и на NocoDB, и на PostgreSQL.
- Следите за ресурсами сервера: если PostgreSQL не настроен под реальную нагрузку (дефолтные
shared_buffersиwork_memрассчитаны на слабое железо), торможение интерфейса NocoDB часто оказывается симптомом непротюненной базы, а не проблемой самого приложения. - Ограничьте число одновременных realtime-подключений через reverse proxy, если NocoDB используют десятки человек одновременно — WebSocket-соединения на слабом VPS тоже расходуют память.
Если после всех настроек интерфейс всё равно медленный при разумном объёме данных — вероятная причина в недостатке CPU у сервера, а не в конфигурации: сборка сложных вьюх с джойнами по нескольким таблицам — процессорноёмкая операция на стороне Node.js-бэкенда NocoDB.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли запустить NocoDB без Docker, напрямую через npm?
Да, npx create-nocodb-app разворачивает приложение без контейнеров, но тогда вы сами отвечаете за версию Node.js, автозапуск через systemd и обновления — на сервере, который должен работать без присмотра, Docker Compose проще поддерживать в стабильном состоянии.
Почему после смены пароля в переменной NC_DB NocoDB не подключается?
Переменные окружения в уже запущенном контейнере не обновляются на лету — нужно пересоздать контейнер командой docker compose up -d --force-recreate nocodb, обычного restart недостаточно.
Безопасно ли давать NocoDB прямой доступ к продакшн-базе без прокси-слоя?
Технически да, но разумнее заводить для NocoDB отдельного пользователя БД с ограниченными правами на конкретную схему, а не суперпользователя — это снижает ущерб при компрометации самого NocoDB.
Что делать, если после обновления пропали вьюхи, а таблицы на месте?
Вьюхи хранятся в служебных метаданных, а не в самой базе — восстановите nc-data из бэкапа, сделанного до апгрейда, вместо попыток пересоздать вьюхи вручную.
Нужен ли отдельный VPS под NocoDB или его можно поставить рядом с другими сервисами?
Для небольшой команды достаточно общего сервера с другими контейнерами, если ресурсов хватает с запасом; для активной работы с большими таблицами и несколькими проектами лучше выделить NocoDB и его базу на отдельный сервер, чтобы пики нагрузки не задевали соседние сервисы.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →