Skip to content
← К сниппетам
BashDockerGitGitHub ActionsNginx

DevOps-сниппеты: Docker, Nginx, Git, GitHub Actions

Шестнадцать эксплуатационных сниппетов: многостадийные сборки Docker и контейнеры без root, обратный прокси Nginx с SSL, балансировка и проксирование WebSocket, приёмы Git с rebase, stash и bisect, а также GitHub Actions для CI, деплоя и расписаний.

Всё здесь происходит между «код написан» и «код обслуживает трафик». Четыре инструмента, одна задача: выкатить сборку и удержать её доступной.

Docker: размер образа — это вопрос стадий сборки

Одностадийный образ Node тащит с собой компилятор, dev-зависимости и исходники рядом с тем, что реально запускается. Многостадийная сборка решает это, копируя в чистый рантайм-образ только результат сборки, и разница обычно не маргинальная — это бо́льшая часть образа. Образы поменьше быстрее выкачиваются на каждом деплое и дают меньшую поверхность для сканирования.

Запуск не от root — вторая половина. Контейнеры изолируют слабее виртуальной машины, и процесс, работающий внутри контейнера от root, в конфигурации по умолчанию работает от пользователя, отображаемого в root на хосте. Создание пользователя и переход на него стоят двух строк. Добавление файловой системы только для чтения стоит ещё одной и убирает целый класс закрепления в системе.

Nginx: проксирование простое, WebSocket — исключение

Обратный прокси для HTTP — это четыре директивы. WebSocket требует ещё двух, Upgrade и Connection, потому что без них смены протокола не произойдёт, а проявление сбоя сбивает с толку: рукопожатие возвращает 200 вместо 101, и клиент бесконечно переподключается. Это самый частый вопрос про Nginx у всех, кто добавляет realtime к работающему сайту.

В конфигурации SSL значения по умолчанию важнее всего: генератор конфигураций Mozilla поддерживается в актуальном состоянии, а копирование пятилетнего списка шифров из статьи в блоге — типичный способ не пройти аудит.

Git: три команды для трёх разных ситуаций

Stash — для прерванной работы, к которой вы вернётесь через несколько минут. Интерактивный rebase — для приведения ветки в порядок перед ревью: схлопнуть коммиты «поправил опечатку», чтобы история описывала замысел, а не порядок, в котором мысли приходили в голову. Bisect — для вопроса «когда это сломалось», и он радикально быстрее чтения диффов: находит виновный коммит за считаные шаги независимо от их количества в диапазоне.

GitHub Actions: секреты живут в деплое

Workflow для CI — в основном обвязка. Внимания требует деплой: SSH-ключи место в зашифрованных секретах, а не в репозитории, а workflow по расписанию обязан быть идемпотентным, потому что GitHub не гарантирует точное время запуска и периодически пропускает или задерживает выполнение.

Docker

Docker Compose для Node.js + PostgreSQL + Redis

Production-ready docker-compose.yml для Node.js приложения с PostgreSQL и Redis — стандартный стек SaaS-бэкенда.

Как это работает: три сервиса — app (Node.js), db (PostgreSQL 16) и cache (Redis 7) — на общей сети. Приложение ждёт, пока база и кеш станут здоровы, перед запуском. Тома сохраняют данные между перезапусками, .env подгружается автоматически.

services:
  app:
    build: .
    ports:
      - "3000:3000"
    env_file: .env
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    volumes:
      - .:/app
      - /app/node_modules

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASS}
      POSTGRES_DB: ${DB_NAME}
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
      interval: 5s
      timeout: 5s
      retries: 5

  cache:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redisdata:/data

volumes:
  pgdata:
  redisdata:
# Запустить все сервисы
docker compose up -d

# Смотреть логи приложения
docker compose logs -f app

# Остановить (тома сохраняются)
docker compose down

# Полностью удалить (включая данные)
docker compose down -v
Docker

Docker multi-stage сборки для Node.js

Production Dockerfile с multi-stage сборкой — раздельные стадии для зависимостей, сборки и рантайма — минимальный финальный образ.

Как это работает: три стадии. deps устанавливает зависимости, builder компилирует приложение, runner копирует только нужное в минимальный образ. Ни dev-зависимостей, ни исходников — только скомпилированный код и production node_modules.

# Stage 1: Dependencies
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && pnpm install --frozen-lockfile

# Stage 2: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN corepack enable pnpm && pnpm build

# Stage 3: Production
FROM node:20-alpine AS runner
WORKDIR /app
RUN addgroup --system --gid 1001 nodejs && \
    adduser --system --uid 1001 appuser
COPY --from=builder --chown=appuser:nodejs /app/dist ./dist
COPY --from=builder --chown=appuser:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:nodejs /app/package.json ./
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"]
docker build -t myapp:latest .
docker images --filter reference=myapp
# Финальный образ ~150MB вместо ~1.2GB
Docker

Docker безопасность — non-root пользователь и read-only

Усиление безопасности контейнеров — запуск от непривилегированного пользователя с read-only файловой системой и отключением возможностей ядра.

Как это работает: создание непривилегированного пользователя внутри образа, переключение на него через USER, затем опции безопасности на этапе запуска — --read-only запрещает запись в файловую систему контейнера, --cap-drop=ALL удаляет все возможности ядра, --security-opt=no-new-privileges предотвращает повышение привилегий.

FROM node:20-alpine
RUN addgroup -g 1001 -S appgroup && \
    adduser -u 1001 -S appuser -G appgroup
WORKDIR /app
COPY --chown=appuser:appgroup . .
USER appuser
EXPOSE 3000
CMD ["node", "server.js"]
# Запуск с усиленной безопасностью
docker run --rm \
  --read-only \
  --cap-drop=ALL \
  --security-opt=no-new-privileges:true \
  --tmpfs /tmp \
  -p 3000:3000 \
  myapp:latest

# Аналог в docker-compose
# security_opt:
#   - no-new-privileges:true
# cap_drop:
#   - ALL
# read_only: true
# tmpfs:
#   - /tmp
NginxNginx

Nginx load balancing между Node.js инстансами

Распределение трафика между несколькими Node.js бэкендами с round-robin, проверками здоровья и пассивным failover — без изменений в приложении.

Как это работает: блок upstream определяет группу бэкенд-серверов. Nginx распределяет запросы по round-robin по умолчанию. Если сервер не отвечает, nginx помечает его недоступным и направляет трафик на оставшиеся.

upstream node_backend {
    # Round-robin балансировка (по умолчанию)
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
    server 127.0.0.1:3003;

    # Опционально: наименьшее количество соединений
    # least_conn;

    # Опционально: привязка по IP
    # ip_hash;

    # Сервер на обслуживании
    # server 127.0.0.1:3004 down;

    # Пассивная проверка здоровья
    # После 3 ошибок помечать недоступным на 30с
    server 127.0.0.1:3005 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://node_backend;
        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_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Таймауты
        proxy_connect_timeout 5s;
        proxy_read_timeout 10s;
        proxy_send_timeout 10s;
    }
}
# Запуск нескольких Node.js инстансов через PM2
pm2 start server.js -i 3
NginxNginx

Nginx reverse proxy с SSL termination

Hardened-конфигурация nginx для проксирования Node.js приложений — SSL termination, rate limiting, заголовки безопасности и gzip.

Как это работает: nginx завершает TLS на границе, перенаправляет запросы на локальный Node.js бэкенд, добавляет заголовки безопасности, ограничение скорости и gzip-сжатие — до того, как запрос дойдёт до приложения.

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate     /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    # Заголовки безопасности
    add_header Strict-Transport-Security "max-age=63072000" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    # Rate limiting
    limit_req zone=api burst=20 nodelay;
    limit_req_status 429;

    # Gzip
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    location / {
        proxy_pass http://127.0.0.1:3000;
        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_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$host$request_uri;
}
# Проверить конфиг перед перезагрузкой
sudo nginx -t

# Перезагрузить без разрыва соединений
sudo nginx -s reload
NginxNginx

Nginx статический сервер с кешированием

Раздача статики (CSS, JS, изображения) с заголовками кеширования на год, gzip-сжатием и SPA-роутингом — без серверного приложения.

Как это работает: nginx отдаёт файлы из /var/www/html напрямую — без прокси. Заголовки кеша указывают браузеру хранить ассеты год; файлы с хешем в имени безопасно кешировать навсегда. Gzip уменьшает объём передачи, try_files включает SPA-роутинг.

server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    index index.html;

    # Gzip
    gzip on;
    gzip_types text/plain text/css application/json application/javascript image/svg+xml;
    gzip_min_length 256;

    # Долгий кеш для версионированных ассетов
    location ~* \.(?:css|js|svg|woff2?)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # Кеш для изображений на неделю
    location ~* \.(?:jpg|jpeg|png|webp|avif)$ {
        expires 7d;
        add_header Cache-Control "public";
    }

    # Без кеша для HTML
    location ~* \.html?$ {
        expires -1;
        add_header Cache-Control "no-cache";
    }

    # SPA fallback
    location / {
        try_files $uri $uri/ /index.html;
    }

    # Запрет доступа к скрытым файлам
    location ~ /\. {
        deny all;
    }
}
NginxNginx

Nginx WebSocket прокси для real-time приложений

Проксирование WebSocket-соединений через nginx — необходимо для Socket.io, живого чата и совместного редактирования за reverse proxy.

Как это работает: WebSocket-соединения начинаются как HTTP-апгрейд. Заголовки Upgrade и Connection должны явно передаваться. Без этой конфигурации nginx закрывает соединение через 60с. proxy_read_timeout в 1ч держит долгоживущие WebSocket-соединения открытыми.

server {
    listen 80;
    server_name app.example.com;

    location /ws {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;

        # Заголовки для WebSocket upgrade
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Стандартные proxy-заголовки
        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;

        # Долгий таймаут для постоянных соединений
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }

    # Обычный HTTP-трафик
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
# Проверка WebSocket-соединения
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Sec-WebSocket-Version: 13" \
  -H "Sec-WebSocket-Key: $(openssl rand -base64 16)" http://app.example.com/ws
GitGit

Git cherry-pick и bisect — точечная работа с коммитами

Cherry-pick применяет конкретный коммит из любой ветки. Bisect — бинарный поиск по истории для нахождения коммита, внёсшего баг.

Как это работает: cherry-pick берёт diff из одного коммита и применяет к HEAD — без merge и rebase. bisect помечает коммиты как хорошие или плохие, а Git сужает круг до точного коммита, где всё сломалось — обычно за меньше чем 10 шагов даже для тысяч коммитов.

# Применить один коммит
git cherry-pick a1b2c3d

# Применить без авто-коммита
git cherry-pick --no-commit a1b2c3d

# Применить диапазон коммитов
git cherry-pick a1b2c3d..e5f6g7h

# Cherry-pick из другой ветки
git checkout main
git cherry-pick feature-branch~3..feature-branch

# Начать bisect
git bisect start
git bisect bad          # текущий коммит сломан
git bisect good v2.0.0  # последний известный рабочий

# Git переключается на середину — тестируем:
git bisect good   # или git bisect bad
# Повторяем, пока Git не найдёт первый плохой коммит

# Завершить bisect
git bisect reset

# Посмотреть изменения в коммите
git show a1b2c3d
GitGit

Git log — фильтрация и форматирование истории

Поиск, фильтрация и форматирование Git-лога — находите коммиты по автору, дате, файлу или содержимому одной строкой.

Как это работает: git log принимает десятки флагов фильтрации. Комбинируйте их, чтобы найти нужные коммиты — кто, когда и зачем изменил файл — без пролистывания нерелевантной истории.

# Одна строка на коммит
git log --oneline

# Граф с ветками
git log --oneline --graph --all

# Коммиты по автору
git log --author="Alex"

# Коммиты после даты
git log --since="2026-06-01"
git log --after="2 weeks ago"

# Коммиты, изменившие файл
git log --oneline -- src/server.ts

# Поиск по сообщению
git log --grep="fix:" --oneline

# Поиск по коду
git log -S "calculateTotal" --oneline

# Коммиты в диапазоне дат
git log --since="2026-06-01" --until="2026-07-01"

# Кастомный формат
git log --pretty=format:"%h %an %ar %s"

# Статистика изменений
git log --stat --oneline

# Последние 5 коммитов
git log -5 --oneline

# Коммиты в ветке, которых нет в main
git log main..feature --oneline
GitGit

Git squash коммитов и интерактивный rebase

Очистка Git-истории с помощью squash, fixup и интерактивного rebase — читаемый лог коммитов перед мержем.

Как это работает: интерактивный rebase (git rebase -i) открывает редактор, где можно склеить (squash), объединить без сообщения (fixup), переименовать или переупорядочить коммиты. Squash объединяет коммит с предыдущим и позволяет отредактировать сообщение; fixup делает то же самое, но сообщение отбрасывает — идеально для коммитов вида "fix typo" и "wip".

# Склеить последние 3 коммита в один
git rebase -i HEAD~3

# Редактор покажет:
# pick a1b2c3d Add login page
# pick e4f5g6h Fix typo on login page
# pick i7j8k9l Add tests for login

# Меняем на:
# pick a1b2c3d Add login page
# squash e4f5g6h Fix typo on login page
# fixup i7j8k9l Add tests for login
# Сохраняем и закрываем → один чистый коммит
# Склеить все коммиты фича-ветки в один
git checkout feature/my-feature
git rebase -i main

# Пометить все коммиты кроме первого как "squash"
# или однострочник:
git reset --soft main
git commit -m "feat: add my feature"
# Исправить последний коммит (если ещё не запушен)
git add . && git commit --amend --no-edit

# Force push после rebase (только в feature-ветках!)
git push --force-with-lease
GitGit

Git stash — сохранение и восстановление черновиков

Временно сохраните незакоммиченные изменения через git stash — переключайте ветки, подтягивайте обновления и восстанавливайте работу без потерь.

Как это работает: git stash берёт все отслеживаемые, но незакоммиченные изменения и помещает их в стек. Рабочая директория становится чистой — можно переключать ветки. git stash pop восстанавливает последний stash и удаляет его из стека.

# Сохранить текущие изменения (только отслеживаемые)
git stash

# Сохранить включая новые файлы
git stash -u

# Сохранить с описанием
git stash push -m "WIP: рефакторинг auth middleware"

# Посмотреть все сохранения
git stash list
# stash@{0}: On feature/login: WIP: рефакторинг auth middleware
# stash@{1}: WIP: правки шапки

# Восстановить последний stash
git stash pop

# Восстановить конкретный stash
git stash pop stash@{1}

# Применить stash без удаления из стека
git stash apply stash@{0}

# Создать ветку из stash (решает конфликты)
git stash branch feature/new-branch stash@{0}

# Удалить конкретный stash
git stash drop stash@{1}

# Очистить все stash
git stash clear
GitHub Actions

GitHub Actions — CI пайплайн для PR

Запуск линтинга, type-check и тестов на каждый pull request до мержа — быстрый отказ с понятными аннотациями в PR.

Как это работает: триггер на pull_request в main — настраивает Node.js, устанавливает зависимости с кешированием, параллельно запускает lint, type-check и тесты, затем загружает результаты как аннотации в PR.

name: CI

on:
  pull_request:
    branches: [main]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run lint
      - run: npm run typecheck
      - run: npm test -- --coverage
      - uses: dorny/paths-filter@v3
        id: changes
        with:
          filters: |
            src:
              - 'src/**'
      - name: Upload coverage
        if: steps.changes.outputs.src == 'true'
        uses: codecov/codecov-action@v4
# Требуемые настройки защиты ветки:
# Включить проверку статуса "quality" перед мержем
GitHub Actions

GitHub Actions — деплой Node.js на VPS через SSH

CI/CD пайплайн, который линтит, тестирует, собирает и деплоит Node.js приложение на VPS через SSH с zero-downtime.

Как это работает: при каждом пуше в main воркфлоу забирает код, устанавливает зависимости, запускает линтинг и тесты, собирает проект, синхронизирует сборку на VPS через rsync по SSH и выполняет zero-downtime перезагрузку через PM2.

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - run: npm ci
      - run: npm run lint
      - run: npm test
      - run: npm run build

      - name: Deploy via rsync
        uses: easingthemes/ssh-deploy@v4
        with:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
          REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
          REMOTE_USER: ${{ secrets.REMOTE_USER }}
          SOURCE: .output/
          TARGET: /var/www/app/
          ARGS: -rlpDzvc --delete

      - name: Reload app
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.REMOTE_HOST }}
          username: ${{ secrets.REMOTE_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/app
            pm2 reload ecosystem.config.js
# Необходимые секреты для воркфлоу:
# SSH_PRIVATE_KEY — ключ деплоя
# REMOTE_HOST — IP или домен VPS
# REMOTE_USER — SSH пользователь
GitHub Actions

GitHub Actions — сборка и публикация Docker образа

Автоматическая сборка и публикация Docker образа в Docker Hub или GitHub Container Registry на каждый push в main — с кешированием слоёв.

Как это работает: при пуше в main воркфлоу логинится в registry, настраивает Docker Buildx для multi-platform сборок, использует GitHub Actions кеш для слоёв, собирает образ с версионными тегами и публикует. Для PR образ собирается без публикации.

name: Docker Build & Push

on:
  push:
    branches: [main]
    tags: ['v*']
  pull_request:
    branches: [main]

jobs:
  docker:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ghcr.io/${{ github.repository }}
          tags: |
            type=semver,pattern={{version}}
            type=ref,event=branch
            type=sha,format=short

      - name: Build and push
        uses: docker/build-push-action@v6
        with:
          context: .
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
GitHub Actions

GitHub Actions — запланированные задачи по cron

Запуск воркфлоу по расписанию — ежедневные бэкапы, еженедельные обновления зависимостей, почасовые проверки здоровья — через cron-синтаксис.

Как это работает: событие schedule использует POSIX cron-синтаксис. Воркфлоу запускается в заданные интервалы независимо от пушей. workflow_dispatch позволяет запустить вручную для тестирования.

name: Daily Backup

on:
  schedule:
    # Каждый день в 2:00 UTC
    - cron: '0 2 * * *'
  workflow_dispatch:

jobs:
  backup:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Create database dump
        run: |
          pg_dump $DATABASE_URL > backup_$(date +%Y-%m-%d).sql
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}

      - name: Upload to S3-compatible storage
        uses: jakejarvis/s3-sync-action@v1
        with:
          args: --acl private
        env:
          AWS_S3_BUCKET: ${{ secrets.AWS_BACKUP_BUCKET }}
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          SOURCE_DIR: .
# Часто используемые расписания:
# Каждый час:          0 * * * *
# Ежедневно в полночь: 0 0 * * *
# Еженедельно в понед: 0 0 * * 1
# Ежемесячно 1-го:     0 0 1 * *
# Каждые 15 минут:     */15 * * * *
BashBash

yt-dlp — полезные Bash-функции для видео, аудио и субтитров

Набор функций для .bashrc / .zshrc для быстрой загрузки видео (до 1080p), экспорта в MP3, очистки субтитров от таймкодов и сохранения превью.

Готовый набор функций для добавления в ваш ~/.bashrc или ~/.zshrc. Использует куки Firefox, Node.js runtime и обходит типичные ограничения скачивания через yt-dlp.

Описание функций и мнемоника для запоминания:

Префикс dlp легко запоминается как DownLoad Please («Скачай, пожалуйста») или сокращение от yt-dlp, а суффикс указывает на нужный формат:

  • dlpv URL — DownLoad Please Video — скачивание видео в качестве до 1080p (MP4 + M4A).
  • dlpa URL — DownLoad Please Audio — извлечение и конвертация аудио в MP3.
  • dlps URL — DownLoad Please Subtitles — загрузка только чистых субтитров без видео.
  • dlpvs URL — DownLoad Please Video + Subtitles — скачивание видео с очищенными англоязычными субтитрами.
  • dlpvt URL — DownLoad Please Video + Thumbnail — скачивание видео вместе с обложкой.
# video
dlpv() {
    yt-dlp --cookies-from-browser Firefox --js-runtime node --remote-components ejs:github -f "bestvideo[height<=1080][ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best" "$1"
}

# audio
dlpa() {
    yt-dlp --cookies-from-browser Firefox --js-runtime node --remote-components ejs:github -x --audio-format mp3 -o "%(title)s [%(id)s].%(ext)s" "$1"
}

# video & subtitles
dlpvs() {
    yt-dlp --cookies-from-browser Firefox --js-runtime node --remote-components ejs:github --write-subs --write-auto-subs --sub-lang en --sub-format ttml --convert-subs txt --exec before_dl:"sed -e '/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9] --> [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]$/d' -e '/^[[:digit:]]\{1,3\}$/d' -e 's/<[^>]*>//g' -e '/^[[:space:]]*$/d' -i '' %(requested_subtitles.:.filepath)#q" -f "bestvideo[height<=1080][ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best" "$1"
}

# subtitles
dlps() {
    yt-dlp --cookies-from-browser Firefox --js-runtime node --remote-components ejs:github --skip-download --write-subs --write-auto-subs --sub-lang en --sub-format ttml --convert-subs txt --exec before_dl:"sed -e '/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9] --> [0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]$/d' -e '/^[[:digit:]]\{1,3\}$/d' -e 's/<[^>]*>//g' -e '/^[[:space:]]*$/d' -i '' %(requested_subtitles.:.filepath)#q" "$1"
}

# video & thumbnail
dlpvt() {
    yt-dlp --cookies-from-browser Firefox --js-runtime node --remote-components ejs:github --write-thumbnail -f "bestvideo[height<=1080][ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best" "$1"
}
// CONNECT

Контактная информация

Оставьте заявку или напишите напрямую в телеграм. Я отвечу в течение 24 часов.

Укажите email или Telegram, чтобы я мог вам ответить.