<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Unix‑шпаргалка для веб‑разработчика: команды для кибербезопасности и поддержки сайтов]]></title><description><![CDATA[<p dir="auto">Материал ориентирован на разработчиков и тех, кто <strong>не живёт в терминале 24/7</strong>, но хочет уверенно чувствовать себя на сервере.</p>
<hr />
<h3>1. Навигация и файловая структура</h3>
<p dir="auto"><strong>Где я и что вокруг</strong></p>
<pre><code class="language-bash">pwd          # показать текущую директорию
ls           # список файлов
ls -la       # список с правами/владельцами/скрытыми файлами
cd /path     # перейти в директорию
cd ..        # на уровень выше
cd -         # переключиться в предыдущую директорию
</code></pre>
<p dir="auto"><strong>Для чего:</strong></p>
<ul>
<li>Проверка, куда деплоится сайт, где лежат логи и конфиги.</li>
<li>Контроль, нет ли «левых» директорий рядом с проектом.</li>
</ul>
<hr />
<h3>2. Просмотр и поиск по файлам (логи, конфиги, шеллы)</h3>
<p dir="auto"><strong>Быстрый просмотр файлов</strong></p>
<pre><code class="language-bash">cat file.log                  # вывести весь файл
less file.log                 # пролистывать вверх/вниз, поиск по /строка
head -n 50 file.log           # первые 50 строк
tail -n 50 file.log           # последние 50 строк
tail -f file.log              # «онлайн» просмотр лога
</code></pre>
<p dir="auto"><strong>Поиск по тексту (ошибки, IP, подозрительные строки)</strong></p>
<pre><code class="language-bash">grep "ERROR" file.log                 # найти строки с ERROR
grep -i "warning" file.log            # регистронезависимый поиск
grep -R "eval(base64_decode" .       # рекурсивный поиск по проекту
grep -R "site.ru" /var/log           # где в логах фигурирует ваш домен
</code></pre>
<p dir="auto">Комбо для live‑мониторинга ошибок:</p>
<pre><code class="language-bash">tail -f /var/log/nginx/error.log | grep --line-buffered "site.ru"
</code></pre>
<hr />
<h3>3. Права, владельцы, подозрительные файлы</h3>
<p dir="auto"><strong>Права и владельцы</strong></p>
<pre><code class="language-bash">ls -la                      # посмотреть права и владельца
chown user:group file       # сменить владельца
chmod 644 file              # стандартные права для файлов
chmod 755 dir               # стандартные права для директорий
</code></pre>
<p dir="auto">Типичные значения для PHP-проектов (без shared‑hosting‑извращений):</p>
<ul>
<li>директории: <code>755</code></li>
<li>файлы: <code>644</code></li>
<li>никакого <code>777</code> в проде, если не хотите неожиданных «сюрпризов».</li>
</ul>
<p dir="auto"><strong>Поиск подозрительных файлов</strong></p>
<pre><code class="language-bash">find . -name "*.php" -mtime -1             # новые/изменённые за сутки
find . -name "*.php" -size +1M             # слишком «толстые» php-файлы
find . -perm -o+w -type f                  # файлы, доступные на запись всем
find . -name ".*" -type f                  # скрытые файлы (в т.ч. пассажи типа .something.php)
</code></pre>
<hr />
<h3>4. Сеть: кто подключён, какие порты, что слушает</h3>
<p dir="auto"><strong>Открытые порты и процессы</strong></p>
<pre><code class="language-bash">ss -tulpen         # список слушающих портов и процессов
ss -tnp            # активные TCP‑подключения
</code></pre>
<p dir="auto"><strong>Кто подключён по SSH</strong></p>
<pre><code class="language-bash">who                # кто в системе
w                  # кто, откуда и что запускает
last -n 20         # последние 20 входов в систему
</code></pre>
<p dir="auto"><strong>Запросы к сайту в реальном времени (Nginx)</strong></p>
<pre><code class="language-bash">tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/access.log | grep "POST"
tail -f /var/log/nginx/access.log | grep "wp-login"    # поиск брут‑запросов к WP, как пример
</code></pre>
<hr />
<h3>5. Процессы, память, нагрузка</h3>
<p dir="auto"><strong>Общая картина</strong></p>
<pre><code class="language-bash">top              # живой монитор ресурсов
htop             # более удобная версия (если установлена)
uptime           # load average и время работы сервера
free -h          # память
df -h            # диски и свободное место
du -sh *         # размер директорий в текущем каталоге
</code></pre>
<p dir="auto"><strong>Кто ест CPU / RAM</strong></p>
<pre><code class="language-bash">ps aux --sort=-%cpu | head      # топ по CPU
ps aux --sort=-%mem | head      # топ по памяти
</code></pre>
<p dir="auto"><strong>Убить зависший процесс</strong></p>
<pre><code class="language-bash">ps aux | grep php-fpm           # найти PID
kill 12345                      # мягко завершить
kill -9 12345                   # жёстко (в крайнем случае)
</code></pre>
<hr />
<h3>6. Работа с архивами и бэкапами</h3>
<p dir="auto"><strong>Создать архив проекта</strong></p>
<pre><code class="language-bash">tar czf backup-`date +%F`.tar.gz /var/www/site
</code></pre>
<p dir="auto"><strong>Распаковать архив</strong></p>
<pre><code class="language-bash">tar xzf backup-2025-12-08.tar.gz -C /var/www/site
</code></pre>
<p dir="auto">Полезно для:</p>
<ul>
<li>быстрых ручных бэкапов перед обновлениями;</li>
<li>переносов проекта между серверами.</li>
</ul>
<hr />
<h3>7. SSH и ключи: безопасность доступа к серверу</h3>
<p dir="auto"><strong>Создать SSH‑ключ</strong></p>
<pre><code class="language-bash">ssh-keygen -t ed25519 -C "your_email@example.com"
</code></pre>
<p dir="auto"><strong>Скопировать ключ на сервер</strong></p>
<pre><code class="language-bash">ssh-copy-id user@server
</code></pre>
<p dir="auto"><strong>Подключиться с ключом</strong></p>
<pre><code class="language-bash">ssh user@server
</code></pre>
<p dir="auto">Базовые практики:</p>
<ul>
<li>выключить парольный вход в <code>sshd_config</code> (<code>PasswordAuthentication no</code>);</li>
<li>использовать нестандартный порт, если это допустимо инфраструктурно;</li>
<li>ограничивать вход по IP, если есть возможность.</li>
</ul>
<hr />
<h3>8. Мониторинг и анализ логов (Nginx, Apache, SSH)</h3>
<p dir="auto"><strong>Типичные места логов</strong></p>
<pre><code class="language-bash">/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/apache2/access.log
/var/log/apache2/error.log
/var/log/auth.log        # попытки входа в систему (SSH и не только)
</code></pre>
<p dir="auto"><strong>Примеры команд</strong></p>
<pre><code class="language-bash"># 20 последних ошибок Nginx
tail -n 20 /var/log/nginx/error.log

# Подозрительные многократные попытки логина по SSH
grep "Failed password" /var/log/auth.log | tail

# Часто встречающиеся IP (грубый подсчёт)
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
</code></pre>
<hr />
<h3>9. Базовое взаимодействие с Git (деплой, код, аудит изменений)</h3>
<p dir="auto">Git напрямую про безопасность не отвечает, но помогает контролировать изменения в коде и ловить «левых редакторов».</p>
<pre><code class="language-bash">git status                     # что изменилось
git diff                       # посмотреть реальные изменения
git log --oneline --decorate   # история коммитов
git blame file.php             # кто и когда менял строки в файле
</code></pre>
<p dir="auto">Подозрительные изменения можно быстрой командой просканировать и найти:</p>
<pre><code class="language-bash">grep -R "base64_decode" .git
grep -R "system(" .
</code></pre>
<hr />
<h3>10. Быстрые однострочники для безопасника и админа</h3>
<p dir="auto">Несколько «готовых» рецептов, которые можно брать и вставлять.</p>
<p dir="auto">Показать топ‑10 IP по числу запросов к сайту:</p>
<pre><code class="language-bash">awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
</code></pre>
<p dir="auto">Поиск всех PHP‑файлов, изменённых за последние 2 часа:</p>
<pre><code class="language-bash">find /var/www/site -name "*.php" -mmin -120 -print
</code></pre>
<p dir="auto">Поиск сигнатур типичных веб-шеллов:</p>
<pre><code class="language-bash">grep -R "eval(base64_decode" /var/www/site
grep -R "passthru(" /var/www/site
grep -R "shell_exec(" /var/www/site
</code></pre>
<hr />
<h3>11. Минимальный набор для «я не админ, но надо срочно глянуть»</h3>
<p dir="auto">Если совсем нет времени, а доступ к SSH есть, то хотя бы эти команды стоит держать под рукой:</p>
<pre><code class="language-bash"># 1. Диски, память, нагрузка
df -h
free -h
uptime

# 2. Логи сайта
tail -n 50 /var/log/nginx/error.log
tail -n 50 /var/log/nginx/access.log

# 3. Кто подключён по SSH
w
last -n 10

# 4. Изменённые PHP-файлы за сутки в проекте
cd /var/www/site
find . -name "*.php" -mtime -1 -print
</code></pre>
<p dir="auto">Эта шпаргалка не претендует на роль полноценного курса по администрированию, но закрывает <strong>рабочий минимум</strong> для:</p>
<ul>
<li>веб‑разработчика, которого внезапно сделали «ответственным за сервер»;</li>
<li>кибербезопасности на уровне проверки логов, прав и подозрительных файлов;</li>
<li>быстрой диагностики типичных проблем с сайтом.</li>
</ul>
]]></description><link>https://forum.exlends.ru/topic/328/unix-shpargalka-dlya-veb-razrabotchika-komandy-dlya-kiberbezopasnosti-i-podderzhki-sajtov</link><generator>RSS for Node</generator><lastBuildDate>Wed, 20 May 2026 07:27:14 GMT</lastBuildDate><atom:link href="https://forum.exlends.ru/topic/328.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 08 Dec 2025 12:43:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Unix‑шпаргалка для веб‑разработчика: команды для кибербезопасности и поддержки сайтов on Tue, 09 Dec 2025 18:52:40 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/arteml" aria-label="Profile: ArtemL">@<bdi>ArtemL</bdi></a> хм, наверное стоит написать про деплой Некста - займусь на выходных</p>
]]></description><link>https://forum.exlends.ru/post/1055</link><guid isPermaLink="true">https://forum.exlends.ru/post/1055</guid><dc:creator><![CDATA[kirilljsx]]></dc:creator><pubDate>Tue, 09 Dec 2025 18:52:40 GMT</pubDate></item><item><title><![CDATA[Reply to Unix‑шпаргалка для веб‑разработчика: команды для кибербезопасности и поддержки сайтов on Tue, 09 Dec 2025 07:12:28 GMT]]></title><description><![CDATA[<p dir="auto">Вопрос,сборку проекта лучше делать где? И как получить  node_modules на проде?</p>
]]></description><link>https://forum.exlends.ru/post/1040</link><guid isPermaLink="true">https://forum.exlends.ru/post/1040</guid><dc:creator><![CDATA[ArtemL]]></dc:creator><pubDate>Tue, 09 Dec 2025 07:12:28 GMT</pubDate></item><item><title><![CDATA[Reply to Unix‑шпаргалка для веб‑разработчика: команды для кибербезопасности и поддержки сайтов on Mon, 08 Dec 2025 13:04:37 GMT]]></title><description><![CDATA[<p dir="auto">А как же самая главная команда?!</p>
<pre><code>rm -rf
</code></pre>
]]></description><link>https://forum.exlends.ru/post/1036</link><guid isPermaLink="true">https://forum.exlends.ru/post/1036</guid><dc:creator><![CDATA[hannadev]]></dc:creator><pubDate>Mon, 08 Dec 2025 13:04:37 GMT</pubDate></item><item><title><![CDATA[Reply to Unix‑шпаргалка для веб‑разработчика: команды для кибербезопасности и поддержки сайтов on Mon, 08 Dec 2025 12:53:02 GMT]]></title><description><![CDATA[<p dir="auto">Дополнение к предыдущей Unix‑шпаргалке, но <strong>специально для Node.js‑приложений</strong>. Здесь конкретные команды, примеры конфигов и típичные проблемы, которые встречаются при запуске и поддержке Node на боевом сервере.</p>
<hr />
<h3>1. Управление процессами Node.js</h3>
<p dir="auto"><strong>Базовый запуск (для разработки)</strong></p>
<pre><code class="language-bash">node app.js                    # простой запуск
node --inspect app.js          # с дебагером (слушает на 9229)
</code></pre>
<p dir="auto"><strong>Продакшн: процесс‑менеджер PM2</strong></p>
<p dir="auto">PM2 — это <strong>фактический стандарт</strong> для Node.js на Linux. Он обеспечивает автозапуск, рестарты и логирование.</p>
<p dir="auto">Установка:</p>
<pre><code class="language-bash">npm install -g pm2
</code></pre>
<p dir="auto">Запуск приложения через PM2:</p>
<pre><code class="language-bash">pm2 start app.js --name "myapp"
pm2 start app.js --name "myapp" --instances max    # кластер на все ядра
pm2 start app.js --name "myapp" --watch             # перезапуск при изменении файлов (для dev)
</code></pre>
<p dir="auto">Управление:</p>
<pre><code class="language-bash">pm2 list                       # список всех приложений
pm2 status                     # статус (живо/мёртво)
pm2 logs myapp                 # логи приложения в реальном времени
pm2 logs myapp --err           # только ошибки
pm2 logs --lines 100           # последние 100 строк всех логов
pm2 monit                      # живой мониторинг CPU/RAM по процессам
pm2 stop myapp                 # остановить
pm2 restart myapp              # перезапустить
pm2 delete myapp               # удалить из управления
pm2 kill                       # остановить PM2 и все процессы
</code></pre>
<p dir="auto"><strong>Автозапуск при перезагрузке сервера</strong></p>
<pre><code class="language-bash">pm2 startup                    # сгенерирует команду для systemd/init.d
pm2 save                       # сохранить текущий список процессов
</code></pre>
<p dir="auto">После этого PM2 автоматически запустит приложение при перезагрузке.</p>
<hr />
<h3>2. Конфиг PM2 (ecosystem.config.js)</h3>
<p dir="auto">Вместо множества флагов лучше использовать файл конфигурации. Создаёте <code>ecosystem.config.js</code> в корне проекта:</p>
<pre><code class="language-javascript">module.exports = {
  apps: [
    {
      name: "api-server",
      script: "./dist/main.js",      // или src/main.js, если используете ts-node
      instances: "max",               // число рабочих процессов
      exec_mode: "cluster",           // кластерный режим
      env: {
        NODE_ENV: "production",
        PORT: 3000,
      },
      env_development: {
        NODE_ENV: "development",
        PORT: 3000,
      },
      // Перезапуск, если использование памяти &gt; 500MB
      max_memory_restart: "500M",
      // Максимальное число перезапусков за час
      max_restarts: 10,
      min_uptime: "10s",
      // Логи
      error_file: "./logs/error.log",
      out_file: "./logs/out.log",
      log_date_format: "YYYY-MM-DD HH:mm:ss Z",
    },
  ],
};
</code></pre>
<p dir="auto">Запуск с этим конфигом:</p>
<pre><code class="language-bash">pm2 start ecosystem.config.js
pm2 start ecosystem.config.js --env development
</code></pre>
<hr />
<h3>3. Логирование приложения</h3>
<p dir="auto"><strong>Куда смотреть</strong></p>
<p dir="auto">PM2 пишет логи сюда:</p>
<pre><code class="language-bash">~/.pm2/logs/           # основные логи приложений
</code></pre>
<p dir="auto">Если вы указали свои пути в конфиге (см. выше):</p>
<pre><code class="language-bash">tail -f ./logs/error.log
tail -f ./logs/out.log
tail -f ./logs/error.log | grep "ERR"
</code></pre>
<p dir="auto"><strong>Правильное логирование в коде</strong></p>
<p dir="auto">Не просто <code>console.log()</code>, а структурированные логи. Популярные либы: <code>winston</code>, <code>pino</code>, <code>bunyan</code>.</p>
<p dir="auto">Пример с <strong>pino</strong> (просто и быстро):</p>
<pre><code class="language-javascript">import pino from "pino";

const logger = pino({
  level: process.env.LOG_LEVEL || "info",
  transport: {
    target: "pino-pretty",
  },
});

logger.info({ userId: 123 }, "User logged in");
logger.error({ err: err }, "Something broke");
</code></pre>
<p dir="auto">В продакшене без <code>pino-pretty</code> (для JSON-логов):</p>
<pre><code class="language-javascript">const logger = pino({
  level: "info",
  // transport убрать для чистого JSON в файл
});
</code></pre>
<p dir="auto"><strong>Мониторинг в реальном времени</strong></p>
<pre><code class="language-bash">pm2 logs                       # все логи
pm2 logs myapp                 # только приложения myapp
pm2 logs myapp --err           # только ошибки
pm2 logs myapp --lines 50      # последние 50 строк
tail -f ~/.pm2/logs/myapp-error.log | grep "500"   # ошибки сервера
</code></pre>
<hr />
<h3>4. Базовая безопасность Node.js‑приложения</h3>
<p dir="auto"><strong>Переменные окружения (<code>.env</code>)</strong></p>
<p dir="auto">Никогда не коммитьте API‑ключи, пароли БД и токены в код.</p>
<p dir="auto">Используйте <code>.env</code> файл:</p>
<pre><code class="language-bash"># .env
DATABASE_URL=postgresql://user:pass@localhost/dbname
API_SECRET=your_secret_key_here
NODE_ENV=production
</code></pre>
<p dir="auto">И в коде:</p>
<pre><code class="language-javascript">import dotenv from "dotenv";
dotenv.config();

const dbUrl = process.env.DATABASE_URL;
</code></pre>
<p dir="auto"><strong>Проверка: нет ли в репо секретов</strong></p>
<pre><code class="language-bash">grep -R "password" .                 # поиск по слову password
grep -R "secret" .                   # по слову secret
grep -R "sk_" .                      # типичные Stripe ключи
find . -name ".env*" -type f         # .env файлы (не должны коммититься)
</code></pre>
<p dir="auto"><strong>Защита папки <code>node_modules</code></strong></p>
<pre><code class="language-bash"># По умолчанию может быть доступна через веб, что плохо
# В Nginx блокируйте:

location /node_modules/ {
    deny all;
}
</code></pre>
<p dir="auto"><strong>Обновление зависимостей (уязвимости)</strong></p>
<pre><code class="language-bash">npm audit                      # показать известные уязвимости
npm audit fix                  # попытаться автоматически исправить
npm outdated                   # показать устаревшие пакеты
npm update                     # обновить в рамках семантики версий
</code></pre>
<hr />
<h3>5. Порты и сетевая безопасность</h3>
<p dir="auto"><strong>На каких портах слушит ваше приложение</strong></p>
<pre><code class="language-bash">ss -tulpen | grep node         # процессы node и их порты
lsof -i -P | grep node         # альтернативный способ
</code></pre>
<p dir="auto"><strong>Хороший паттерн для продакшена</strong></p>
<pre><code>Node.js слушает на localhost:3000
Nginx сверху (порт 80/443) → проксирует на Node на localhost:3000
</code></pre>
<p dir="auto">Конфиг Nginx для проксирования:</p>
<pre><code class="language-nginx">upstream nodejs {
    server 127.0.0.1:3000;
}

server {
    listen 80;
    server_name your-site.ru;

    location / {
        proxy_pass http://nodejs;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
</code></pre>
<p dir="auto"><strong>Проверка прав на порты</strong></p>
<pre><code class="language-bash"># Node.js не должен запускаться от root (для портов &lt; 1024 нужна привилегия)
# Правильно: Node на 3000, Nginx как обратный прокси на 80

ps aux | grep node             # под каким юзером запущен node
</code></pre>
<hr />
<h3>6. Работа с базами данных (Node.js + PostgreSQL/MySQL)</h3>
<p dir="auto">Типичные проблемы: вход на БД не установлен, утечка данных в логи, медленные квери.</p>
<p dir="auto"><strong>Проверка подключения</strong></p>
<pre><code class="language-bash"># На сервере, если БД локальная
psql -U postgres -d your_db    # PostgreSQL
mysql -u root -p your_db       # MySQL
</code></pre>
<p dir="auto"><strong>Утечки в логи (секреты не должны попадать)</strong></p>
<pre><code class="language-bash">grep -R "password" ~/.pm2/logs/
grep -R "DATABASE_URL" ~/.pm2/logs/
</code></pre>
<p dir="auto">Убедитесь, что в логах не выводится полная строка подключения.</p>
<p dir="auto"><strong>ORM и драйверы (NestJS примеры)</strong></p>
<p dir="auto">Если используется TypeORM:</p>
<pre><code class="language-typescript">import { DataSource } from 'typeorm';

export const AppDataSource = new DataSource({
  type: 'postgres',
  host: process.env.DB_HOST,
  port: parseInt(process.env.DB_PORT || '5432'),
  username: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  entities: ['src/**/*.entity.ts'],
  migrations: ['src/migrations/**/*.ts'],
});
</code></pre>
<p dir="auto"><strong>Проверка количества активных подключений к БД</strong></p>
<pre><code class="language-bash"># PostgreSQL (на самой БД)
psql -U postgres -d your_db -c "SELECT count(*) FROM pg_stat_activity;"
</code></pre>
<hr />
<h3>7. Логирование запросов (HTTP логи приложения)</h3>
<p dir="auto">В Express / Fastify / NestJS используйте middleware для логирования:</p>
<p dir="auto"><strong>Express пример с morgan</strong></p>
<pre><code class="language-javascript">import morgan from 'morgan';
import fs from 'fs';

// Логирование в файл
const accessLogStream = fs.createWriteStream('./logs/access.log', { flags: 'a' });
app.use(morgan('combined', { stream: accessLogStream }));

// В консоль (development)
app.use(morgan('dev'));
</code></pre>
<p dir="auto"><strong>NestJS пример</strong></p>
<pre><code class="language-typescript">import { Logger, Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  private logger = new Logger('HTTP');

  use(req: Request, res: Response, next: NextFunction) {
    const { method, originalUrl, ip } = req;
    const start = Date.now();

    res.on('finish', () =&gt; {
      const duration = Date.now() - start;
      this.logger.log(
        `${method} ${originalUrl} ${res.statusCode} ${duration}ms from ${ip}`,
      );
    });

    next();
  }
}
</code></pre>
<p dir="auto"><strong>Поиск проблемных запросов</strong></p>
<pre><code class="language-bash"># Медленные запросы (&gt;5 секунд)
awk '$NF &gt; 5 {print}' /var/log/nginx/access.log

# POST запросы (обычно подозрительнее)
tail -f /var/log/nginx/access.log | grep "POST"

# 500 ошибки
tail -f ~/.pm2/logs/myapp-error.log | grep "500"
</code></pre>
<hr />
<h3>8. Мониторинг производительности (CPU, память, утечки)</h3>
<p dir="auto"><strong>Live мониторинг PM2</strong></p>
<pre><code class="language-bash">pm2 monit                      # встроенный монитор
</code></pre>
<p dir="auto"><strong>Хронометраж приложения (кластер)</strong></p>
<pre><code class="language-bash">pm2 describe myapp             # детали о приложении и рабочих процессах
</code></pre>
<p dir="auto"><strong>Утечка памяти — основной враг Node.js</strong></p>
<p dir="auto">Признак утечки: приложение медленно ест RAM, потом падает.</p>
<p dir="auto">Проверка в коде:</p>
<pre><code class="language-javascript">// Периодически логируем использование памяти
setInterval(() =&gt; {
  const mem = process.memoryUsage();
  console.log(
    `Memory: ${Math.round(mem.heapUsed / 1024 / 1024)}MB / ${Math.round(mem.heapTotal / 1024 / 1024)}MB`
  );
}, 5000);
</code></pre>
<p dir="auto">Если растёт без остановки — утечка. Ищите:</p>
<ul>
<li>забытые listener’ы (<code>EventEmitter</code>);</li>
<li>не закрытые соединения с БД;</li>
<li>циклические ссылки в объектах.</li>
</ul>
<hr />
<h3>9. Типичные боевые ошибки и как их ловить</h3>
<p dir="auto"><strong>Запуск без базы данных</strong></p>
<p dir="auto">Приложение стартует, но падает при первом запросе. Решение:</p>
<pre><code class="language-javascript">// Проверка перед запуском
async function checkConnections() {
  try {
    await db.ping();
    logger.info('Database connected');
  } catch (err) {
    logger.error('Database connection failed:', err);
    process.exit(1);
  }
}

await checkConnections();
app.listen(3000);
</code></pre>
<p dir="auto"><strong>Нестабильность (приложение рестартится сам по себе)</strong></p>
<p dir="auto">Причины: out of memory, exception, зависший процесс.</p>
<pre><code class="language-bash">pm2 logs myapp --err            # смотрим последние ошибки
pm2 monit                       # жмём букву 'l' для логов
</code></pre>
<p dir="auto"><strong>EADDRINUSE: port already in use</strong></p>
<p dir="auto">Порт занят:</p>
<pre><code class="language-bash">ss -tulpen | grep :3000         # кто занял порт
kill -9 PID                     # убить процесс
</code></pre>
<p dir="auto">Или PM2 уже не очистил:</p>
<pre><code class="language-bash">pm2 kill                        # убить PM2 полностью
pm2 start ecosystem.config.js   # начать заново
</code></pre>
<hr />
<h3>10. Обновление и деплой приложения (с нулевым downtime)</h3>
<p dir="auto"><strong>Сценарий: новая версия в Git, нужно обновить в продакшене</strong></p>
<pre><code class="language-bash"># На сервере в директории с приложением
cd /var/www/myapp

# Забрать обновления
git pull origin main

# Установить зависимости (если были изменения в package.json)
npm ci                         # предпочтительнее npm install для продакшена

# Собрать (если есть TypeScript)
npm run build

# Перезапустить приложение с нулевым downtime (PM2 reload)
pm2 reload myapp
</code></pre>
<p dir="auto"><strong>Автоматизация через GitHub Actions (push в main → автоматический деплой)</strong></p>
<p dir="auto"><code>.github/workflows/deploy.yml</code>:</p>
<pre><code class="language-yaml">name: Deploy to production

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Deploy via SSH
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.DEPLOY_KEY }}" &gt; ~/.ssh/key
          chmod 600 ~/.ssh/key
          ssh -i ~/.ssh/key deploy@your-server.com &lt;&lt; 'EOF'
            cd /var/www/myapp
            git pull origin main
            npm ci
            npm run build
            pm2 reload myapp
          EOF
</code></pre>
<hr />
<h3>11. Безопасность: входящие запросы и injection‑атаки</h3>
<p dir="auto"><strong>Базовая валидация в Express / NestJS</strong></p>
<pre><code class="language-typescript">import { IsString, IsEmail, MinLength } from 'class-validator';

export class CreateUserDto {
  @IsString()
  @MinLength(3)
  username: string;

  @IsEmail()
  email: string;

  @IsString()
  @MinLength(8)
  password: string;
}

// В контроллере
@Post('/users')
async create(@Body() dto: CreateUserDto) {
  // Валидация автоматическая, injection невозможна
  return this.usersService.create(dto);
}
</code></pre>
<p dir="auto"><strong>SQL injection защита</strong></p>
<p dir="auto">Никогда не конкатенируйте SQL вручную:</p>
<pre><code class="language-javascript">// ❌ ПЛОХО
const result = await db.query(`SELECT * FROM users WHERE id = ${userId}`);

// ✅ ХОРОШО (parameterized query)
const result = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
</code></pre>
<p dir="auto"><strong>CORS и CSRF</strong></p>
<pre><code class="language-javascript">import cors from 'cors';
import csrf from 'csurf';

// CORS (только свои домены)
app.use(cors({
  origin: ['https://your-site.ru'],
  credentials: true,
}));

// CSRF protection
app.use(csrf({ cookie: false }));
</code></pre>
<hr />
<h3>12. Ротация логов и место на диске</h3>
<p dir="auto">Логи растут бесконечно. Нужна ротация.</p>
<p dir="auto"><strong>PM2 + logrotate</strong></p>
<p dir="auto">Создайте <code>/etc/logrotate.d/pm2-app</code>:</p>
<pre><code>/home/deploy/.pm2/logs/*.log {
  daily
  rotate 14
  compress
  delaycompress
  notifempty
  missingok
  postrotate
    pm2 reload myapp &gt; /dev/null 2&gt;&amp;1 || true
  endscript
}
</code></pre>
<p dir="auto">Проверка:</p>
<pre><code class="language-bash">logrotate -f /etc/logrotate.d/pm2-app   # принудительная ротация
</code></pre>
<p dir="auto"><strong>Проверка размера логов</strong></p>
<pre><code class="language-bash">du -sh ~/.pm2/logs/
ls -lh ~/.pm2/logs/
</code></pre>
<hr />
<h3>13. Быстрые однострочники для Node.js</h3>
<p dir="auto">Поиск всех GET запросов с кодом 404:</p>
<pre><code class="language-bash">grep " 404 " ~/.pm2/logs/myapp-out.log | wc -l
</code></pre>
<p dir="auto">Топ IP-адресов, обращающихся к приложению (если логируете):</p>
<pre><code class="language-bash">grep -oP '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b' ~/.pm2/logs/myapp-out.log | sort | uniq -c | sort -nr | head
</code></pre>
<p dir="auto">Поиск ошибок за последний час:</p>
<pre><code class="language-bash">tail -f ~/.pm2/logs/myapp-error.log | grep "$(date +'%H:%M')"
</code></pre>
<p dir="auto">Убить зависший процесс Node (перезапустится через PM2):</p>
<pre><code class="language-bash">pkill -f "node dist/main.js"
</code></pre>
<hr />
<h3>14. Чек‑лист: запуск Node.js‑приложения в продакшене</h3>
<ol>
<li><strong>Переменные окружения</strong>: <code>.env</code> с DATABASE_URL, API keys, NODE_ENV=production</li>
<li><strong>PM2 конфиг</strong>: <code>ecosystem.config.js</code> с instances, памятью, логами</li>
<li><strong>Nginx</strong>: обратный прокси на localhost:3000</li>
<li><strong>SSL/HTTPS</strong>: Let’s Encrypt + certbot</li>
<li><strong>Логирование</strong>: структурированные логи (pino/winston), ротация</li>
<li><strong>Валидация</strong>: DTO + class-validator для всех input’ов</li>
<li><strong>БД</strong>: миграции, проверка подключения при старте</li>
<li><strong>Мониторинг</strong>: <code>pm2 monit</code>, периодическая проверка памяти</li>
<li><strong>Бэкапы</strong>: регулярное копирование БД и важных файлов</li>
<li><strong>Обновления</strong>: планомерное обновление зависимостей, проверка уязвимостей (<code>npm audit</code>)</li>
</ol>
<hr />
<p dir="auto">Все это <strong>практический минимум</strong> для того, чтобы запустить и поддерживать Node.js на боевом сервере без паники. Мультипроцессность, логирование, мониторинг и безопасность — вот костяк.</p>
<p dir="auto">Когда приложение начнёт падать на продакшене (а оно упадёт — это вопрос времени), эта шпаргалка должна помочь найти причину за 10 минут, а не за час.</p>
]]></description><link>https://forum.exlends.ru/post/1035</link><guid isPermaLink="true">https://forum.exlends.ru/post/1035</guid><dc:creator><![CDATA[Aladdin]]></dc:creator><pubDate>Mon, 08 Dec 2025 12:53:02 GMT</pubDate></item></channel></rss>