Some updates, mostly problems with postgres permissions and logs permissions, mess with improper master management service processing from .env
This commit is contained in:
parent
b3fee7eec2
commit
2786f5ba72
@ -1,4 +1,35 @@
|
||||
# This file should be generated from ansible/templates/.env.ytdlp.j2
|
||||
# Do not edit manually - your changes will be overwritten.
|
||||
#
|
||||
# To generate this file, run the Ansible playbook that processes the templates.
|
||||
# This file is managed by Ansible. Do not edit manually.
|
||||
|
||||
# --- Common Settings ---
|
||||
HOSTNAME="af-green"
|
||||
COMPOSE_PROJECT_NAME="ytdlp-ops-management"
|
||||
TZ="Europe/Moscow"
|
||||
service_role="management"
|
||||
|
||||
# --- Docker Image Settings ---
|
||||
YTDLP_OPS_IMAGE="pangramia/ytdlp-ops-server:latest"
|
||||
AIRFLOW_IMAGE_NAME="pangramia/ytdlp-ops-airflow:latest"
|
||||
|
||||
# --- Network Settings ---
|
||||
ENVOY_PORT=9080
|
||||
ENVOY_ADMIN_PORT=9901
|
||||
YTDLP_BASE_PORT=9090
|
||||
YTDLP_WORKERS=3
|
||||
MANAGEMENT_SERVICE_PORT=9091
|
||||
REDIS_PORT=52909
|
||||
POSTGRES_PORT=5432
|
||||
|
||||
# --- Security Settings ---
|
||||
REDIS_PASSWORD="rOhTAIlTFFylXsjhqwxnYxDChFc"
|
||||
POSTGRES_PASSWORD="pgdb_pwd_A7bC2xY9zE1wV5uP"
|
||||
AIRFLOW_ADMIN_PASSWORD="2r234sdfrt3q454arq45q355"
|
||||
FLOWER_PASSWORD="dO4eXm7UkF81OdMvT8E2tIKFtPYPCzyzwlcZ4RyOmCsmG4qzrNFqM5sNTOT9"
|
||||
|
||||
# --- User and Group IDs ---
|
||||
AIRFLOW_UID=1003
|
||||
AIRFLOW_GID=1001
|
||||
|
||||
# --- Master-specific settings ---
|
||||
MASTER_HOST_IP=89.253.221.173
|
||||
# Camoufox is not used on master, but the config generator expects the variable.
|
||||
CAMOUFOX_PROXIES=
|
||||
|
||||
@ -149,6 +149,7 @@ services:
|
||||
retries: 5
|
||||
start_period: 5s
|
||||
restart: always
|
||||
user: "999:999"
|
||||
|
||||
redis:
|
||||
# Redis is limited to 7.2-bookworm due to licencing change
|
||||
|
||||
@ -78,7 +78,7 @@ services:
|
||||
- "--service-role"
|
||||
- "{{ service_role }}"
|
||||
|
||||
{% if service_role != 'management' %}
|
||||
{% if service_role is defined and service_role != 'management' %}
|
||||
# --- Parameters for worker/all-in-one roles ONLY ---
|
||||
- "--script-dir"
|
||||
- "/app"
|
||||
@ -100,9 +100,7 @@ services:
|
||||
volumes:
|
||||
context-data:
|
||||
|
||||
{% if service_role == 'management' or not camoufox_proxies %}
|
||||
networks:
|
||||
proxynet:
|
||||
name: airflow_proxynet
|
||||
external: true
|
||||
{% endif %}
|
||||
|
||||
@ -8,6 +8,6 @@ services:
|
||||
- ./.env
|
||||
volumes:
|
||||
# Mount the entire project directory to access scripts and write output files
|
||||
- ../:/app
|
||||
- .:/app
|
||||
command: >
|
||||
sh -c "pip install jinja2 && python3 /app/generate_envoy_config.py"
|
||||
|
||||
135
airflow/dags/ORCHESTRATOR.ru.md
Normal file
135
airflow/dags/ORCHESTRATOR.ru.md
Normal file
@ -0,0 +1,135 @@
|
||||
# Архитектура и описание YTDLP Airflow DAGs
|
||||
|
||||
Этот документ описывает архитектуру и назначение DAG'ов, используемых для скачивания видео с YouTube. Система построена на модели непрерывного, самоподдерживающегося цикла для параллельной и отказоустойчивой обработки.
|
||||
|
||||
## Основной цикл обработки
|
||||
|
||||
Обработка выполняется двумя основными DAG'ами, которые работают в паре: оркестратор и воркер.
|
||||
|
||||
### `ytdlp_ops_orchestrator` (Система "зажигания")
|
||||
|
||||
- **Назначение:** Этот DAG действует как "система зажигания" для запуска обработки. Он запускается вручную для старта указанного количества параллельных циклов-воркеров.
|
||||
- **Принцип работы:**
|
||||
- Он **не** обрабатывает URL-адреса самостоятельно.
|
||||
- Его единственная задача — запустить сконфигурированное количество DAG'ов `ytdlp_ops_worker_per_url`.
|
||||
- Он передает всю необходимую конфигурацию (пул аккаунтов, подключение к Redis и т.д.) воркерам.
|
||||
|
||||
### `ytdlp_ops_worker_per_url` (Самоподдерживающийся воркер)
|
||||
|
||||
- **Назначение:** Этот DAG обрабатывает один URL и спроектирован для работы в непрерывном цикле.
|
||||
- **Принцип работы:**
|
||||
1. **Запуск:** Начальный запуск инициируется `ytdlp_ops_orchestrator`.
|
||||
2. **Получение задачи:** Воркер извлекает один URL из очереди `_inbox` в Redis. Если очередь пуста, выполнение воркера завершается, и его "линия" обработки останавливается.
|
||||
3. **Обработка:** Он взаимодействует с сервисом `ytdlp-ops-server` для получения `info.json` и прокси, после чего скачивает видео.
|
||||
4. **Продолжение или остановка:**
|
||||
- **В случае успеха:** Он запускает новый экземпляр самого себя, создавая непрерывный цикл для обработки следующего URL.
|
||||
- **В случае сбоя:** Цикл прерывается (если `stop_on_failure` установлено в `True`), останавливая эту "линию" обработки. Это предотвращает остановку всей системы из-за одного проблемного URL или аккаунта.
|
||||
|
||||
## Управляющие DAG'и
|
||||
|
||||
### `ytdlp_mgmt_proxy_account`
|
||||
|
||||
- **Назначение:** Это основной инструмент для мониторинга и управления состоянием ресурсов, используемых `ytdlp-ops-server`.
|
||||
- **Функциональность:**
|
||||
- **Просмотр статусов:** Позволяет увидеть текущий статус всех прокси и аккаунтов (например, `ACTIVE`, `BANNED`, `RESTING`).
|
||||
- **Управление прокси:** Позволяет вручную банить, разбанивать или сбрасывать статус прокси.
|
||||
- **Управление аккаунтами:** Позволяет вручную банить или разбанивать аккаунты.
|
||||
|
||||
### `ytdlp_mgmt_queues`
|
||||
|
||||
- **Назначение:** Предоставляет набор инструментов для управления очередями Redis, используемыми в конвейере обработки.
|
||||
- **Функциональность (через параметр `action`):**
|
||||
- `add_videos`: Добавление одного или нескольких URL-адресов YouTube в очередь.
|
||||
- `clear_queue`: Очистка (удаление) указанного ключа Redis.
|
||||
- `list_contents`: Просмотр содержимого ключа Redis (списка или хэша).
|
||||
- `check_status`: Проверка общего состояния очередей (тип, размер).
|
||||
- `requeue_failed`: Перемещение всех URL-адресов из очереди сбоев `_fail` обратно в очередь `_inbox` для повторной обработки.
|
||||
|
||||
## Стратегия управления ресурсами (Прокси и Аккаунты)
|
||||
|
||||
Система использует интеллектуальную стратегию для управления жизненным циклом и состоянием аккаунтов и прокси, чтобы максимизировать процент успеха и минимизировать блокировки.
|
||||
|
||||
- **Жизненный цикл аккаунта ("Cooldown"):**
|
||||
- Чтобы предотвратить "выгорание", аккаунты автоматически переходят в состояние "отдыха" (`RESTING`) после периода интенсивного использования.
|
||||
- По истечении периода отдыха они автоматически возвращаются в `ACTIVE` и снова становятся доступными для воркеров.
|
||||
|
||||
- **Умная стратегия банов:**
|
||||
- **Сначала бан аккаунта:** При возникновении серьезной ошибки (например, `BOT_DETECTED`) система наказывает **только аккаунт**, который вызвал сбой. Прокси при этом продолжает работать.
|
||||
- **Бан прокси по "скользящему окну":** Прокси банится автоматически, только если он демонстрирует **систематические сбои с РАЗНЫМИ аккаунтами** за короткий промежуток времени. Это является надежным индикатором того, что проблема именно в прокси.
|
||||
|
||||
- **Мониторинг:**
|
||||
- DAG `ytdlp_mgmt_proxy_account` является основным инструментом для мониторинга. Он показывает текущий статус всех ресурсов, включая время, оставшееся до активации забаненных или отдыхающих аккаунтов.
|
||||
- Граф выполнения DAG `ytdlp_ops_worker_per_url` теперь явно показывает шаги, такие как `assign_account`, `get_token`, `ban_account`, `retry_get_token`, что делает процесс отладки более наглядным.
|
||||
|
||||
## Внешние сервисы
|
||||
|
||||
### `ytdlp-ops-server` (Thrift Service)
|
||||
|
||||
- **Назначение:** Внешний сервис, который предоставляет аутентификационные данные (токены, cookies, proxy) для скачивания видео.
|
||||
- **Взаимодействие:** Worker DAG (`ytdlp_ops_worker_per_url`) обращается к этому сервису перед началом загрузки для получения необходимых данных для `yt-dlp`.
|
||||
|
||||
## Логика работы Worker DAG (`ytdlp_ops_worker_per_url`)
|
||||
|
||||
Этот DAG является "рабочей лошадкой" системы. Он спроектирован как самоподдерживающийся цикл для обработки одного URL за запуск.
|
||||
|
||||
### Задачи и их назначение:
|
||||
|
||||
- **`pull_url_from_redis`**: Извлекает один URL из очереди `_inbox` в Redis. Если очередь пуста, DAG завершается со статусом `skipped`, останавливая эту "линию" обработки.
|
||||
- **`assign_account`**: Выбирает аккаунт для выполнения задачи. Он будет повторно использовать тот же аккаунт, который был успешно использован в предыдущем запуске в своей "линии" (привязка аккаунта). Если это первый запуск, он выбирает случайный аккаунт.
|
||||
- **`get_token`**: Основная задача. Она обращается к `ytdlp-ops-server` для получения `info.json`.
|
||||
- **`handle_bannable_error_branch`**: Если `get_token` завершается с ошибкой, требующей бана, эта задача-развилка решает, что делать дальше, в зависимости от политики `on_bannable_failure`.
|
||||
- **`ban_account_and_prepare_for_retry`**: Если политика разрешает повтор, эта задача банит сбойный аккаунт и выбирает новый для повторной попытки.
|
||||
- **`retry_get_token`**: Выполняет вторую попытку получить токен с новым аккаунтом.
|
||||
- **`ban_second_account_and_proxy`**: Если и вторая попытка неудачна, эта задача банит второй аккаунт и использованный прокси.
|
||||
- **`download_and_probe`**: Если `get_token` (или `retry_get_token`) завершилась успешно, эта задача использует `yt-dlp` для скачивания медиа и `ffmpeg` для проверки целостности скачанного файла.
|
||||
- **`mark_url_as_success`**: Если `download_and_probe` завершилась успешно, эта задача записывает результат в хэш `_result` в Redis.
|
||||
- **`handle_generic_failure`**: Если любая из основных задач завершается с неисправимой ошибкой, эта задача записывает подробную информацию об ошибке в хэш `_fail` в Redis.
|
||||
- **`decide_what_to_do_next`**: Задача-развилка, которая запускается после успеха или неудачи. Она решает, продолжать ли цикл.
|
||||
- **`trigger_self_run`**: Задача, которая фактически запускает следующий экземпляр DAG, создавая непрерывный цикл.
|
||||
|
||||
## Механизм привязки воркеров к конкретным машинам (Worker Pinning / Affinity)
|
||||
|
||||
Для обеспечения того, чтобы все задачи, связанные с обработкой одного конкретного URL, выполнялись на одной и той же машине (воркере), система использует комбинацию из трех компонентов: Оркестратора, Диспетчера и специального хука Airflow.
|
||||
|
||||
### 1. `ytdlp_ops_orchestrator` (Оркестратор)
|
||||
|
||||
- **Роль:** Инициирует процесс обработки.
|
||||
- **Действие:** При запуске он создает несколько DAG-запусков `ytdlp_ops_dispatcher`. Каждый такой запуск предназначен для обработки одного URL.
|
||||
- **Передача параметров:** Оркестратор передает свои параметры конфигурации (например, `account_pool`, `redis_conn_id`, `service_ip`) каждому запуску диспетчера.
|
||||
|
||||
### 2. `ytdlp_ops_dispatcher` (Диспетчер)
|
||||
|
||||
- **Роль:** Основной механизм обеспечения привязки.
|
||||
- **Действие:**
|
||||
1. **Получает URL:** Извлекает один URL из очереди Redis (`_inbox`).
|
||||
2. **Определяет воркер:** Использует `socket.gethostname()` для определения имени текущей машины (воркера), на которой он выполняется.
|
||||
3. **Формирует имя очереди:** Создает уникальное имя очереди для этого воркера, например, `queue-dl-dl-worker-1`.
|
||||
4. **Запускает Worker DAG:** Инициирует запуск DAG `ytdlp_ops_worker_per_url`, передавая ему:
|
||||
* Извлеченный `url_to_process`.
|
||||
* Сформированное имя очереди `worker_queue` через параметр `conf`.
|
||||
* Все остальные параметры, полученные от оркестратора.
|
||||
- **Ключевой момент:** Именно на этом этапе устанавливается связь между конкретным URL и конкретным воркером, на котором началась обработка этого URL.
|
||||
|
||||
### 3. `task_instance_mutation_hook` (Хук изменения задач)
|
||||
|
||||
- **Расположение:** `airflow/config/custom_task_hooks.py`
|
||||
- **Роль:** Является механизмом, который обеспечивает выполнение *всех* задач Worker DAG на нужной машине.
|
||||
- **Как это работает:**
|
||||
1. **Регистрация:** Хук регистрируется в конфигурации Airflow и вызывается перед запуском *каждой* задачи.
|
||||
2. **Проверка DAG ID:** Хук проверяет, принадлежит ли задача (`TaskInstance`) DAG `ytdlp_ops_worker_per_url`.
|
||||
3. **Извлечение `conf`:** Если да, он безопасно извлекает `conf` из `DagRun`, связанного с этой задачей.
|
||||
4. **Изменение очереди:**
|
||||
* Если в `conf` найден ключ `worker_queue` (что будет true для всех запусков, инициированных диспетчером), хук *переопределяет* стандартную очередь задачи на это значение.
|
||||
* Это означает, что Airflow планировщик поставит эту задачу именно в ту очередь, которая прослушивается нужным воркером.
|
||||
5. **Резервный вариант:** Если `worker_queue` не найден (например, DAG запущен вручную), задача возвращается в стандартную очередь `queue-dl`.
|
||||
- **Ключевой момент:** Этот хук гарантирует, что *все последующие задачи* в рамках одного запуска `ytdlp_ops_worker_per_url` (например, `get_token`, `download_and_probe`, `mark_url_as_success`) будут выполнены на том же воркере, который изначально получил URL в диспетчере.
|
||||
|
||||
### Резюме
|
||||
|
||||
Комбинация `Оркестратор -> Диспетчер -> Хук` эффективно реализует привязку задач к воркерам:
|
||||
|
||||
1. **Оркестратор** запускает процесс.
|
||||
2. **Диспетчер** связывает конкретный URL с конкретным воркером, определяя его имя хоста и передавая его как `worker_queue` в Worker DAG.
|
||||
3. **Хук** гарантирует, что все задачи Worker DAG выполняются в очереди, соответствующей этому воркеру.
|
||||
|
||||
Это позволяет системе использовать локальные ресурсы воркера (например, кэш, временные файлы) эффективно и предсказуемо для обработки каждого отдельного URL.
|
||||
@ -33,7 +33,7 @@ def load_dotenv(dotenv_path):
|
||||
"""
|
||||
if not os.path.exists(dotenv_path):
|
||||
logging.warning(f".env file not found at {dotenv_path}. Using system environment variables or defaults.")
|
||||
return
|
||||
return False
|
||||
try:
|
||||
with open(dotenv_path) as f:
|
||||
for line in f:
|
||||
@ -43,6 +43,7 @@ def load_dotenv(dotenv_path):
|
||||
key = key.strip()
|
||||
value = value.strip()
|
||||
# Remove surrounding quotes which are common in .env files
|
||||
# Handle both single and double quotes
|
||||
if (value.startswith('"') and value.endswith('"')) or \
|
||||
(value.startswith("'") and value.endswith("'")):
|
||||
value = value[1:-1]
|
||||
@ -53,9 +54,10 @@ def load_dotenv(dotenv_path):
|
||||
if key not in os.environ:
|
||||
os.environ[key] = value
|
||||
logging.info(f"Successfully loaded variables from {dotenv_path}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to read or parse {dotenv_path}: {e}")
|
||||
# Continue, will use defaults or system env vars
|
||||
return False
|
||||
|
||||
def _get_port_from_proxy_url(url: str) -> Optional[str]:
|
||||
"""Extracts the port from a proxy URL string."""
|
||||
@ -94,9 +96,18 @@ def generate_configs():
|
||||
project_root = os.path.dirname(os.path.abspath(__file__)) # This will be /app
|
||||
configs_dir = os.path.join(project_root, 'configs')
|
||||
|
||||
# Load .env from the 'configs' directory.
|
||||
dotenv_path = os.path.join(configs_dir, '.env')
|
||||
load_dotenv(dotenv_path)
|
||||
# Load .env from the project root ONLY - no fallback
|
||||
dotenv_path = os.path.join(project_root, '.env')
|
||||
logging.info(f"Looking for .env file at: {dotenv_path}")
|
||||
|
||||
if os.path.exists(dotenv_path):
|
||||
if load_dotenv(dotenv_path):
|
||||
logging.info(f"Using .env file from: {dotenv_path}")
|
||||
else:
|
||||
logging.error(f"Failed to load .env file from: {dotenv_path}")
|
||||
exit(1)
|
||||
else:
|
||||
logging.warning(f".env file not found at {dotenv_path}. Using system environment variables or defaults.")
|
||||
|
||||
# --- Common Configuration ---
|
||||
ytdlp_workers_str = os.getenv('YTDLP_WORKERS', '3').strip()
|
||||
@ -117,7 +128,13 @@ def generate_configs():
|
||||
env.globals['_get_port_from_proxy_url'] = _get_port_from_proxy_url
|
||||
|
||||
# Get service role from environment to determine what to generate
|
||||
service_role = os.getenv('SERVICE_ROLE', 'all-in-one')
|
||||
# Ensure we strip any remaining quotes that might have slipped through
|
||||
service_role = os.getenv('service_role', 'management')
|
||||
# Additional stripping of quotes for robustness
|
||||
if (service_role.startswith('"') and service_role.endswith('"')) or \
|
||||
(service_role.startswith("'") and service_role.endswith("'")):
|
||||
service_role = service_role[1:-1]
|
||||
|
||||
logging.info(f"Service role for generation: '{service_role}'")
|
||||
|
||||
# --- Camoufox Configuration (only for worker/all-in-one roles) ---
|
||||
|
||||
@ -17,7 +17,7 @@ external_access_ips: []
|
||||
file_permissions: '0644'
|
||||
host_timezone: Europe/Moscow
|
||||
management_service_port: 9091
|
||||
master_host_ip: 89.253.223.97
|
||||
master_host_ip: 89.253.221.173
|
||||
postgres_port: 5432
|
||||
redis_port: 52909
|
||||
rsync_default_opts:
|
||||
|
||||
22
ansible/host_vars/af-green.yml
Normal file
22
ansible/host_vars/af-green.yml
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
# Variables for af-green
|
||||
master_host_ip: 89.253.221.173
|
||||
redis_port: 52909
|
||||
shadowsocks_proxies:
|
||||
sslocal-rust-1087:
|
||||
server: "91.103.252.51"
|
||||
server_port: 8388
|
||||
local_port: 1087
|
||||
vault_password_key: "vault_ss_password_1"
|
||||
sslocal-rust-1086:
|
||||
server: "62.60.178.45"
|
||||
server_port: 8388
|
||||
local_port: 1086
|
||||
vault_password_key: "vault_ss_password_2"
|
||||
sslocal-rust-1081:
|
||||
server: "79.137.207.43"
|
||||
server_port: 8388
|
||||
local_port: 1081
|
||||
vault_password_key: "vault_ss_password_2"
|
||||
worker_proxies:
|
||||
- "socks5://sslocal-rust-1087:1087"
|
||||
22
ansible/host_vars/dl001.yml
Normal file
22
ansible/host_vars/dl001.yml
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
# Variables for dl001
|
||||
master_host_ip: 89.253.221.173
|
||||
redis_port: 52909
|
||||
shadowsocks_proxies:
|
||||
sslocal-rust-1087:
|
||||
server: "91.103.252.51"
|
||||
server_port: 8388
|
||||
local_port: 1087
|
||||
vault_password_key: "vault_ss_password_1"
|
||||
sslocal-rust-1086:
|
||||
server: "62.60.178.45"
|
||||
server_port: 8388
|
||||
local_port: 1086
|
||||
vault_password_key: "vault_ss_password_2"
|
||||
sslocal-rust-1081:
|
||||
server: "79.137.207.43"
|
||||
server_port: 8388
|
||||
local_port: 1081
|
||||
vault_password_key: "vault_ss_password_2"
|
||||
worker_proxies:
|
||||
- "socks5://sslocal-rust-1087:1087"
|
||||
22
ansible/host_vars/dl003.yml
Normal file
22
ansible/host_vars/dl003.yml
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
# Variables for dl003
|
||||
master_host_ip: 89.253.221.173
|
||||
redis_port: 52909
|
||||
shadowsocks_proxies:
|
||||
sslocal-rust-1087:
|
||||
server: "91.103.252.51"
|
||||
server_port: 8388
|
||||
local_port: 1087
|
||||
vault_password_key: "vault_ss_password_1"
|
||||
sslocal-rust-1086:
|
||||
server: "62.60.178.45"
|
||||
server_port: 8388
|
||||
local_port: 1086
|
||||
vault_password_key: "vault_ss_password_2"
|
||||
sslocal-rust-1081:
|
||||
server: "79.137.207.43"
|
||||
server_port: 8388
|
||||
local_port: 1081
|
||||
vault_password_key: "vault_ss_password_2"
|
||||
worker_proxies:
|
||||
- "socks5://sslocal-rust-1087:1087"
|
||||
@ -3,7 +3,8 @@
|
||||
# Edit cluster.yml and re-run the generator instead.
|
||||
|
||||
[airflow_master]
|
||||
af-test ansible_host=89.253.223.97 ansible_port=22
|
||||
af-green ansible_host=89.253.221.173 ansible_port=22
|
||||
|
||||
[airflow_workers]
|
||||
dl002 ansible_host=62.60.178.54
|
||||
dl003 ansible_host=62.60.245.103
|
||||
dl001 ansible_host=109.107.189.106
|
||||
|
||||
@ -47,6 +47,7 @@
|
||||
- "docker-compose-ytdlp-ops.yaml.j2"
|
||||
- "docker-compose.config-generate.yaml"
|
||||
- "envoy.yaml.j2"
|
||||
- "docker-compose.camoufox.yaml.j2"
|
||||
|
||||
- name: Create .env file for YT-DLP master service
|
||||
template:
|
||||
|
||||
@ -1,55 +1,59 @@
|
||||
# This file is managed by Ansible.
|
||||
# Set the timezone for all services to ensure consistency in logs.
|
||||
TZ=Europe/Moscow
|
||||
# This file is managed by Ansible. Do not edit manually.
|
||||
|
||||
# --- Common Settings ---
|
||||
HOSTNAME="{{ inventory_hostname }}"
|
||||
SERVICE_ROLE={{ service_role }}
|
||||
{% if server_identity is defined %}
|
||||
SERVER_IDENTITY={{ server_identity }}
|
||||
{% endif %}
|
||||
COMPOSE_PROJECT_NAME="ytdlp-ops-{{ service_role | default('all-in-one') }}"
|
||||
TZ="{{ host_timezone }}"
|
||||
service_role={{ service_role | default('all-in-one') }}
|
||||
|
||||
# Passwords
|
||||
# --- Docker Image Settings ---
|
||||
YTDLP_OPS_IMAGE="{{ ytdlp_ops_image }}"
|
||||
AIRFLOW_IMAGE_NAME="{{ airflow_image_name }}"
|
||||
|
||||
# --- Network Settings ---
|
||||
ENVOY_PORT={{ envoy_port }}
|
||||
ENVOY_ADMIN_PORT={{ envoy_admin_port }}
|
||||
YTDLP_BASE_PORT={{ ytdlp_base_port }}
|
||||
YTDLP_WORKERS={{ ytdlp_workers | default(3) }}
|
||||
MANAGEMENT_SERVICE_PORT={{ management_service_port }}
|
||||
REDIS_PORT={{ redis_port }}
|
||||
POSTGRES_PORT={{ postgres_port }}
|
||||
|
||||
# --- Security Settings ---
|
||||
REDIS_PASSWORD="{{ vault_redis_password }}"
|
||||
POSTGRES_PASSWORD="{{ vault_postgres_password }}"
|
||||
|
||||
# Common settings
|
||||
AIRFLOW_UID={{ airflow_uid | default(1003) }}
|
||||
AIRFLOW_GID={{ deploy_group_gid | default(1001) }}
|
||||
YTDLP_BASE_PORT={{ ytdlp_base_port }}
|
||||
REDIS_PORT={{ redis_port }}
|
||||
|
||||
# Master-specific settings
|
||||
{% if 'master' in service_role or 'management' in service_role %}
|
||||
AIRFLOW_ADMIN_PASSWORD="{{ vault_airflow_admin_password }}"
|
||||
FLOWER_PASSWORD="{{ vault_flower_password }}"
|
||||
AIRFLOW_VAR_MASTER_HOST_IP={{ hostvars[groups['airflow_master'][0]].ansible_host }}
|
||||
# MASTER_HOST_IP is not needed on the master node itself for ytdlp-ops,
|
||||
# as it connects to Redis via the internal Docker service name 'redis'.
|
||||
# It is defined for workers to connect back to the master.
|
||||
|
||||
# --- User and Group IDs ---
|
||||
AIRFLOW_UID={{ airflow_uid | default(1003) }}
|
||||
AIRFLOW_GID={{ deploy_group_gid | default(1001) }}
|
||||
|
||||
# --- Master-specific settings ---
|
||||
{% if 'master' in service_role or 'management' in service_role %}
|
||||
MASTER_HOST_IP={{ hostvars[groups['airflow_master'][0]].ansible_host }}
|
||||
# Camoufox is not used on master, but the config generator expects the variable.
|
||||
CAMOUFOX_PROXIES=
|
||||
|
||||
{% endif %}
|
||||
|
||||
# Worker-specific settings
|
||||
# --- Worker-specific settings ---
|
||||
{% if 'worker' in service_role %}
|
||||
AIRFLOW_PROJ_DIR={{ airflow_worker_dir }}
|
||||
MASTER_HOST_IP={{ hostvars[groups['airflow_master'][0]].ansible_host }}
|
||||
|
||||
# --- Envoy & Worker Configuration ---
|
||||
ENVOY_PORT={{ envoy_port }}
|
||||
ENVOY_ADMIN_PORT={{ envoy_admin_port }}
|
||||
MANAGEMENT_SERVICE_PORT={{ management_service_port }}
|
||||
YTDLP_WORKERS=4
|
||||
ENVOY_BACKEND_ADDRESS=ytdlp-ops-service
|
||||
YTDLP_TIMEOUT=600
|
||||
|
||||
# --- Camoufox (Browser) Configuration ---
|
||||
CAMOUFOX_PROXIES="{{ (worker_proxies | default([])) | join(',') }}"
|
||||
VNC_PASSWORD="{{ vault_vnc_password }}"
|
||||
CAMOUFOX_BASE_VNC_PORT={{ camoufox_base_vnc_port }}
|
||||
CAMOUFOX_PORT=12345
|
||||
CAMOUFOX_PORT={{ camoufox_port }}
|
||||
|
||||
# --- Account Manager Configuration ---
|
||||
ACCOUNT_ACTIVE_DURATION_MIN=7
|
||||
ACCOUNT_COOLDOWN_DURATION_MIN=30
|
||||
ACCOUNT_ACTIVE_DURATION_MIN={{ account_active_duration_min | default(7) }}
|
||||
ACCOUNT_COOLDOWN_DURATION_MIN={{ account_cooldown_duration_min | default(30) }}
|
||||
|
||||
{% endif %}
|
||||
|
||||
@ -88,7 +88,7 @@ shadowsocks_proxies:
|
||||
|
||||
master:
|
||||
af-green:
|
||||
ip: 89.253.223.97
|
||||
ip: 89.253.221.173
|
||||
port: 22
|
||||
proxies:
|
||||
- "socks5://sslocal-rust-1087:1087"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user