Coolify не выдаёт SSL-сертификат: причины и решение
Домен привязан, приложение задеплоено, а браузер показывает NET::ERR_CERT_AUTHORITY_INVALID и сертификат с именем TRAEFIK DEFAULT CERT. Это значит одно из двух: Coolify либо вообще не попросил сертификат у Let's Encrypt, либо попросил и получил отказ. Поломки разные — ниже как за пять минут понять, какая у вас.
Содержание
- Быстрая диагностика: три команды, которые называют причину
- Причина №1: домен без схемы https:// — Coolify даже не пробовал
- DNS: AAAA-ловушка, CAA и оранжевое облако Cloudflare
- Порт 80 занят или закрыт снаружи
- Ошибки внутри Traefik: acme.json, права и staging
- Лимиты Let's Encrypt, wildcard и свой сертификат
- Какой сервер нужен под Coolify, чтобы SSL выдавался сразу
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Быстрая диагностика: три команды, которые называют причину
Начните с того, что реально отдаёт сервер:
openssl s_client -connect app.example.com:443 -servername app.example.com </dev/null 2>/dev/null \
| openssl x509 -noout -issuer -subject -dates
Сертификат не выпущен — увидите заглушку issuer=CN = TRAEFIK DEFAULT CERT и такой же subject. Рабочий вариант: issuer=C = US, O = Let's Encrypt, CN = R11 и ровно 90 дней в notAfter.
Дальше журнал прокси — весь ACME-обмен идёт через Traefik, и он пишет причину отказа открытым текстом. И хранилище: Coolify держит его в /data/coolify/proxy/acme.json, резолвер — letsencrypt.
docker logs coolify-proxy --since 30m 2>&1 | grep -iE 'acme|certificate|unable' | tail -20
jq -r '.letsencrypt.Certificates[].domain.main' /data/coolify/proxy/acme.json
Пустой вывод jq — сертификата нет. Сверьтесь с таблицей:
| Что видно в логах | Причина |
|---|---|
Ни строки acme про ваш домен | нет TLS-роутера — секция 2 |
Invalid response ... : 404 | запрос идёт не на ваш сервер — секция 3 |
Timeout during connect (likely firewall problem) | 80-й порт закрыт — секция 4 |
permissions 644 for /traefik/acme.json are too open | права на хранилище — секция 5 |
urn:ietf:params:acme:error:rateLimited | лимит Let's Encrypt — секция 6 |
Причина №1: домен без схемы https:// — Coolify даже не пробовал
Самый частый случай, когда Coolify SSL не работает, вообще не связан с Let's Encrypt. Coolify собирает метки Traefik из поля Domains и решает по схеме URL. Если там app.example.com или http://app.example.com, создаётся только HTTP-роутер: метки tls и certresolver не появляются, запрос в удостоверяющий центр не уходит никогда, а в логах прокси идеальная тишина.
Проверяется одной командой по контейнеру приложения:
docker inspect <имя_контейнера> \
--format '{{range $k,$v := .Config.Labels}}{{$k}}={{$v}}{{"\n"}}{{end}}' \
| grep -i traefik | sort
Рабочий набор обязан содержать строки такого вида:
traefik.enable=true
traefik.http.routers.https-0-r8ck0cs.entrypoints=https
traefik.http.routers.https-0-r8ck0cs.rule=Host(`app.example.com`) && PathPrefix(`/`)
traefik.http.routers.https-0-r8ck0cs.tls.certresolver=letsencrypt
Только роутеры http-0- и ни одного https-0- — дело в схеме. Впишите домен как https://app.example.com и сделайте Redeploy, а не Restart: метки вшиваются в контейнер при создании.
То же для домена панели — Settings → Instance Domain тоже начинается с https://. Сохранили туда домен до того, как разошёлся DNS, и потеряли доступ — верните APP_URL=http://<ваш-ip>:8000 в /data/coolify/source/.env и поднимите контейнер заново через docker compose up -d --force-recreate coolify.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть CoolifyDNS: AAAA-ловушка, CAA и оранжевое облако Cloudflare
Let's Encrypt проверяет владение доменом по HTTP — домен обязан вести именно на ваш сервер. Смотрим три записи:
dig +short A app.example.com @1.1.1.1
dig +short AAAA app.example.com @1.1.1.1
dig +short CAA example.com @1.1.1.1
curl -s https://api.ipify.org
A-запись должна совпасть с выводом последней команды. Частая история: домен переехал, но у регистратора остались две A-записи. Валидация тогда попадает на старый хост через раз, и в логах мигают 404.
AAAA — главная ловушка. Let's Encrypt предпочитает IPv6, и если AAAA есть, а IPv6 на сервере не работает или Docker не публикует на нём порты, в логе будет:
acme: error: 400 :: urn:ietf:params:acme:error:connection :: Fetching http://app.example.com/
.well-known/acme-challenge/mQ8f...: Timeout during connect (likely firewall problem)
Проще всего удалить AAAA до выпуска сертификата. Нужен IPv6 — включайте честно: "ip6tables": true в /etc/docker/daemon.json и рабочий адрес на интерфейсе.
CAA задаёт, каким центрам разрешено выпускать сертификаты для домена. Вернулось 0 issue "digicert.com" — Let's Encrypt откажет с urn:ietf:params:acme:error:caa. Добавьте 0 issue "letsencrypt.org" либо уберите CAA целиком.
Cloudflare с оранжевым облаком даёт самую запутанную картину: браузер видит валидный сертификат Cloudflare, но на origin сертификата нет, и в режиме Full (strict) сайт отдаёт 526 Invalid SSL certificate. Быстрый путь: переключите запись в DNS only, дождитесь появления домена в acme.json, потом верните проксирование.
Примета 2026 года: с 2025-го Let's Encrypt проверяет домен из нескольких географических точек сразу. Есть в ошибке During secondary validation: — сервер доступен не отовсюду, типичная картина для IP из фильтруемых диапазонов. Лечится не настройками, а адресом.
Порт 80 занят или закрыт снаружи
Coolify использует HTTP-01: Let's Encrypt стучится на http://ваш-домен/.well-known/acme-challenge/<токен> по 80-му порту. Без него сертификата не будет, даже если сайт работает по 443-му. Здоровый вывод — оба порта за docker-proxy:
ss -tlnp | grep -E ':(80|443) '
LISTEN 0 4096 0.0.0.0:80 0.0.0.0:* users:(("docker-proxy",pid=1442,fd=7))
LISTEN 0 4096 0.0.0.0:443 0.0.0.0:* users:(("docker-proxy",pid=1461,fd=7))
Видите там nginx или apache2 — прокси Coolify не поднялся, и в docker logs coolify-proxy будет Bind for 0.0.0.0:80 failed: port is already allocated. Освободите порт (systemctl disable --now nginx) и нажмите Servers → сервер → Proxy → Restart.
Проверьте доступность снаружи, с телефона по мобильному интернету:
curl -sS -m 10 -o /dev/null -w '%{http_code} %{remote_ip}\n' \
http://app.example.com/.well-known/acme-challenge/probe
Ожидаемый ответ — 404 203.0.113.10. Именно 404: его отдаёт Traefik, то есть запрос дошёл. Пустой вывод или таймаут — трафик режется по дороге.
Честная оговорка: Docker публикует порты своими цепочками iptables и обходит ufw, так что ufw allow 80/tcp тут ничего не решает — снаружи режет фаервол провайдера или security group.
Ошибки внутри Traefik: acme.json, права и staging
Даже при исправных DNS и портах Traefik может молча отказаться от хранилища:
level=error msg="The ACME resolver \"letsencrypt\" is skipped from the resolvers list because:
unable to get ACME account: permissions 644 for /traefik/acme.json are too open, please use 600"
Права слетают после rsync без -p, после scp или распаковки архива без --same-permissions. Чинится строкой chmod 600 /data/coolify/proxy/acme.json && docker restart coolify-proxy.
Второй вариант — файл побился: Unable to read ACME storage: unexpected end of JSON input. Третий — застрявшая запись: сертификат есть, но битый или достался от прошлого сервера. Вырежьте один домен вместо сброса всего файла, чтобы не потратить недельный лимит на остальные:
docker stop coolify-proxy
cp /data/coolify/proxy/acme.json /root/acme.json.bak
jq '.letsencrypt.Certificates |= map(select(.domain.main != "app.example.com"))' \
/root/acme.json.bak > /data/coolify/proxy/acme.json
chmod 600 /data/coolify/proxy/acme.json && docker start coolify-proxy
Файл нечитаем целиком — echo '{}' > /data/coolify/proxy/acme.json и те же права, но все сертификаты пойдут на перевыпуск.
Четвёртый вариант — остался тестовый удостоверяющий центр. Признак: ошибка доверия, а эмитент выглядит как CN = (STAGING) Pretend Pear X1. Уберите строку caserver из /data/coolify/proxy/docker-compose.yml, сделайте docker compose up -d --force-recreate и очистите хранилище: staging-аккаунт лежит в том же acme.json.
И проверьте свои файлы в /data/coolify/proxy/dynamic/: одна ошибка отступа — и Traefik игнорирует всю динамическую конфигурацию с yaml: line 7: mapping values are not allowed in this context.
Лимиты Let's Encrypt, wildcard и свой сертификат
Если вы полдня передеплоиваете приложение, вы почти наверняка упёрлись в лимиты: 50 новых сертификатов на зарегистрированный домен в неделю, 5 повторных выпусков на один и тот же набор имён за 168 часов, 5 неудачных валидаций на связку аккаунт+домен в час. Текст отказа однозначный:
urn:ietf:params:acme:error:rateLimited :: too many certificates (5) already issued for this
exact set of identifiers in the last 168h0m0s
Сколько выпущено, видно в логе прозрачности — https://crt.sh/?q=example.com. Обойти лимит нельзя, окно придётся переждать. Отлаживать домен правильнее на тестовом acme-staging-v02.api.letsencrypt.org, где лимиты в разы выше, а потом убрать флаг и очистить acme.json.
Wildcard через HTTP-01 не выпускается в принципе: *.example.com требует DNS-01. Из интерфейса это не настраивается — надо править /data/coolify/proxy/docker-compose.yml: токен провайдера в environment плюс флаг --certificatesresolvers.letsencrypt.acme.dnschallenge.provider=cloudflare. Минус честно: Coolify считает файл своим и может перезаписать его при перезапуске прокси из UI.
Свой сертификат — купленный или корпоративный — подключается отдельным файлом динамической конфигурации. Каталог /data/coolify/proxy смонтирован в контейнер как /traefik, поэтому файлы кладут в /data/coolify/proxy/certs/:
# /data/coolify/proxy/dynamic/custom-ssl.yaml
tls:
certificates:
- certFile: /traefik/certs/example.com.crt
keyFile: /traefik/certs/example.com.key
Про продление: Traefik обновляет сертификат за 30 дней до конца срока сам, без cron. Но Let's Encrypt с середины 2025 года не рассылает письма об истечении — заведите свою проверку openssl x509 -noout -enddate в cron. Появившиеся тогда же шестидневные сертификаты Coolify по умолчанию не использует, и для боевого сайта это к лучшему: шесть дней не прощают ошибок в автопродлении.
Какой сервер нужен под Coolify, чтобы SSL выдавался сразу
Половина историй «Coolify не выдаёт сертификат» — это не Coolify, а сервер: закрытый 80-й порт, серый IP, забитый диск.
Минимум — 2 vCPU, 4 ГБ RAM, 60 ГБ NVMe. Формально Coolify стартует и на 2 ГБ, но стек самой панели (приложение, PostgreSQL, Redis, сервис реального времени и прокси) в покое занимает около 1 ГБ — на сборках памяти не остаётся. Деплой падает с коротким Killed, а правду видно в журнале ядра:
dmesg -T | grep -i 'out of memory'
[Fri Aug 28 12:41:07 2026] Out of memory: Killed process 2261 (node) total-vm:3184920kB
Упираетесь только на сборках — своп дешевле апгрейда: fallocate -l 4G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile.
Комфортный вариант — 4 vCPU, 8 ГБ RAM, 160 ГБ NVMe. Панель, десяток приложений, база рядом и параллельные сборки без OOM. Диск связан с темой статьи напрямую: образы и кэш растут быстро, а когда раздел заполняется, Traefik не может записать хранилище — unable to save ACME account: write /traefik/acme.json: no space left on device, и продление тихо перестаёт работать. Следите за docker system df. Расклад по памяти — в материале про требования Coolify к серверу.
Обязательные условия для SSL: белый статический IPv4, открытые входящие 80 и 443, чистая репутация адреса. На этом спотыкаются домашние серверы за NAT и дешёвые VPS с адресами из «грязных» подсетей.
Локация. Для европейской и мировой аудитории берите UK, Лондон: RTT до Франкфурта 10–15 мс, до Амстердама 8–12 мс, IP не попадает в региональные фильтры, плюс GDPR-соседство. Российская аудитория и 152-ФЗ — RU, но заранее проверьте, что входящий 80-й порт не фильтруется. Приложения ходят в OpenAI или Anthropic — US с чистым адресом.
В MAATRIX сервер под Coolify поднимается за несколько минут — белый статический IP, открытые 80/443, локации UK, US, FR и RU, выбрать конфигурацию можно сразу под задачу. Оплата картой российского банка, по СБП, криптой или токеном MAAT: иностранная карта не нужна даже для Лондона. Если Coolify ещё не стоит — начните с установки и настройки, остальные грабли собраны в разборе частых ошибок Coolify.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть CoolifyОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Сайт открывается по HTTPS, но браузер ругается на сертификат.
Проверьте эмитента через openssl x509 -noout -issuer. TRAEFIK DEFAULT CERT означает, что сертификат так и не выпущен, а (STAGING) Pretend Pear X1 — что в конфиге прокси остался тестовый CA.
Поменял домен, а сертификат не появился.
Метки Traefik пишутся в контейнер при создании, поэтому нужен Redeploy, а не Restart. И домен должен быть указан со схемой https:// — иначе TLS-роутер не создаётся вовсе.
Можно ли обойти лимит, если упёрся в 429?
Нет, окно в 168 часов придётся переждать. Пока ждёте, отлаживайте домен на staging-сервере ACME или подключите свой сертификат через /data/coolify/proxy/dynamic/custom-ssl.yaml.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.