За годы работы накопилась коллекция граблей, на которые наступал я и мои коллеги. Вот топ ошибок конфигурации, которые заставляли тратить часы на дебаг, хотя исправление занимало 30 секунд.
1. Кавычки в переменных окружения
Было:
# .env файл
DATABASE_URL="postgresql://user:pass@localhost/db"
API_KEY='super-secret-key'
Проблема:
Node.js приложение читает переменные вместе с кавычками. База не подключается, API возвращает 401.
Решение:
# .env файл - БЕЗ кавычек!
DATABASE_URL=postgresql://user:pass@localhost/db
API_KEY=super-secret-key
Урок:
В .env файлах кавычки НЕ нужны (если это не Docker Compose).
2. YAML: пробелы vs табы
Было:
services:
app:
image: myapp:latest
ports: # <-- ТУТ ТАБ!
- "3000:3000"
Проблема:
Error: yaml: line 4: found character that cannot start any token
Решение:
Настроить редактор показывать пробелы/табы. Использовать линтер.
Урок:
YAML не прощает табы. Только пробелы. Точка.
3. Nginx: точка с запятой
Было:
server {
listen 80;
server_name example.com
location / {
proxy_pass http://backend:3000;
}
}
Проблема:
nginx: [emerg] unexpected "location"
Решение:
server_name example.com; # <- точка с запятой!
Урок:
В Nginx КАЖДАЯ директива заканчивается точкой с запятой.
4. Docker: контекст сборки
Было:
COPY ../configs/app.conf /etc/app/
Проблема:
COPY failed: forbidden path outside the build context
Решение:
# Собирать из родительской директории
docker build -f docker/Dockerfile .
Урок:
Docker не может копировать файлы выше контекста сборки.
5. Kubernetes: неймспейсы
Было:
kubectl apply -f deployment.yaml
kubectl get pods
# No resources found in default namespace.
Проблема:
Деплой создался в другом namespace, а ищем в default.
Решение:
kubectl get pods -A # или --all-namespaces
# или
kubectl get pods -n production
Урок:
Всегда указывайте namespace явно или используйте -A для поиска.
6. Права доступа: 777 это не решение
Было:
chmod 777 /var/www/html -R # "чтобы заработало"
Проблема:
- Security alert от любого аудита
- Возможность изменить файлы кем угодно
- Потенциальная дыра в безопасности
Решение:
# Правильные права
chown -R www-data:www-data /var/www/html
chmod -R 755 /var/www/html
chmod -R 644 /var/www/html/*.php
Урок:
Разберитесь с правами. 777 - это костыль, не решение.
7. Git: case sensitivity
Было:
# На Mac (case-insensitive)
mv Component.js component.js
git add .
git commit -m "rename file"
git push
Проблема:
На Linux (case-sensitive) сборка падает - файл не найден.
Решение:
git mv Component.js component.js
Урок:
Используйте git mv
для переименования. Всегда.
8. SSL: забытый intermediate certificate
Было:
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
Проблема:
Браузеры показывают предупреждение о безопасности.
Решение:
# Объединить сертификат с intermediate
cat cert.pem intermediate.pem > fullchain.pem
ssl_certificate /etc/ssl/fullchain.pem;
Урок:
Всегда включайте intermediate certificates в цепочку.
9. Cron: окружение
Было:
0 2 * * * /home/user/backup.sh
backup.sh работает вручную, но не через cron.
Проблема:
У cron минимальное окружение. Нет PATH, нет переменных.
Решение:
PATH=/usr/local/bin:/usr/bin:/bin
0 2 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1
Урок:
В cron всегда указывайте полные пути и перенаправляйте вывод.
10. Redis: защита
Было:
# redis.conf
bind 0.0.0.0
protected-mode no
Проблема:
Redis доступен из интернета без пароля. Криптомайнеры говорят спасибо.
Решение:
bind 127.0.0.1 ::1
requirepass super-strong-password-here
Урок:
НИКОГДА не открывайте Redis/MongoDB/Elasticsearch в интернет без защиты.
Чек-лист против граблей
- Проверил синтаксис конфига (nginx -t, yaml lint)
- Проверил права доступа (не 777)
- Проверил, что сервисы не торчат наружу
- Добавил логирование для отладки
- Проверил на другой ОС (если важно)
- Прочитал сообщение об ошибке полностью
- Погуглил точный текст ошибки
Бонус: универсальный дебаг
Когда ничего не помогает:
# 1. Проверить, что сервис слушает
ss -tlnp | grep :80
# 2. Проверить, что трафик доходит
tcpdump -i any port 80
# 3. Проверить DNS
dig example.com
nslookup example.com
# 4. Проверить сертификаты
openssl s_client -connect example.com:443
# 5. strace в крайнем случае
strace -f -e network nginx
Помните: большинство проблем - это опечатки или неправильные права. Начинайте с простого!