15 Commits
docs ... master

Author SHA1 Message Date
b5ed25d542 Доработка docker-окружения
- перенос конфигов для web в его папку
- префикс m3u-su- возвращён к на iptv-
- уточнения по сборке docs и мелочи по остальным
2026-01-03 01:14:19 +08:00
448eada6e9 Перевод checker и docs на контейнеры 2025-11-23 01:40:42 +08:00
bdbd9f9e57 Корректировка скрипта iptv с учётом замены репозиториев на контейнеры 2025-11-23 01:39:58 +08:00
66df86f1aa Выключен appendonly 2025-07-20 10:58:02 +08:00
24a5f988a3 Выключена репликация keydb 2025-07-19 15:58:50 +08:00
28f93bd9a6 Правки конфига keydb
- перечитка старых данных при перезапуске
- попытка вырубить репликацию
2025-07-10 11:15:41 +08:00
70847623e8 Из конфига keydb убран log, ибо не имеет смысла 2025-07-07 08:46:58 +08:00
68d051c36e Конфиг от keydb вместо redis 2025-07-07 08:27:11 +08:00
1456237de2 Merge branch 'master' of git.axenov.dev:IPTV/iptv-docker 2025-07-05 00:41:51 +08:00
fbc5ea4428 Мелочи по keydb 2025-07-05 00:41:33 +08:00
c49b6b979d IPTV_ENV=dev 2025-07-05 00:38:30 +08:00
10bf297543 Вернулась команда iptv exec, исправлена rebuild 2025-07-05 00:34:18 +08:00
4d2cfe8030 Фикс образа web.prod 2025-07-05 00:09:45 +08:00
ea700fc0fe Выключены параметры репликации 2025-06-30 23:33:47 +08:00
13de506761 Удалена директория docs 2025-06-21 22:30:39 +08:00
18 changed files with 687 additions and 580 deletions

View File

@@ -1,4 +1,4 @@
IPTV_ENV=prod IPTV_ENV=dev
KEYDB_UID=1000 KEYDB_UID=1000
KEYDB_GID=1000 KEYDB_GID=1000

3
.gitignore vendored
View File

@@ -1,7 +1,10 @@
/.idea/ /.idea/
/.vscode/ /.vscode/
/docker/keydb/data/*
/log/**/*
/iptvc/ /iptvc/
/web/ /web/
/docs/
/playlists/ /playlists/
/tools/ /tools/
/.profile/ /.profile/

View File

@@ -1,13 +1,13 @@
# Инфраструктурный слой проекта iptv.axenov.dev # Инфраструктурный слой проекта m3u.su
Docker-окружение для работы проекта iptv.axenov.dev. Docker-окружение для работы проекта m3u.su.
> **Веб-сайт:** [iptv.axenov.dev](https://iptv.axenov.dev) > **Веб-сайт:** [m3u.su](https://m3u.su)
> **Зеркало:** [m3u.su](https://m3u.su) > **Документация:** [m3u.su/docs](https://m3u.su/docs)
> Исходный код: [git.axenov.dev/IPTV](https://git.axenov.dev/IPTV) > Исходный код: [git.axenov.dev/IPTV](https://git.axenov.dev/IPTV)
> Telegram-канал: [@iptv_aggregator](https://t.me/iptv_aggregator) > Telegram-канал: [@iptv_aggregator](https://t.me/iptv_aggregator)
> Обсуждение: [@iptv_aggregator_chat](https://t.me/iptv_aggregator_chat) > Обсуждение: [@iptv_aggregator_chat](https://t.me/iptv_aggregator_chat)
> Дополнительные сведения: [git.axenov.dev/IPTV/.profile](https://git.axenov.dev/IPTV/.profile) > Бот: [@iptv_aggregator_bot](https://t.me/iptv_aggregator_bot)
## Использованный стек ## Использованный стек
@@ -38,15 +38,15 @@ wget -O - https://git.axenov.dev/IPTV/iptv-docker/raw/branch/master/iptv | bash
## Описание переменных окружения ## Описание переменных окружения
* `IPTV_ENV` -- окружение для развёртывания: это имена директорий и/или префиксы имён конфигов, которые будут проброшены в контейнеры; * `IPTV_ENV` окружение для развёртывания: это имена директорий и/или префиксы имён конфигов, которые будут проброшены в контейнеры;
* `KEYDB_UID`, `KEYDB_GID` -- ID пользователя/группы для разрешения владельца файлов и директорий keydb; * `KEYDB_UID`, `KEYDB_GID` ID пользователя/группы для разрешения владельца файлов и директорий keydb;
* `KEYDB_PORT` -- порт keydb, который будет проброшен на хост. * `KEYDB_PORT` порт keydb, который будет проброшен на хост.
* `KEYDB_USERNAME`, `KEYDB_PASSWORD` -- реквизиты доступа к keydb; * `KEYDB_USERNAME`, `KEYDB_PASSWORD` реквизиты доступа к keydb;
* `CHECKER_DB` -- БД keydb для хранения кеша проверенных плейлистов; * `CHECKER_DB` БД keydb для хранения кеша проверенных плейлистов;
* `CHECKER_TTL` -- время жизни кеша проверенных плейлистов; * `CHECKER_TTL` время жизни кеша проверенных плейлистов;
* `CHECKER_WAIT` -- кол-во секунд между запусками iptvc; * `CHECKER_WAIT` кол-во секунд между запусками iptvc;
* `CHECKER_INIFILE` -- путь к файлу списка плейлистов внутри контейнера; * `CHECKER_INIFILE` путь к файлу списка плейлистов внутри контейнера;
* `CHECKER_TAGFILE` -- путь к файлу списка тегов внутри контейнера. * `CHECKER_TAGFILE` путь к файлу списка тегов внутри контейнера.
## Reverse-proxy ## Reverse-proxy

View File

@@ -1,5 +1,7 @@
name: iptv
networks: networks:
iptv: iptv-network:
driver: bridge driver: bridge
x-common-attributes: &common-attributes x-common-attributes: &common-attributes
@@ -12,19 +14,34 @@ x-common-attributes: &common-attributes
- /etc/localtime:/etc/localtime:ro - /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro - /etc/timezone:/etc/timezone:ro
networks: networks:
- iptv - iptv-network
services: services:
nginx:
<<: *common-attributes
container_name: iptv-nginx
image: nginx:latest
pull_policy: always
volumes:
- ./docker/nginx/vhost.conf:/etc/nginx/conf.d/default.conf:ro
- ./log/nginx:/var/log/nginx:rw
- ./web:/var/www:ro
ports:
- 3000:80
depends_on:
- web
keydb: keydb:
<<: *common-attributes <<: *common-attributes
container_name: iptv-keydb container_name: iptv-keydb
image: eqalpha/keydb:latest image: eqalpha/keydb:latest
pull_policy: always
user: ${KEYDB_UID}:${KEYDB_GID} user: ${KEYDB_UID}:${KEYDB_GID}
entrypoint: ["sh", "/entrypoint.sh"]
volumes: volumes:
- ./docker/keydb/entrypoint.sh:/entrypoint.sh
- ./docker/keydb/keydb.conf:/etc/keydb/keydb.conf - ./docker/keydb/keydb.conf:/etc/keydb/keydb.conf
- ./docker/keydb/data/:/data:rw - ./docker/keydb/data/:/data:rw
- ./log/keydb:/var/log/keydb/:rw
ports: ports:
- ${KEYDB_PORT:-6379}:6379 - ${KEYDB_PORT:-6379}:6379
@@ -32,12 +49,14 @@ services:
<<: *common-attributes <<: *common-attributes
container_name: iptv-web container_name: iptv-web
build: build:
dockerfile: dockerfile.web.${IPTV_ENV} context: ./web
dockerfile: Dockerfile
target: iptv-web-${IPTV_ENV}
environment: environment:
- PHP_IDE_CONFIG=serverName=iptv.local - PHP_IDE_CONFIG=serverName=iptv.local
volumes: volumes:
- ./docker/php/${IPTV_ENV}/www.conf:/usr/local/etc/php-fpm.d/www.conf:ro - ./web/docker/${IPTV_ENV}/www.conf:/usr/local/etc/php-fpm.d/www.conf:ro
- ./docker/php/${IPTV_ENV}/php.ini:/usr/local/etc/php/conf.d/php.ini:ro - ./web/docker/${IPTV_ENV}/php.ini:/usr/local/etc/php/conf.d/php.ini:ro
- ./playlists/playlists.ini:/var/www/config/playlists.ini - ./playlists/playlists.ini:/var/www/config/playlists.ini
- ./log/php:/var/log/php:rw - ./log/php:/var/log/php:rw
- ./web:/var/www:rw - ./web:/var/www:rw
@@ -47,40 +66,29 @@ services:
checker: checker:
<<: *common-attributes <<: *common-attributes
container_name: iptv-checker container_name: iptv-checker
image: git.axenov.dev/iptv/iptvc:latest
build: build:
dockerfile: ./dockerfile.checker context: ./iptvc
dockerfile: Dockerfile
command: ["check", "--repeat", "0", "--every", "${CHECKER_WAIT:-60}"]
environment: environment:
- CACHE_ENABLED=true - CACHE_ENABLED=true
# - CACHE_HOST=localhost
- CACHE_HOST=iptv-keydb - CACHE_HOST=iptv-keydb
- CACHE_PORT=${KEYDB_PORT:-6379} - CACHE_PORT=${KEYDB_PORT:-6379}
- CACHE_USERNAME=${KEYDB_USERNAME} - CACHE_USERNAME=${KEYDB_USERNAME}
- CACHE_PASSWORD=${KEYDB_PASSWORD} - CACHE_PASSWORD=${KEYDB_PASSWORD}
- CACHE_DB=${CHECKER_DB:-0} - CACHE_DB=${CHECKER_DB:-0}
- CACHE_TTL=${CHECKER_TTL:-1800} - CACHE_TTL=${CHECKER_TTL:-1800}
- CHECKER_WAIT=${CHECKER_WAIT:-60}
- CHECKER_INIFILE=${CHECKER_INIFILE:-/app/playlists.ini}
- CHECKER_TAGFILE=${CHECKER_TAGFILE:-/app/channels.json}
volumes: volumes:
- ./docker/checker/entrypoint.sh:/entrypoint.sh - ./playlists/playlists.ini:/app/playlists.ini
- ./iptvc/:/app/ - ./playlists/channels.json:/app/channels.json
- ./playlists/playlists.ini:${CHECKER_INIFILE:-/app/playlists.ini}
- ./playlists/channels.json:${CHECKER_TAGFILE:-/app/channels.json}
depends_on:
- keydb
nginx: docs:
<<: *common-attributes <<: *common-attributes
container_name: iptv-nginx container_name: iptv-docs
image: nginx:latest image: git.axenov.dev/iptv/iptv-docs:latest
volumes: build:
- ./docker/nginx/vhost.conf:/etc/nginx/conf.d/default.conf:ro context: ./docs
- ./log/nginx:/var/log/nginx:rw dockerfile: Dockerfile
- ./web:/var/www:ro
- ./docs/site:/usr/share/nginx/html/doc-files:ro
ports: ports:
- 8080:80 - 3001:80
links:
- web
depends_on:
- web

View File

@@ -1,30 +0,0 @@
#!/bin/bash
echo "CHECKER_WAIT=$CHECKER_WAIT"
echo "CHECKER_INIFILE=$CHECKER_INIFILE"
echo "CHECKER_TAGFILE=$CHECKER_TAGFILE"
binary="$PWD/bin/iptvc"
if [ ! -f "$binary" ]; then
echo "Downloading latest iptvc..."
wget https://git.axenov.dev/IPTV/iptvc/releases/download/latest/linux_amd64.zip
[ ! -d "$PWD/bin" ] && mkdir "$PWD/bin"
unzip -o linux_amd64.zip -d "$PWD/bin"
rm -rf linux_amd64.zip
fi
if [ ! -f "$binary" ]; then
echo "Not found: $binary"
exit 1
fi
$binary version
args="check -i $CHECKER_INIFILE -t $CHECKER_TAGFILE"
while true; do
echo
echo "Running: $binary $args"
$binary $args
echo "Waiting $CHECKER_WAIT seconds"
sleep $CHECKER_WAIT
done

View File

@@ -0,0 +1,4 @@
#!/bin/sh
trap 'echo "Received SIGTERM, saving KeyDB data..."; keydb-cli SAVE; echo "Data saved. Exiting."; exit 0' TERM
echo "[entrypoint] Starting KeyDB..."
exec keydb-server /etc/keydb/keydb.conf "$@"

File diff suppressed because it is too large Load Diff

View File

@@ -22,14 +22,14 @@ server {
} }
location ^~ /docs/ { location ^~ /docs/ {
alias /usr/share/nginx/html/doc-files/; proxy_pass http://docs:80/;
index index.html; proxy_set_header Host $host;
# access_log /var/log/nginx/docs_access.log; proxy_set_header X-Real-IP $remote_addr;
error_log /var/log/nginx/docs_error.log warn; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg)$ { proxy_set_header X-Forwarded-Proto $scheme;
expires 1y; proxy_read_timeout 300;
add_header Cache-Control "public"; proxy_connect_timeout 300;
} proxy_send_timeout 300;
} }
location / { location / {
@@ -48,6 +48,8 @@ server {
fastcgi_hide_header X-Powered-By; fastcgi_hide_header X-Powered-By;
fastcgi_read_timeout 300; fastcgi_read_timeout 300;
proxy_read_timeout 300; proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
include fastcgi_params; include fastcgi_params;
location ~* \.(jpg|jpeg|gif|css|png|ttf|woff|svg|js|ico)$ { location ~* \.(jpg|jpeg|gif|css|png|ttf|woff|svg|js|ico)$ {
access_log off; access_log off;

View File

@@ -1,26 +0,0 @@
[PHP]
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED
expose_php = Off
file_uploads = Off
max_execution_time=-1
memory_limit = 512M
[opcache]
opcache.enable = 1
opcache.enable_cli = 1
opcache.memory_consumption = 128
opcache.max_accelerated_files = 30000
opcache.revalidate_freq = 0
opcache.jit_buffer_size = 64M
opcache.jit = tracing
[xdebug]
; https://xdebug.org/docs/all_settings
zend_extension = xdebug.so
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.trigger_value = go
xdebug.client_host = host.docker.internal
xdebug.REQUEST = *
xdebug.SESSION = *
xdebug.SERVER = *

View File

@@ -1,22 +0,0 @@
[www]
user = www-data
group = www-data
listen = 127.0.0.1:9000
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 50
pm.status_path = /status
ping.path = /ping
ping.response = pong
access.log = /var/log/php/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{milli}d %{kilo}M %C%%"
; chroot = /var/www
; chdir = /var/www
php_flag[display_errors] = on
php_admin_value[error_log] = /var/log/php/$pool.error.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 512M
php_admin_value[error_reporting] = E_ALL & ~E_NOTICE & ~E_DEPRECATED

View File

@@ -1,16 +0,0 @@
[PHP]
error_reporting = E_ALL
expose_php = Off
file_uploads = Off
memory_limit = 512M
; upload_max_filesize=10M
; post_max_size=10M
[opcache]
opcache.enable = 1
opcache.enable_cli = 1
opcache.memory_consumption = 128
opcache.max_accelerated_files = 30000
opcache.revalidate_freq = 0
opcache.jit_buffer_size = 64M
opcache.jit = tracing

View File

@@ -1,22 +0,0 @@
[www]
user = www-data
group = www-data
listen = 127.0.0.1:9000
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 50
pm.status_path = /status
ping.path = /ping
ping.response = pong
access.log = /var/log/php/$pool.access.log
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{milli}d %{kilo}M %C%%"
; chroot = /var/www
; chdir = /var/www
php_flag[display_errors] = on
php_admin_value[error_log] = /var/log/php/$pool.error.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 512M
php_admin_value[error_reporting] = E_ALL & ~E_NOTICE & ~E_DEPRECATED

View File

@@ -1,15 +0,0 @@
FROM alpine:3.21 AS iptvc-compiler
RUN apk --no-cache add \
bash \
tzdata \
go \
make \
libc6-compat
RUN mkdir /app && \
chmod 777 /app
WORKDIR /app
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -1,37 +0,0 @@
FROM php:8.4-fpm AS iptv-php-dev
RUN apt update && \
apt upgrade -y && \
apt install -y \
git \
unzip \
7zip \
cron \
zlib1g-dev \
imagemagick \
libpng-dev \
libjpeg-dev
# https://pecl.php.net/package/xdebug
# https://pecl.php.net/package/redis
RUN pecl channel-update pecl.php.net && \
pecl install \
xdebug-3.4.1 \
redis-6.1.0
RUN docker-php-ext-enable redis && \
docker-php-ext-configure gd --with-jpeg && \
docker-php-ext-install gd
RUN mkdir -p /var/run/php && \
mkdir -p /var/log/php && \
chmod -R 777 /var/log/php
COPY --from=composer /usr/bin/composer /usr/local/bin/composer
RUN git config --global --add safe.directory /var/www
EXPOSE 9000
WORKDIR /var/www
CMD composer install && \
php-fpm --nodaemonize

View File

@@ -1,34 +0,0 @@
FROM php:8.4-fpm AS iptv-php-prod
RUN apt update && \
apt upgrade -y && \
apt install -y \
git \
unzip \
7zip \
cron \
zlib1g-dev \
imagemagick \
libpng-dev \
libjpeg-dev
# https://pecl.php.net/package/redis
RUN pecl channel-update pecl.php.net && \
pecl install redis-6.1.0
RUN docker-php-ext-enable xdebug redis && \
docker-php-ext-configure gd --with-jpeg && \
docker-php-ext-install gd
RUN mkdir -p /var/run/php && \
mkdir -p /var/log/php && \
chmod -R 777 /var/log/php
COPY --from=composer /usr/bin/composer /usr/local/bin/composer
RUN git config --global --add safe.directory /var/www
EXPOSE 9000
WORKDIR /var/www/
CMD composer install && \
php-fpm --nodaemonize

1
docs

Submodule docs deleted from 3a2eca9e15

42
iptv
View File

@@ -21,7 +21,7 @@ else
ROOT_PATH="$(pwd)" ROOT_PATH="$(pwd)"
fi fi
IPTV_PROJECTS=("iptvc" "docs" "web" "playlists") IPTV_PROJECTS=("web" "playlists")
IPTV_GITEA_URL_SSH="git@git.axenov.dev:IPTV" IPTV_GITEA_URL_SSH="git@git.axenov.dev:IPTV"
IPTV_GITEA_URL_HTTPS="https://git.axenov.dev/IPTV" IPTV_GITEA_URL_HTTPS="https://git.axenov.dev/IPTV"
IPTV_DOCKER_URL_SSH="$IPTV_GITEA_URL_SSH/iptv-docker.git" IPTV_DOCKER_URL_SSH="$IPTV_GITEA_URL_SSH/iptv-docker.git"
@@ -338,6 +338,7 @@ docker.build_base_images() {
# done # done
subtitle "Построение образов" subtitle "Построение образов"
docker.compose build docker.compose build
[ ! -d web/cache/views ] && mkdir -p web/cache/views
success "Базовые образы построены" success "Базовые образы построены"
} }
@@ -432,7 +433,7 @@ find_services_compose() {
[ "$*" ] && for svc in "$@"; do [ "$*" ] && for svc in "$@"; do
grep_match "$svc" "^--?.*" && continue grep_match "$svc" "^--?.*" && continue
svc="$(find_service_compose "$svc")" svc="$(find_service_compose "${svc/iptv-/}")"
services="$services $svc" services="$services $svc"
done done
@@ -468,7 +469,7 @@ init() {
local project_repo_path="$docker_repo_path/$repo_name" local project_repo_path="$docker_repo_path/$repo_name"
subtitle "[$counter/$repo_count] Подготовка репозитория ${FBOLD}$repo_name${FRESET}..." subtitle "[$counter/$repo_count] Подготовка репозитория ${FBOLD}$repo_name${FRESET}..."
local project_repo_url=$(project_url_ssh "$repo_name") local project_repo_url=$(project_url_https "$repo_name")
debug "Известная ссылка на репозиторий: $project_repo_url" debug "Известная ссылка на репозиторий: $project_repo_url"
project_clone "$project_repo_url" "$project_repo_path" project_clone "$project_repo_url" "$project_repo_path"
@@ -494,12 +495,11 @@ up() {
process_help_arg process_help_arg
subtitle "Создание и запуск контейнеров" subtitle "Создание и запуск контейнеров"
argl profiles 0 profiles
local services='' local services=''
[ "$*" ] && services="$(find_services_compose "$@")" [ "$*" ] && services="$(find_services_compose "$@")"
COMPOSE_PROFILES="$profiles" docker.compose up "$services" --build --detach --remove-orphans && \ [ ! -d web/cache/views ] && mkdir -p web/cache/views
docker.compose up "$services" --build --detach --remove-orphans && \
success 'Среда запущена успешно' success 'Среда запущена успешно'
} }
@@ -522,13 +522,10 @@ down() {
process_help_arg process_help_arg
subtitle "Остановка и удаление контейнеров" subtitle "Остановка и удаление контейнеров"
argl profiles 0 profiles
[[ -z "$profiles" ]] && profiles="full"
local services='' local services=''
[ "$*" ] && services="$(find_services_compose "$@")" [ "$*" ] && services="$(find_services_compose "$@")"
COMPOSE_PROFILES="$profiles" docker.compose down "$services" --remove-orphans && \ docker.compose down "$services" --remove-orphans && \
success 'Среда остановлена успешно' success 'Среда остановлена успешно'
} }
@@ -554,7 +551,7 @@ rebuild() {
is_full=$(arg full 1) is_full=$(arg full 1)
[ "$is_full" = 0 ] && is_full=$(argl full 1) [ "$is_full" = 0 ] && is_full=$(argl full 1)
[ -n "$*" ] && down "$@" [ -n "$*" ] && down "$@" || down
[ "$is_full" = 1 ] && docker.build_base_images [ "$is_full" = 1 ] && docker.build_base_images
up "$@" up "$@"
@@ -579,6 +576,27 @@ purge() {
success 'Образы удалены успешно' success 'Образы удалены успешно'
} }
# Выполняет команду в контейнере
exec() {
process_help_arg
as_root=0
svc="$1"
regex_match "$svc" "--?r(oot)?" && { as_root=1; shift; svc="$1"; }
svc_correct="iptv-$(find_service_compose "$svc")"
command=("${@:2}")
regex_match "${command[0]}" "--?r(oot)?" && { as_root=1; unset "command[0]"; }
[[ -z "${command[*]}" ]] && die "не указана команда для выполнения в контейнере"
#TODO многострочные команды прокидываются корректно, но выполняется только первая строка?
if [[ "$as_root" == 1 ]]; then
docker.exec "$svc_correct" "${command[*]}"
else
docker.exec_www "$svc_correct" "${command[*]}"
fi
}
# Выводит логи сервиса # Выводит логи сервиса
logs() { logs() {
process_help_arg process_help_arg
@@ -602,7 +620,6 @@ stats() {
docker.compose stats "$@" docker.compose stats "$@"
} }
######################################################## ########################################################
# Команды справки # Команды справки
######################################################## ########################################################
@@ -827,6 +844,7 @@ case "$COMMAND" in
stop ) stop "$@" ;; stop ) stop "$@" ;;
r|rebuild ) rebuild "$@" ;; r|rebuild ) rebuild "$@" ;;
restart ) restart "$@" ;; restart ) restart "$@" ;;
exec ) exec "$@" ;;
purge ) purge ;; purge ) purge ;;
logs ) logs "$@" ;; logs ) logs "$@" ;;
stats ) stats "$@" ;; stats ) stats "$@" ;;

View File