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

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

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

MAATRIX

Coolify обещает «свой Vercel на своём сервере» и обещание держит — ровно до первой нештатной мелочи. Панель не открывается, сервер помечен как unreachable, сборка падает с кодом 137, приложение отдаёт 502. Почти все ошибки Coolify укладываются в полтора десятка сценариев и чинятся за минуты, если знать, в каком слое искать.

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

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

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

Сначала триаж: у Coolify три независимых слоя

Половина потерянного времени уходит на то, что чинят не тот слой. Начинайте с docker ps --filter name=coolify — здоровый инстанс выглядит так:

NAMES              STATUS                PORTS
coolify            Up 6 days (healthy)   0.0.0.0:8000->8080/tcp
coolify-realtime   Up 6 days (healthy)   0.0.0.0:6001-6002->6001-6002/tcp
coolify-db         Up 6 days (healthy)   5432/tcp
coolify-redis      Up 6 days (healthy)   6379/tcp
coolify-proxy      Up 6 days             0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp

Первый слой — панель: coolify (Laravel и очередь Horizon), база coolify-db, кэш coolify-redis, вебсокет coolify-realtime. Второй — прокси coolify-proxy (Traefik v3 на портах 80 и 443), он же выпускает сертификаты. Третий — контейнеры приложений: они переживают перезапуск панели без последствий.

Логи смотрите по слоям: docker logs coolify --tail=200 — панель и очередь, docker logs coolify-proxy — маршруты и ACME.

Отдельный случай — деплой висит в статусе Queued: умер воркер очереди внутри панели. Выполните docker exec -it coolify php artisan horizon:status, и если ответ Horizon is inactive. вместо Horizon is running. — чинит обычный docker restart coolify.

Панель не открывается, логи деплоя не обновляются

docker ps показывает healthy, но http://IP:8000 не отвечает. В девяти случаях из десяти это фаервол — системный ufw или сетевой фильтр провайдера. Нужны ufw allow 22/tcp (первым, иначе ufw enable с политикой deny выкинет вас из SSH), затем 80/tcp, 443/tcp, 8000/tcp для панели и 6001/tcp для вебсокета.

Второй симптом — панель открывается, но логи деплоя не текут, приходится жать F5. Это оборванный вебсокет: в консоли браузера будет WebSocket connection to 'ws://203.0.113.10:6001/app/coolify' failed. Причина — закрытый 6001 либо несовпадение адреса панели с записанным в APP_URL.

Лечение — не открывать 6001 наружу, а повесить на инстанс домен: Settings → Configuration → Instance Domain, вписать https://coolify.example.com и сохранить. Дальше Coolify проксирует и панель, и вебсокет через 443, а лишние порты закрываются. Нюанс: править APP_URL руками в /data/coolify/source/.env без перезапуска стека бесполезно. За Cloudflare нужны ещё WebSockets в разделе Network и режим SSL/TLS Full (strict): на Flexible панель уйдёт в редирект-петлю, а сертификат не выпустится — почему Coolify не выдаёт SSL.

Третий сценарий: coolify-proxy не стартует, в логах Bind for 0.0.0.0:80 failed: port is already allocated. Значит, на хосте уже есть nginx или apache. Найдите занявшего (ss -tlnp | grep ':80 ') и уберите: systemctl disable --now nginx.

Развернуть за пару минут

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

Развернуть Coolify

После обновления или переезда: права и «The MAC is invalid»

Обновление идёт из панели или командой curl -fsSL https://cdn.coollabs.io/coolify/upgrade.sh | bash. Частая поломка после апдейта — контейнер coolify в рестарт-лупе, а в docker logs coolify однозначное:

The stream or file "/var/www/html/storage/logs/laravel.log" could not be opened
in append mode: Failed to open stream: Permission denied

Это сбитые права: внутри контейнера приложение работает под UID 9999, лечится парой chown -R 9999:root /data/coolify и chmod -R 700 /data/coolify. Если же в логе SQLSTATE[08006] [7] connection to server at "coolify-db" failed — смотрите docker logs coolify-db, обычно Postgres не поднялся из-за кончившегося диска.

Переезд на другой сервер — самая дорогая ошибка. Человек копирует каталог /data/coolify без файла source/.env, панель открывается, а при открытии любого приложения падает The MAC is invalid.. Секреты, переменные окружения и приватные SSH-ключи лежат в базе зашифрованными ключом APP_KEY из .env, и новым ключом их не расшифровать: переносить надо каталог целиком, вместе с source/.env, где лежат APP_KEY, DB_PASSWORD и REDIS_PASSWORD.

Отсюда правило бэкапа: копию .env держите отдельно, дамп снимайте командой docker exec coolify-db pg_dump -U coolify coolify | gzip > /root/coolify-$(date +%F).sql.gz. Честный минус: кнопки «откатить обновление» в Coolify нет, спасает только снапшот диска.

«Server is not reachable»: Coolify не может зайти сам к себе

Неочевидная деталь: Coolify управляет сервером по SSH даже когда это тот же сервер, где он и стоит — контейнер панели ходит на хост через host.docker.internal и логинится root'ом по ключу. Когда цепочка рвётся, сервер краснеет с надписью «Server is not reachable».

Причина первая — публичный ключ пропал из /root/.ssh/authorized_keys. Пересоздать пару:

ssh-keygen -t ed25519 -a 100 -N '' -C root@coolify \
  -f /data/coolify/ssh/keys/id.root@host.docker.internal
cat /data/coolify/ssh/keys/id.root@host.docker.internal.pub >> /root/.ssh/authorized_keys
chown 9999 /data/coolify/ssh/keys/id.root@host.docker.internal

И обязательно вставьте новый приватный ключ в панели: Keys & Tokens → Private Keys, иначе в базе останется старый.

Причина вторая — sshd. Проверяйте эффективный конфиг, а не файл: sshd -T | grep -E 'permitrootlogin|allowusers'. Значение prohibit-password нормально, а permitrootlogin no или allowusers deploy заблокируют доступ.

Причина третья, самая коварная, — фаервол режет трафик с docker-мостов: хост видит подключение с адреса вида 172.17.0.2, и правило «22 порт только с моего IP» отсекает Coolify заодно с чужаками. Лечится строкой ufw allow from 172.16.0.0/12 to any port 22 proto tcp. Вход по ключу проверяется с хоста: ssh -i /data/coolify/ssh/keys/id.root@host.docker.internal root@localhost 'docker version' — вернулась версия демона (в 2026-м обычно 27.x или 28.x), значит, ключ и sshd в порядке.

Сборка падает: код 137, кончился диск, не тянутся образы

Exit code 137. В логе деплоя вы видите:

#14 [builder 5/5] RUN npm run build
#14 ERROR: process "/bin/sh -c npm run build" did not complete successfully: exit code: 137

137 — это 128 + 9, процесс убит SIGKILL, и убил его OOM-killer ядра; подтверждение в dmesg -T | grep -iE 'killed process|out of memory'. Сборка фронтенда — самый прожорливый этап пайплайна: на Next.js или крупном Vite-проекте npm run build просит 2,5–3,5 ГБ и на VPS с 2 ГБ умрёт.

Быстрый костыль — swap: fallocate -l 4G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile плюс строка /swapfile none swap sw 0 0 в /etc/fstab. Честный минус: swap вытаскивает сборку, но если в него уедет работающее приложение, отклик сайта просядет. Второй приём — NODE_OPTIONS=--max-old-space-size=3072 с обязательной галкой Build Variable: без неё переменная видна только в рантайме. Та же галка нужна всем NEXT_PUBLIC_* и VITE_* — забыли, и в бандле окажется undefined.

No space left on device. Выглядит как failed to compute cache key: write /var/lib/docker/tmp/buildkit-mount123: no space left on device. Смотрим docker system df на сервере, где Coolify живёт полгода без присмотра:

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          34        11        21.4GB    14.8GB (69%)
Local Volumes   9         6         3.11GB    640MB (20%)
Build Cache     286       0         18.7GB    18.7GB

Каждый деплой среднего фронтенда оставляет 1,5–2,5 ГБ слоёв и кэша: тридцать-сорок деплоев — и 40 ГБ диска нет. Чистка — docker builder prune -f --filter until=72h и docker image prune -af --filter until=168h, а лучше включить уборку в Server → Advanced с порогом занятости диска (около 80%).

Осторожно: не запускайте docker system prune -a --volumes — под --volumes попадут тома остановленных баз, и Postgres, притушенный «на минутку», исчезнет с данными. И помните: со старыми образами уходит возможность откатиться на предыдущий деплой.

Образ не тянется. С российских IP это отдельный сюжет 2026 года:

ERROR: failed to resolve source metadata for docker.io/library/node:22-alpine:
Head "https://registry-1.docker.io/v2/library/node/manifests/22-alpine": dial tcp: i/o timeout

Docker Hub с российских адресов отдаёт отказ или таймаут, а Nixpacks ходит в cache.nixos.org, который отвечает через раз. Лечится зеркалом реестра в /etc/docker/daemon.json (секция "registry-mirrors" — зеркала живут недолго, проверяйте актуальность) либо сервером за пределами РФ. Учтите: systemctl restart docker перезапустит и контейнеры Coolify.

Собралось и запустилось, но отдаёт 502 или 404

502 Bad Gateway значит, что Traefik нашёл маршрут, но не достучался до контейнера. Причина номер один — поле Ports Exposes: Coolify по умолчанию ставит туда 3000, и если приложение слушает 8080 или 5000, прокси стучится не туда. Причина номер два — приложение слушает 127.0.0.1 внутри контейнера, а это его собственный локалхост, снаружи туда не попасть. Проверка: docker exec -it <контейнер> sh -c 'ss -tlnp || netstat -tlnp' — нужна строка 0.0.0.0:3000, а не 127.0.0.1:3000. Лечится в приложении: next start -H 0.0.0.0, vite preview --host 0.0.0.0, HOST=0.0.0.0 для Express, gunicorn --bind 0.0.0.0:8000 для Python. Причина номер три — healthcheck: приложение поднимается дольше отведённого, контейнер висит unhealthy, и прокси его не берёт.

404 page not found — ответ самого Traefik: маршрута с таким Host нет. Первая причина — домен записан неправильно: в поле Domains нужен полный URL со схемой, https://app.example.com, без слэша на конце и без пути. Вторая — DNS ещё не указывает на сервер: dig +short app.example.com должен вернуть его IP. Третья — два приложения заявили один домен, и второй роутер не создался; живые маршруты показывает дашборд Traefik (Server → Proxy), а динамическая конфигурация лежит в /data/coolify/proxy/dynamic/.

Рядом живут ошибки с гитом: git@github.com: Permission denied (publickey) означает, что deploy key не добавлен в репозиторий; а если пуш не запускает деплой — смотрите на GitHub Webhooks → Recent Deliveries, где 401 это несовпадение секрета.

Какой сервер под Coolify взять в MAATRIX

Считаем честно: половина разобранных ошибок — нехватка ресурсов, а не кривые руки. В простое coolify держит 400–500 МБ, coolify-db — 120–150 МБ, coolify-realtime — около 50 МБ, coolify-redis и coolify-proxy — по несколько десятков мегабайт. Итого 700–900 МБ съедено до первого приложения.

Минимум: 2 vCPU, 4 ГБ RAM, 80 ГБ NVMe. Официальные требования говорят про 2 ГБ — и это правда ровно для панели, которая ничего не собирает. Как только запускается npm run build, 2 ГБ превращаются в тот самый exit 137. Диск в 80 ГБ не блажь: на 30-гигабайтном вы упрётесь в no space left on device через пару недель.

Комфортно: 4 vCPU, 8 ГБ RAM, 160 ГБ NVMe. Панель, прокси, три-четыре приложения и база живут без ежедневного присмотра за диском, а сборка не выталкивает прод в swap. Раскладка по памяти — в материале сколько RAM нужно для Coolify.

Локация. По умолчанию берите UK (Лондон): сборка постоянно ходит в Docker Hub, GHCR, npm и кэш Nixpacks, а из Лондона эти реестры доступны без зеркал — именно на них спотыкается большинство деплоев с российских адресов. Плюс 8–15 мс до Амстердама и Франкфурта и рабочие 40–55 мс до Москвы. Франция — по тем же соображениям, если аудитория в континентальной Европе. Россия оправдана в одном случае: приложение обрабатывает персональные данные россиян по 152-ФЗ, и тогда зеркала реестров закладывайте сразу.

Заказ занимает несколько минут: выбираете локацию и конфигурацию, отмечаете приложение Coolify — сервер приедет с поднятым Docker и панелью. Ручная установка разобрана по шагам для Ubuntu 24.04, а выбор панели — в сравнении Coolify против Dokploy. Оплата — картами российских банков, по СБП, криптой или токеном MAAT; иностранная карта не нужна.

Развернуть за пару минут

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

Развернуть Coolify

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

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

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

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

Деплой висит в статусе Queued и не начинается — что делать?

Умер воркер очереди внутри панели. Проверьте docker exec -it coolify php artisan horizon:status и, если ответ Horizon is inactive., выполните docker restart coolify.

Сборка падает с exit code 137 — это баг Coolify?

Нет, это OOM-killer: 137 = 128 + 9, процесс убит по нехватке памяти. Лечится swap-файлом, переменной NODE_OPTIONS=--max-old-space-size=3072 с галкой Build Variable или сборкой образа в CI.

Можно ли перенести Coolify копированием /data/coolify?

Только целиком, вместе с файлом source/.env. Без старого APP_KEY панель откроется, а при обращении к приложениям выдаст The MAC is invalid. — расшифровать сохранённые секреты будет нечем.

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

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