Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
b5ed25d542
|
|||
|
448eada6e9
|
|||
|
bdbd9f9e57
|
|||
|
66df86f1aa
|
|||
|
24a5f988a3
|
|||
|
28f93bd9a6
|
|||
|
70847623e8
|
|||
|
68d051c36e
|
|||
|
1456237de2
|
|||
|
fbc5ea4428
|
|||
|
c49b6b979d
|
|||
|
10bf297543
|
|||
|
4d2cfe8030
|
|||
|
ea700fc0fe
|
|||
|
13de506761
|
|||
|
7e5a0bcebd
|
|||
|
2f3bea76f4
|
|||
|
f1bd94b35b
|
|||
|
55bc7ce0f8
|
|||
|
907aea1f9e
|
|||
|
833c5218eb
|
14
.env.example
14
.env.example
@@ -1,5 +1,13 @@
|
||||
IPTV_ENV=dev
|
||||
|
||||
REDIS_UID=1000
|
||||
REDIS_GID=1000
|
||||
REDIS_PORT=6379
|
||||
KEYDB_UID=1000
|
||||
KEYDB_GID=1000
|
||||
KEYDB_PORT=6379
|
||||
KEYDB_USERNAME=
|
||||
KEYDB_PASSWORD=
|
||||
|
||||
CHECKER_DB=0
|
||||
CHECKER_TTL=1800
|
||||
CHECKER_WAIT=60
|
||||
CHECKER_INIFILE=/app/playlists.ini
|
||||
CHECKER_TAGFILE=/app/channels.json
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,18 +1,19 @@
|
||||
/.idea/
|
||||
/.vscode/
|
||||
/docker/keydb/data/*
|
||||
/log/**/*
|
||||
/iptvc/
|
||||
/web/
|
||||
/docs/
|
||||
/playlists/
|
||||
/tools/
|
||||
/.profile/
|
||||
/tmp/
|
||||
|
||||
*.log
|
||||
.env
|
||||
*.log
|
||||
*.m3u
|
||||
*.m3u.*
|
||||
*.m3u8
|
||||
*.m3u8.*
|
||||
*.rdb
|
||||
|
||||
!/**/.gitkeep
|
||||
|
||||
55
README.md
55
README.md
@@ -1,41 +1,58 @@
|
||||
# Инфраструктурный слой проекта iptv.axenov.dev
|
||||
# Инфраструктурный слой проекта m3u.su
|
||||
|
||||
> **Адрес**: https://iptv.axenov.dev
|
||||
> **FAQ**: https://iptv.axenov.dev/faq
|
||||
> **Исходный код**: https://git.axenov.dev/IPTV
|
||||
Docker-окружение для работы проекта m3u.su.
|
||||
|
||||
Содержит docker-окружение для запуска проекта iptv.axenov.dev.
|
||||
> **Веб-сайт:** [m3u.su](https://m3u.su)
|
||||
> **Документация:** [m3u.su/docs](https://m3u.su/docs)
|
||||
> Исходный код: [git.axenov.dev/IPTV](https://git.axenov.dev/IPTV)
|
||||
> Telegram-канал: [@iptv_aggregator](https://t.me/iptv_aggregator)
|
||||
> Обсуждение: [@iptv_aggregator_chat](https://t.me/iptv_aggregator_chat)
|
||||
> Бот: [@iptv_aggregator_bot](https://t.me/iptv_aggregator_bot)
|
||||
|
||||
## Использованный стек
|
||||
|
||||
* [docker compose](https://docs.docker.com/compose/)
|
||||
* [php8.3-fpm](https://www.php.net/releases/8.3/ru.php)
|
||||
* [php8.4-fpm](https://www.php.net/releases/8.4/ru.php)
|
||||
* [nginx](https://nginx.org/ru/)
|
||||
* [keydb](https://docs.keydb.dev/docs/)
|
||||
* [iptvc](https://git.axenov.dev/IPTV/iptvc)
|
||||
* bash
|
||||
|
||||
## Установка и настройка
|
||||
|
||||
```
|
||||
git clone https://git.axenov.dev/IPTV/docker.git iptv
|
||||
cp .env.example .env
|
||||
git clone https://git.axenov.dev/IPTV/web.git
|
||||
cp web/.env.example web/.env
|
||||
docker exec -it iptv-main composer i
|
||||
docker compose up -d --build
|
||||
wget -O - https://git.axenov.dev/IPTV/iptv-docker/raw/branch/master/iptv | bash -s - init
|
||||
```
|
||||
|
||||
### Описание переменных окружения
|
||||
## Cкрипт [`iptv`](./iptv)
|
||||
|
||||
* `IPTV_ENV` -- окружение для развёртывания: это имена директорий и/или префиксы имён конфигов, которые будут проброшены в контейнеры;
|
||||
* `REDIS_UID`, `REDIS_GID` -- ID пользователя/группы для разрешения владельца файлов и директорий keydb;
|
||||
* `REDIS_PORT` -- порт keydb, который будет проброшен на хост.
|
||||
Это инструмент, который позволяет быстро управлять локальной средой `lis-docker`:
|
||||
* инициализировать с нуля, как в примере выше;
|
||||
* управлять образами и контейнерами среды.
|
||||
|
||||
### Reverse-proxy
|
||||
> Управление средой не всегда удобно через команды git и docker, поэтому рекомендуется использовать `./iptv`.
|
||||
|
||||
Набери `./iptv help` для справки по использованию.
|
||||
|
||||
При доработке используй [линтер](https://www.shellcheck.net): `shellcheck -s bash iptv`
|
||||
|
||||
## Описание переменных окружения
|
||||
|
||||
* `IPTV_ENV` — окружение для развёртывания: это имена директорий и/или префиксы имён конфигов, которые будут проброшены в контейнеры;
|
||||
* `KEYDB_UID`, `KEYDB_GID` — ID пользователя/группы для разрешения владельца файлов и директорий keydb;
|
||||
* `KEYDB_PORT` — порт keydb, который будет проброшен на хост.
|
||||
* `KEYDB_USERNAME`, `KEYDB_PASSWORD` — реквизиты доступа к keydb;
|
||||
* `CHECKER_DB` — БД keydb для хранения кеша проверенных плейлистов;
|
||||
* `CHECKER_TTL` — время жизни кеша проверенных плейлистов;
|
||||
* `CHECKER_WAIT` — кол-во секунд между запусками iptvc;
|
||||
* `CHECKER_INIFILE` — путь к файлу списка плейлистов внутри контейнера;
|
||||
* `CHECKER_TAGFILE` — путь к файлу списка тегов внутри контейнера.
|
||||
|
||||
## Reverse-proxy
|
||||
|
||||
На сервере опционально можно настроить реверс-прокси до контейнера веб-сервиса, например, чтобы настроить доступ по доменному имени, изменить порт, подключить SSL-сертификаты или др.
|
||||
|
||||
#### Apache
|
||||
### Apache
|
||||
|
||||
Если на сервере, на котором запускаются контейнеры, стоит apache2, то, чтобы использовать его как реверс-прокси, нужно:
|
||||
|
||||
@@ -84,7 +101,7 @@ $ # для подгрузки включенных модулей выполни
|
||||
$ sudo systemctl restart apache2
|
||||
```
|
||||
|
||||
#### Nginx
|
||||
### Nginx
|
||||
|
||||
```
|
||||
$ sudo nano /etc/nginx/sites-available/iptv.conf
|
||||
|
||||
124
compose.yml
124
compose.yml
@@ -1,5 +1,7 @@
|
||||
name: iptv
|
||||
|
||||
networks:
|
||||
iptv:
|
||||
iptv-network:
|
||||
driver: bridge
|
||||
|
||||
x-common-attributes: &common-attributes
|
||||
@@ -12,67 +14,81 @@ x-common-attributes: &common-attributes
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
networks:
|
||||
- iptv
|
||||
- iptv-network
|
||||
|
||||
services:
|
||||
|
||||
keydb:
|
||||
<<: *common-attributes
|
||||
container_name: iptv-keydb
|
||||
build:
|
||||
dockerfile: docker/keydb/dockerfile
|
||||
user: "${REDIS_UID}:${REDIS_GID}"
|
||||
volumes:
|
||||
- ./docker/keydb/keydb.conf:/etc/keydb/keydb.conf
|
||||
- ./docker/keydb/data/:/data:rw
|
||||
- ./log/keydb:/var/log/keydb/:rw
|
||||
ports:
|
||||
- "${REDIS_PORT:-6379}:6379"
|
||||
|
||||
php-main:
|
||||
<<: *common-attributes
|
||||
container_name: iptv-main
|
||||
environment:
|
||||
- PHP_IDE_CONFIG=serverName=iptv.local
|
||||
build:
|
||||
dockerfile: docker/php/${IPTV_ENV}/dockerfile.main
|
||||
volumes:
|
||||
- ./docker/php/${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
|
||||
- ./log/php:/var/log/php:rw
|
||||
- ./web:/var/www:rw
|
||||
depends_on:
|
||||
- keydb
|
||||
|
||||
php-cron:
|
||||
<<: *common-attributes
|
||||
container_name: iptv-cron
|
||||
environment:
|
||||
- PHP_IDE_CONFIG=serverName=iptv.local
|
||||
build:
|
||||
dockerfile: docker/php/${IPTV_ENV}/dockerfile.cron
|
||||
volumes:
|
||||
- ./docker/php/${IPTV_ENV}/cron_entrypoint.sh:/entrypoint.sh
|
||||
- ./docker/php/${IPTV_ENV}/cron_jobs:/etc/cron.d/iptv_jobs
|
||||
- ./docker/php/${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
|
||||
- ./log/php:/var/log/php:rw
|
||||
- ./web:/var/www:rw
|
||||
depends_on:
|
||||
- keydb
|
||||
|
||||
nginx:
|
||||
<<: *common-attributes
|
||||
container_name: iptv-nginx
|
||||
build:
|
||||
dockerfile: docker/nginx/dockerfile
|
||||
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:
|
||||
- "8080:80"
|
||||
links:
|
||||
- php-main
|
||||
- 3000:80
|
||||
depends_on:
|
||||
- php-main
|
||||
- web
|
||||
|
||||
keydb:
|
||||
<<: *common-attributes
|
||||
container_name: iptv-keydb
|
||||
image: eqalpha/keydb:latest
|
||||
pull_policy: always
|
||||
user: ${KEYDB_UID}:${KEYDB_GID}
|
||||
entrypoint: ["sh", "/entrypoint.sh"]
|
||||
volumes:
|
||||
- ./docker/keydb/entrypoint.sh:/entrypoint.sh
|
||||
- ./docker/keydb/keydb.conf:/etc/keydb/keydb.conf
|
||||
- ./docker/keydb/data/:/data:rw
|
||||
ports:
|
||||
- ${KEYDB_PORT:-6379}:6379
|
||||
|
||||
web:
|
||||
<<: *common-attributes
|
||||
container_name: iptv-web
|
||||
build:
|
||||
context: ./web
|
||||
dockerfile: Dockerfile
|
||||
target: iptv-web-${IPTV_ENV}
|
||||
environment:
|
||||
- PHP_IDE_CONFIG=serverName=iptv.local
|
||||
volumes:
|
||||
- ./web/docker/${IPTV_ENV}/www.conf:/usr/local/etc/php-fpm.d/www.conf:ro
|
||||
- ./web/docker/${IPTV_ENV}/php.ini:/usr/local/etc/php/conf.d/php.ini:ro
|
||||
- ./playlists/playlists.ini:/var/www/config/playlists.ini
|
||||
- ./log/php:/var/log/php:rw
|
||||
- ./web:/var/www:rw
|
||||
depends_on:
|
||||
- keydb
|
||||
|
||||
checker:
|
||||
<<: *common-attributes
|
||||
container_name: iptv-checker
|
||||
image: git.axenov.dev/iptv/iptvc:latest
|
||||
build:
|
||||
context: ./iptvc
|
||||
dockerfile: Dockerfile
|
||||
command: ["check", "--repeat", "0", "--every", "${CHECKER_WAIT:-60}"]
|
||||
environment:
|
||||
- CACHE_ENABLED=true
|
||||
- CACHE_HOST=iptv-keydb
|
||||
- CACHE_PORT=${KEYDB_PORT:-6379}
|
||||
- CACHE_USERNAME=${KEYDB_USERNAME}
|
||||
- CACHE_PASSWORD=${KEYDB_PASSWORD}
|
||||
- CACHE_DB=${CHECKER_DB:-0}
|
||||
- CACHE_TTL=${CHECKER_TTL:-1800}
|
||||
volumes:
|
||||
- ./playlists/playlists.ini:/app/playlists.ini
|
||||
- ./playlists/channels.json:/app/channels.json
|
||||
|
||||
docs:
|
||||
<<: *common-attributes
|
||||
container_name: iptv-docs
|
||||
image: git.axenov.dev/iptv/iptv-docs:latest
|
||||
build:
|
||||
context: ./docs
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- 3001:80
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
FROM eqalpha/keydb:latest AS iptv-keydb
|
||||
4
docker/keydb/entrypoint.sh
Normal file
4
docker/keydb/entrypoint.sh
Normal 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
@@ -1 +0,0 @@
|
||||
FROM nginx:latest AS iptv-nginx
|
||||
@@ -1,8 +1,14 @@
|
||||
server {
|
||||
server_name iptv.local;
|
||||
listen 80;
|
||||
root /var/www/public;
|
||||
index index.php;
|
||||
index index.html index.php;
|
||||
# access_log /var/log/nginx/access.log;
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
add_header Access-Control-Allow-Origin '*';
|
||||
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
|
||||
add_header Access-Control-Allow-Headers "*";
|
||||
add_header Access-Control-Allow-Credentials "true";
|
||||
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
@@ -10,17 +16,31 @@ server {
|
||||
gzip_buffers 16 8k;
|
||||
gzip_http_version 1.1;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
|
||||
access_log off;
|
||||
expires max;
|
||||
log_not_found off;
|
||||
|
||||
location = /docs {
|
||||
return 301 /docs/;
|
||||
}
|
||||
|
||||
location ^~ /docs/ {
|
||||
proxy_pass http://docs:80/;
|
||||
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 300;
|
||||
proxy_connect_timeout 300;
|
||||
proxy_send_timeout 300;
|
||||
}
|
||||
|
||||
location / {
|
||||
root /var/www/public;
|
||||
try_files $uri $uri/ /index.php$is_args$args;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
root /var/www/public;
|
||||
try_files $uri /index.php =404;
|
||||
fastcgi_pass php-main:9000;
|
||||
fastcgi_pass web:9000;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
@@ -28,6 +48,20 @@ server {
|
||||
fastcgi_hide_header X-Powered-By;
|
||||
fastcgi_read_timeout 300;
|
||||
proxy_read_timeout 300;
|
||||
proxy_connect_timeout 300;
|
||||
proxy_send_timeout 300;
|
||||
include fastcgi_params;
|
||||
location ~* \.(jpg|jpeg|gif|css|png|ttf|woff|svg|js|ico)$ {
|
||||
access_log off;
|
||||
expires max;
|
||||
log_not_found off;
|
||||
}
|
||||
}
|
||||
|
||||
location ~* \.(jpg|jpeg|gif|css|png|ttf|woff|svg|js|ico)$ {
|
||||
root /var/www/public;
|
||||
access_log off;
|
||||
expires max;
|
||||
log_not_found off;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
echo "Current pwd: $(pwd)"
|
||||
for file in "/etc/cron.d/iptv_jobs" "/var/www/iptv-cli"; do
|
||||
if [ ! -f "$file" ]; then echo "Not found: $file" && exit 1; fi
|
||||
done;
|
||||
|
||||
echo "Importing crontab /etc/cron.d/iptv_jobs:"
|
||||
echo "======================="
|
||||
cat /etc/cron.d/iptv_jobs
|
||||
echo "======================="
|
||||
|
||||
crontab -n /etc/cron.d/iptv_jobs || exit 2
|
||||
|
||||
echo "Running cron with /etc/cron.d/iptv_jobs"
|
||||
crontab /etc/cron.d/iptv_jobs
|
||||
touch /var/log/cron.log
|
||||
cron -L 15 && tail -fn 1 /var/log/cron.log
|
||||
@@ -1,5 +0,0 @@
|
||||
SHELL=/bin/sh
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||
PHP_IDE_CONFIG=serverName=iptv.local
|
||||
|
||||
* * * * * /var/www/iptv-cli check:ini --count 5 --order random
|
||||
@@ -1,44 +0,0 @@
|
||||
FROM php:8.4-fpm AS iptv-img-base
|
||||
|
||||
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 && \
|
||||
docker-php-ext-configure pcntl --enable-pcntl && \
|
||||
docker-php-ext-install pcntl
|
||||
|
||||
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"]
|
||||
|
||||
################################################################
|
||||
|
||||
FROM iptv-img-base AS iptv-img-cron
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
@@ -1,44 +0,0 @@
|
||||
FROM php:8.4-fpm AS iptv-img-base
|
||||
|
||||
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 xdebug redis && \
|
||||
docker-php-ext-configure gd --with-jpeg && \
|
||||
docker-php-ext-install gd && \
|
||||
docker-php-ext-configure pcntl --enable-pcntl && \
|
||||
docker-php-ext-install pcntl
|
||||
|
||||
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"]
|
||||
|
||||
################################################################
|
||||
|
||||
FROM iptv-img-base AS iptv-img-main
|
||||
|
||||
ENTRYPOINT ["php-fpm", "--nodaemonize"]
|
||||
@@ -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 = *
|
||||
@@ -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/www/$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/www/$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
|
||||
@@ -1,21 +0,0 @@
|
||||
FROM php:8.3-fpm
|
||||
|
||||
RUN apt update && \
|
||||
apt upgrade -y && \
|
||||
apt install -y git
|
||||
|
||||
# https://pecl.php.net/package/redis
|
||||
RUN pecl channel-update pecl.php.net && \
|
||||
pecl install redis && \
|
||||
docker-php-ext-enable redis && \
|
||||
mkdir -p /var/log/php && \
|
||||
chmod -R 777 /var/log/php && \
|
||||
git config --global --add safe.directory /var/www
|
||||
|
||||
COPY --from=composer /usr/bin/composer /usr/local/bin/composer
|
||||
|
||||
USER www-data
|
||||
EXPOSE 9000
|
||||
WORKDIR /var/www
|
||||
CMD composer install --no-dev --optimize-autoloader
|
||||
ENTRYPOINT php-fpm
|
||||
@@ -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
|
||||
@@ -1,21 +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
|
||||
622
iptv
622
iptv
@@ -21,10 +21,10 @@ else
|
||||
ROOT_PATH="$(pwd)"
|
||||
fi
|
||||
|
||||
IPTV_PROJECTS=("web" "playlists")
|
||||
IPTV_GITEA_URL_SSH="git@git.axenov.dev:IPTV"
|
||||
IPTV_GITEA_URL_HTTPS="https://git.axenov.dev/IPTV"
|
||||
IPTV_DOCKER_URL_SSH="$IPTV_GITEA_URL_SSH/docker.git"
|
||||
IPTV_DOXYGEN_OUTPUT="$ROOT_PATH/docs/doxygen"
|
||||
IPTV_DOCKER_URL_SSH="$IPTV_GITEA_URL_SSH/iptv-docker.git"
|
||||
|
||||
for sig in SIGHUP SIGINT SIGQUIT SIGABRT SIGKILL SIGTERM SIGTSTP; do
|
||||
# https://faculty.cs.niu.edu/~hutchins/csci480/signals.htm
|
||||
@@ -154,15 +154,6 @@ grep_match() {
|
||||
printf "%s" "$1" | grep -qE "$2" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Очищает строку аргументов от тех, которые не следует передавать в docker
|
||||
clear_flags() {
|
||||
args=${*/--full/}
|
||||
args=${args/-f/}
|
||||
args=${args/--root/}
|
||||
args=${args/-r/}
|
||||
echo "$args"
|
||||
}
|
||||
|
||||
# Возвращает название текущей ОС
|
||||
get_os() {
|
||||
case "$(uname -s)" in
|
||||
@@ -297,12 +288,6 @@ git.is_repo() {
|
||||
is_dir "$1/" && is_dir "$1/.git/"
|
||||
}
|
||||
|
||||
# Требует, чтобы в директории был инициализирован репозиторий
|
||||
git.require_repo() {
|
||||
require git
|
||||
git.is_repo "$1" || die "'$1' is not git repository!" 10
|
||||
}
|
||||
|
||||
# Клонирует репозиторий
|
||||
git.clone() {
|
||||
require git
|
||||
@@ -311,74 +296,6 @@ git.clone() {
|
||||
$cmd
|
||||
}
|
||||
|
||||
# Клонирует репозиторий быстро
|
||||
git.clone_quick() {
|
||||
require git
|
||||
git.clone --depth=1 --single-branch "$@"
|
||||
}
|
||||
|
||||
# Изменяет значение конфигурацию репозитория по ключу
|
||||
git.cfg_set() {
|
||||
require git
|
||||
cmd="git config --replace-all $1 $2"
|
||||
debug "Команда: $cmd"
|
||||
$cmd
|
||||
}
|
||||
|
||||
# Получает значение конфигурацию репозитория по ключу
|
||||
git.cfg_get() {
|
||||
require git
|
||||
cmd="git config --get $1"
|
||||
debug "Команда: $cmd"
|
||||
$cmd
|
||||
}
|
||||
|
||||
# Устанавливает имя $1 и email $2 пользователя git в конфигурации репозитория
|
||||
git.set_user() {
|
||||
require git
|
||||
|
||||
local name="$1"
|
||||
local email="$2"
|
||||
|
||||
git.cfg_set "user.name" "$name"
|
||||
git.cfg_set "user.email" "$email"
|
||||
success "Установлен пользователь git: '$name <$email>'"
|
||||
}
|
||||
|
||||
# Получает изменения из удалённого репозитория и сливает их в текущую ветку
|
||||
# shellcheck disable=SC2120
|
||||
git.pull() {
|
||||
require git
|
||||
git pull "$@" 2>&1
|
||||
}
|
||||
|
||||
# Получает изменения из удалённого репозитория и сливает их в текущую ветку
|
||||
git.fetch() {
|
||||
require git
|
||||
if [ "$1" ]; then
|
||||
if git.remote_branch_exists "origin/$1"; then
|
||||
git fetch origin "refs/heads/$1:refs/remotes/origin/$1" --progress --prune --quiet 2>&1 \
|
||||
|| die "Could not fetch $1 from origin" 12
|
||||
else
|
||||
warn "Tried to fetch branch 'origin/$1' but it does not exist."
|
||||
fi
|
||||
else
|
||||
git fetch origin --progress --prune --quiet 2>&1 || exit 12
|
||||
fi
|
||||
}
|
||||
|
||||
# Переключает HEAD
|
||||
git.checkout() {
|
||||
require git
|
||||
git checkout "$@" 2>&1
|
||||
}
|
||||
|
||||
# Возвращает имя текущей ветки
|
||||
git.current_branch() {
|
||||
require git
|
||||
git branch --show-current
|
||||
}
|
||||
|
||||
########################################################
|
||||
# Функции для работы с docker
|
||||
########################################################
|
||||
@@ -421,6 +338,7 @@ docker.build_base_images() {
|
||||
# done
|
||||
subtitle "Построение образов"
|
||||
docker.compose build
|
||||
[ ! -d web/cache/views ] && mkdir -p web/cache/views
|
||||
|
||||
success "Базовые образы построены"
|
||||
}
|
||||
@@ -445,12 +363,12 @@ docker.exec_www() {
|
||||
|
||||
# Возвращает ssh-адрес к репозиторию проекта
|
||||
project_url_ssh() {
|
||||
echo "$IPTV_GITEA_URL_SSH/${IPTV_PROJECTS[$1]}.git"
|
||||
echo "$IPTV_GITEA_URL_SSH/$1.git"
|
||||
}
|
||||
|
||||
# Возвращает https-адрес к репозиторию проекта
|
||||
project_url_https() {
|
||||
echo "$IPTV_GITEA_URL_HTTPS/${IPTV_PROJECTS[$1]}"
|
||||
echo "$IPTV_GITEA_URL_HTTPS/$1"
|
||||
}
|
||||
|
||||
# Копирует .env.example в .env, если возможно
|
||||
@@ -461,20 +379,6 @@ prepare_dot_env() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Устанавливает в файле .env для переменной $1 значение $2
|
||||
set_env_value() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
|
||||
debug "Установка '$key=$value' в файле .env"
|
||||
|
||||
if [[ "$(get_os)" = "Macos" ]]; then
|
||||
sed -Ei '' "s|$key=.+|$key=$value|g" .env
|
||||
else
|
||||
sed -Ei "s|$key=.+|$key=$value|g" .env
|
||||
fi
|
||||
}
|
||||
|
||||
# Клонирует проект
|
||||
project_clone() {
|
||||
local repo_url="$1"; shift
|
||||
@@ -511,9 +415,9 @@ find_service_compose() {
|
||||
svc="$1"
|
||||
[ -z "$svc" ] && die "неизвестный сервис" 2
|
||||
|
||||
for known in $(docker.compose --profile full config --services); do
|
||||
for known in $(docker.compose config --services); do
|
||||
if [ "$known" = "$svc" ]; then
|
||||
debug "Сервис '$svc' найден в композе"
|
||||
debug "Сервис '$known' найден в композе"
|
||||
echo "$known"
|
||||
exit
|
||||
fi
|
||||
@@ -529,20 +433,13 @@ find_services_compose() {
|
||||
|
||||
[ "$*" ] && for svc in "$@"; do
|
||||
grep_match "$svc" "^--?.*" && continue
|
||||
var_dump svc
|
||||
svc="$(find_service_compose "$svc")"
|
||||
svc="$(find_service_compose "${svc/iptv-/}")"
|
||||
services="$services $svc"
|
||||
done
|
||||
|
||||
trim "$services"
|
||||
}
|
||||
|
||||
# Возвращает состояние контейнера
|
||||
container_state() {
|
||||
state=$(docker.inspect -f '{{.State.Status}}' "$1")
|
||||
echo "${state//\'/}"
|
||||
}
|
||||
|
||||
########################################################
|
||||
# Главные функции обработки команд
|
||||
########################################################
|
||||
@@ -567,22 +464,21 @@ init() {
|
||||
prepare_dot_env
|
||||
|
||||
local counter=1
|
||||
local projects_count=${#IPTV_PROJECTS[@]}
|
||||
for project_name in "${!IPTV_PROJECTS[@]}"; do
|
||||
local project_repo_path="$docker_repo_path/$project_name"
|
||||
subtitle "[$counter/$projects_count] Подготовка проекта ${FBOLD}$project_name${FRESET}..."
|
||||
local repo_count=${#IPTV_PROJECTS[@]}
|
||||
for repo_name in "${IPTV_PROJECTS[@]}"; do
|
||||
local project_repo_path="$docker_repo_path/$repo_name"
|
||||
subtitle "[$counter/$repo_count] Подготовка репозитория ${FBOLD}$repo_name${FRESET}..."
|
||||
|
||||
local project_repo_url=$(project_url_ssh "$project_name")
|
||||
local project_repo_url=$(project_url_https "$repo_name")
|
||||
debug "Известная ссылка на репозиторий: $project_repo_url"
|
||||
|
||||
project_clone "$project_repo_url" "$project_repo_path"
|
||||
cd "$project_repo_path"
|
||||
|
||||
# git.checkout dev
|
||||
prepare_dot_env
|
||||
|
||||
cd - >/dev/null
|
||||
success "Проект $project_name готов"
|
||||
success "Репозиторий $repo_name готов"
|
||||
counter=$((counter+1))
|
||||
done
|
||||
|
||||
@@ -599,12 +495,11 @@ up() {
|
||||
process_help_arg
|
||||
subtitle "Создание и запуск контейнеров"
|
||||
|
||||
argl profiles 0 profiles
|
||||
|
||||
local services=''
|
||||
[ "$*" ] && 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 'Среда запущена успешно'
|
||||
}
|
||||
|
||||
@@ -627,13 +522,10 @@ down() {
|
||||
process_help_arg
|
||||
subtitle "Остановка и удаление контейнеров"
|
||||
|
||||
argl profiles 0 profiles
|
||||
[[ -z "$profiles" ]] && profiles="full"
|
||||
|
||||
local services=''
|
||||
[ "$*" ] && services="$(find_services_compose "$@")"
|
||||
|
||||
COMPOSE_PROFILES="$profiles" docker.compose down "$services" --remove-orphans && \
|
||||
docker.compose down "$services" --remove-orphans && \
|
||||
success 'Среда остановлена успешно'
|
||||
}
|
||||
|
||||
@@ -659,7 +551,7 @@ rebuild() {
|
||||
is_full=$(arg full 1)
|
||||
[ "$is_full" = 0 ] && is_full=$(argl full 1)
|
||||
|
||||
[ -n "$*" ] && down "$@"
|
||||
[ -n "$*" ] && down "$@" || down
|
||||
[ "$is_full" = 1 ] && docker.build_base_images
|
||||
|
||||
up "$@"
|
||||
@@ -679,150 +571,11 @@ purge() {
|
||||
|
||||
down
|
||||
docker rmi "$(docker image list | grep iptv- | awk '{print $3}')"
|
||||
docker rmi iptv/doxygen
|
||||
docker system prune --all --force
|
||||
|
||||
success 'Образы удалены успешно'
|
||||
}
|
||||
|
||||
# Обновляет все репозитории
|
||||
update() {
|
||||
process_help_arg
|
||||
local docker_repo_path=$ROOT_PATH
|
||||
local basename=$(basename "$docker_repo_path")
|
||||
if [ ! "$basename" = "iptv-docker" ]; then
|
||||
docker_repo_path="$docker_repo_path/iptv-docker"
|
||||
fi
|
||||
|
||||
subtitle "Обновление локальной среды..."
|
||||
|
||||
cd "$docker_repo_path"
|
||||
|
||||
need_pull=$(arg pull 1)
|
||||
[[ "$need_pull" = 0 ]] && need_pull=$(argl pull 1)
|
||||
[[ "$need_pull" = 1 ]] && git.pull || git.fetch
|
||||
|
||||
local counter=1
|
||||
local projects_count=${#IPTV_PROJECTS[@]}
|
||||
for project_name in "${!IPTV_PROJECTS[@]}"; do
|
||||
local project_repo_path="$docker_repo_path/$project_name"
|
||||
subtitle "[$counter/$projects_count] Обновление проекта ${FBOLD}$project_name${FRESET}..."
|
||||
|
||||
cd "$project_repo_path"
|
||||
#TODO при грязном дереве + $need_pull спрашивать (стеш, сброс), учитывать перед 'cd -' и поддержать аргументы
|
||||
git.checkout dev
|
||||
[ "$need_pull" = 1 ] && git.pull && git.fetch
|
||||
cd - >/dev/null
|
||||
|
||||
success "Проект $project_name обновлён"
|
||||
counter=$((counter+1))
|
||||
done
|
||||
|
||||
success "Локальная среда обновлена"
|
||||
}
|
||||
|
||||
# Генерирует флеймграф
|
||||
flame() {
|
||||
process_help_arg
|
||||
require zcat git
|
||||
|
||||
arg trace 0 trace_file_path
|
||||
[ -z "$trace_file_path" ] && argl trace 0 trace_file_path
|
||||
[ -z "$trace_file_path" ] && die 'Файл трейса не указан'
|
||||
|
||||
trace_file_path=$(abspath "$trace_file_path")
|
||||
|
||||
debug "Файл трейса: $trace_file_path"
|
||||
is_file "$trace_file_path" || die 'Файл трейса не найден'
|
||||
|
||||
svg_file_path=${trace_file_path/xt.gz/svg}
|
||||
debug "Файл флеймграфа: $svg_file_path"
|
||||
|
||||
flame_repo_path="$ROOT_PATH/.tools/FlameGraph"
|
||||
|
||||
if is_dir "$flame_repo_path"; then
|
||||
need_update=$(arg update 1)
|
||||
[ "$need_update" = 0 ] && need_update=$(argl update 1)
|
||||
if [ "$need_update" = 1 ]; then
|
||||
inform 'Подготовка генератора...'
|
||||
cd "$flame_repo_path"
|
||||
git.pull
|
||||
cd - >/dev/null
|
||||
fi
|
||||
else
|
||||
inform 'Подготовка генератора...'
|
||||
# https://derickrethans.nl/flamboyant-flamegraphs.html
|
||||
# https://github.com/interstellar-space/FlameGraph
|
||||
git.clone_quick https://github.com/brendangregg/FlameGraph.git "$flame_repo_path"
|
||||
fi
|
||||
|
||||
inform "Генерация флеймграфа (может занять некоторое время)..."
|
||||
|
||||
zcat "$trace_file_path" | "$flame_repo_path/flamegraph.pl" > "$svg_file_path"
|
||||
exit_code=$?
|
||||
if [[ $exit_code -gt 0 ]]; then
|
||||
exit $exit_code
|
||||
fi
|
||||
|
||||
success "Флеймграф сохранён. Открой файл в браузере:"
|
||||
print "$svg_file_path"
|
||||
}
|
||||
|
||||
# Исправляет некоторые возможные проблемы
|
||||
fix() {
|
||||
process_help_arg
|
||||
require docker
|
||||
|
||||
subtitle "Попытка исправления построения образов"
|
||||
|
||||
print "Список проблем, которые можно попробовать решить:"
|
||||
print " 1. ошибки при построении образов"
|
||||
print " 2. ошибки прав на директории vendor/bars/*"
|
||||
print " 3. ошибки записи в директорию"
|
||||
ask "Выбери свою проблему (Enter - выход)" choose
|
||||
|
||||
# shellcheck disable=SC2154
|
||||
case $choose in
|
||||
1)
|
||||
purge
|
||||
docker.build_base_images
|
||||
up
|
||||
;;
|
||||
|
||||
2)
|
||||
ask "Введи имя сервиса" svc
|
||||
svc_correct=$(find_service_hardcoded "$svc")
|
||||
[ -z "$svc_correct" ] && exit
|
||||
|
||||
dirs=("$(docker.exec "$svc_correct" "find /var/www/vendor/bars -mindepth 1 -maxdepth 1 -type d")")
|
||||
for dir in "${dirs[@]}"; do
|
||||
inform "Исправление $dir"
|
||||
docker.exec_www "$svc_correct" git config --global --add safe.directory "$dir"
|
||||
done
|
||||
;;
|
||||
|
||||
3)
|
||||
ask "Введи имя сервиса" svc
|
||||
svc_correct=$(find_service_hardcoded "$svc")
|
||||
[ -z "$svc_correct" ] && exit
|
||||
|
||||
# current=$(docker.exec "$svc_correct" sh -c 'pwd')
|
||||
ask "Введи директорию (Enter - выбор текущей /var/www)" dir
|
||||
[ -z "$dir" ] && dir='/var/www'
|
||||
|
||||
if [[ $IPTV_DEBUG -gt 0 ]]; then
|
||||
docker.exec "$svc_correct" find "$dir" -type d -print -exec chmod a+w {} +
|
||||
docker.exec "$svc_correct" find "$dir" -type f -print -exec chmod a+w {} +
|
||||
else
|
||||
docker.exec "$svc_correct" find "$dir" -type d -exec chmod a+w {} +
|
||||
docker.exec "$svc_correct" find "$dir" -type f -exec chmod a+w {} +
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
success "Готово"
|
||||
}
|
||||
|
||||
# Выполняет команду в контейнере
|
||||
exec() {
|
||||
process_help_arg
|
||||
@@ -830,7 +583,7 @@ exec() {
|
||||
svc="$1"
|
||||
regex_match "$svc" "--?r(oot)?" && { as_root=1; shift; svc="$1"; }
|
||||
|
||||
svc_correct="$(find_service_compose "$svc")"
|
||||
svc_correct="iptv-$(find_service_compose "$svc")"
|
||||
command=("${@:2}")
|
||||
regex_match "${command[0]}" "--?r(oot)?" && { as_root=1; unset "command[0]"; }
|
||||
|
||||
@@ -849,8 +602,7 @@ logs() {
|
||||
process_help_arg
|
||||
[ -z "$1" ] && die "не указан сервис" 8
|
||||
|
||||
svc=$(find_service_hardcoded "$1")
|
||||
[ -z "$svc" ] && svc=$(find_service_compose "$1")
|
||||
svc=$(find_service_compose "$1")
|
||||
[ -z "$svc" ] && die "неизвестный сервис" 3
|
||||
|
||||
subtitle "Логи сервиса $svc"
|
||||
@@ -861,113 +613,6 @@ logs() {
|
||||
$cmd
|
||||
}
|
||||
|
||||
# Выводит список профилей
|
||||
profiles() {
|
||||
process_help_arg
|
||||
subtitle "Список доступных профилей"
|
||||
|
||||
profiles=("$(docker.compose config --profiles | sort)")
|
||||
IFS=$'\n' sorted=("${profiles[@]}")
|
||||
for profile in "${sorted[@]}"; do
|
||||
print " $profile"
|
||||
done
|
||||
|
||||
echo
|
||||
inform "Просмотра списка сервисов в профиле используй './iptv services ПРОФИЛЬ'"
|
||||
}
|
||||
|
||||
# Выводит список сервисов профиля
|
||||
services() {
|
||||
process_help_arg
|
||||
[ -z "$1" ] && die "не указан профиль" 8
|
||||
|
||||
subtitle "Список сервисов в профиле: $1"
|
||||
|
||||
services=$(docker.compose --profile "$1" config --services | sort)
|
||||
IFS=$'\n' sorted=("${services[@]}")
|
||||
for service in "${sorted[@]}"; do
|
||||
print " $service"
|
||||
done
|
||||
|
||||
echo
|
||||
inform "Для просмотра ПО сервиса используй './iptv info СЕРВИС'"
|
||||
inform "Для просмотра состояния сервиса используй './iptv status СЕРВИС'"
|
||||
inform "Для выполнения команды в сервисе используй './iptv exec СЕРВИС'"
|
||||
}
|
||||
|
||||
# Выводит информацию о ПО в контейнере
|
||||
info() {
|
||||
process_help_arg
|
||||
svc=$(find_service_hardcoded "$1")
|
||||
|
||||
subtitle "Состояние сервиса $svc"
|
||||
#TODO как-то определять состав ПО, от этого уже выводить что-то дальше
|
||||
|
||||
docker.exec "$svc" date
|
||||
|
||||
subtitle "Переменные среды:"
|
||||
docker.exec_www "$svc" env && echo
|
||||
|
||||
subtitle "Версии ПО:"
|
||||
docker.exec "$svc" cat /etc/os-release && echo
|
||||
docker.exec "$svc" git --version && echo
|
||||
docker.exec "$svc" php -v && echo
|
||||
docker.exec "$svc" composer --version && echo
|
||||
docker.exec "$svc" php artisan --version && echo
|
||||
docker.exec "$svc" go version && echo
|
||||
docker.exec "$svc" go env
|
||||
|
||||
subtitle "Содержимое \$_SERVER (php):"
|
||||
docker.exec_www "$svc" php -i | grep _SERVER
|
||||
|
||||
subtitle "Загруженные расширения (php):"
|
||||
docker.exec_www "$svc" php -m
|
||||
}
|
||||
|
||||
# Выводит состояние сервиса
|
||||
status() {
|
||||
process_help_arg
|
||||
[ -z "$1" ] && die "не указан сервис" 8
|
||||
|
||||
svc=$(find_service_hardcoded "$1")
|
||||
[ -z "$svc" ] && svc=$(find_service_compose "$1")
|
||||
[ -z "$svc" ] && die "неизвестный сервис" 3
|
||||
|
||||
subtitle "Состояние сервиса $svc"
|
||||
inform "Код:"
|
||||
|
||||
# shellcheck disable=SC2015
|
||||
git.is_repo "$ROOT_PATH/$svc/app/" \
|
||||
&& print " Репозиторий: +" \
|
||||
|| print " Репозиторий: -"
|
||||
|
||||
if is_dir "$ROOT_PATH/$svc/app/"; then
|
||||
cd "$ROOT_PATH/$svc/app/" 2>/dev/null
|
||||
print " Ветка: $(git.current_branch)"
|
||||
cd - >/dev/null
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2015
|
||||
is_file "$ROOT_PATH/$svc/app/.env" && \
|
||||
print " Файл app/.env: +" || \
|
||||
print " Файл app/.env: -"
|
||||
|
||||
inform "Контейнер:"
|
||||
ips=$(docker.inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$svc")
|
||||
print " IP: ${ips:--}"
|
||||
print " State: $(container_state "$svc")"
|
||||
health=$(docker.inspect -f '{{.State.Health.Status}}' "$svc")
|
||||
health=${health//\'/}
|
||||
print " Health: ${health:--}"
|
||||
print " Running: $(docker.inspect -f '{{.State.Running}}' "$svc")"
|
||||
print " Paused: $(docker.inspect -f '{{.State.Paused}}' "$svc")"
|
||||
print " Restarting: $(docker.inspect -f '{{.State.Restarting}}' "$svc")"
|
||||
print " OOMKilled: $(docker.inspect -f '{{.State.OOMKilled}}' "$svc")"
|
||||
print " Dead: $(docker.inspect -f '{{.State.Dead}}' "$svc")"
|
||||
error=$(docker.inspect -f '{{.State.Error}}' "$svc")
|
||||
print " Error: ${error:--}"
|
||||
}
|
||||
|
||||
# Выводит статистику потребления ресурсов контейнерами
|
||||
stats() {
|
||||
subtitle "Состояние контейнеров"
|
||||
@@ -975,51 +620,6 @@ stats() {
|
||||
docker.compose stats "$@"
|
||||
}
|
||||
|
||||
# Генерирует документацию по коду сервиса
|
||||
doxygen() {
|
||||
process_help_arg
|
||||
require docker
|
||||
|
||||
if [[ $(docker image ls | grep -c iptv/doxygen) -eq 0 ]]; then
|
||||
inform "Подготовка doxygen..."
|
||||
docker build -t iptv/doxygen "$ROOT_PATH/.tools/doxygen"
|
||||
fi
|
||||
|
||||
svc=$(find_service_hardcoded "$1")
|
||||
[ -z "$svc" ] && die "неизвестный сервис" 3
|
||||
|
||||
subtitle "Генерация документации для $svc"
|
||||
[[ $IPTV_DEBUG -gt 0 ]] && args="" || args="-q"
|
||||
|
||||
doxyfile="$ROOT_PATH/.tools/doxygen/$svc.Doxyfile"
|
||||
is_file "$doxyfile" || die "Не найден файл $doxyfile" 8
|
||||
|
||||
input_dir="$ROOT_PATH/$svc"
|
||||
is_dir "$input_dir" || die "Не найдена директория $input_dir" 9
|
||||
|
||||
output_dir="$IPTV_DOXYGEN_OUTPUT/$svc"
|
||||
is_dir "$output_dir" || mkdir -p "$output_dir"
|
||||
|
||||
cmd="docker run --rm -it -v $input_dir:/data -v $output_dir:/output -v $doxyfile:/data/Doxyfile iptv/doxygen $args"
|
||||
debug "Команда: $cmd"
|
||||
# $cmd
|
||||
rm -f "$input_dir/Doxyfile"
|
||||
|
||||
doc_path=$(basename "$IPTV_DOXYGEN_OUTPUT")
|
||||
html_path="$IPTV_DOXYGEN_OUTPUT/../doxygen.html"
|
||||
html="<!DOCTYPE html><html><head><meta charset='UTF-8'><style>*{font-family:'monospace'}h3{margin-bottom:0}</style><title>LisUP Doxygen</title></head>"
|
||||
html="$html<body><h1>Документация к коду сервисов</h1><p><b>Для справки по генерации документации выполни в терминале './iptv doxygen --help'</b></p><ul>"
|
||||
for html_dir in "$IPTV_DOXYGEN_OUTPUT"/*; do
|
||||
doc_svc=$(basename "$html_dir")
|
||||
mtime=$(date -d"$(stat -c '%y' "$html_dir")" +'%d.%m.%Y %H:%M')
|
||||
html="$html<li><h3><a href='./$doc_path/$doc_svc/html/index.html'>$doc_svc</a></h3><b>Обновлено:</b> $mtime<br><b>Команда:</b> ./iptv doxygen $doc_svc</li>"
|
||||
done
|
||||
echo "$html</ul></body></html>" > "$html_path"
|
||||
|
||||
echo
|
||||
success "Готово. Открой в браузере файл $(realpath "$html_path")"
|
||||
}
|
||||
|
||||
########################################################
|
||||
# Команды справки
|
||||
########################################################
|
||||
@@ -1107,15 +707,11 @@ help.up() {
|
||||
print " ./iptv up [АРГУМЕНТЫ] [СЕРВИСЫ...]"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " -f|--full - перестроить также и базовые образы (если опущено, будут"
|
||||
print " построены только образы сервисов)"
|
||||
print " --profiles - использовать указанные профили (через запятую)"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
print
|
||||
print "Если указан один и более СЕРВИСОВ, то КОМАНДА будет применена только к ним."
|
||||
print
|
||||
# print "СЕРВИСЫ можно передавать без приставки 'lis-'"
|
||||
print "Полный список СЕРВИСОВ можно узнать командой './iptv services full'"
|
||||
print "СЕРВИСЫ можно передавать без префикса 'iptv-'"
|
||||
}
|
||||
|
||||
help.start() {
|
||||
@@ -1126,13 +722,11 @@ help.start() {
|
||||
print " ./iptv start [АРГУМЕНТЫ] [СЕРВИСЫ...]"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " --profiles - использовать указанные профили (через запятую)"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
print
|
||||
print "Если указан один и более СЕРВИСОВ, то КОМАНДА будет применена только к ним."
|
||||
print
|
||||
# print "СЕРВИСЫ можно передавать без приставки 'lis-'"
|
||||
print "Полный список СЕРВИСОВ можно узнать командой './iptv services full'"
|
||||
print "СЕРВИСЫ можно передавать без префикса 'iptv-'"
|
||||
}
|
||||
|
||||
help.down() {
|
||||
@@ -1143,13 +737,11 @@ help.down() {
|
||||
print " ./iptv down [АРГУМЕНТЫ] [СЕРВИСЫ...]"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " --profiles - использовать указанные профили (через запятую)"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
print
|
||||
print "Если указан один и более СЕРВИСОВ, то КОМАНДА будет применена только к ним."
|
||||
print
|
||||
# print "СЕРВИСЫ можно передавать без приставки 'lis-'"
|
||||
print "Полный список СЕРВИСОВ можно узнать командой './iptv services full'"
|
||||
print "СЕРВИСЫ можно передавать без префикса 'iptv-'"
|
||||
}
|
||||
|
||||
help.stop() {
|
||||
@@ -1160,13 +752,11 @@ help.stop() {
|
||||
print " ./iptv stop [АРГУМЕНТЫ] [СЕРВИСЫ...]"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " --profiles - использовать указанные профили (через запятую)"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
print
|
||||
print "Если указан один и более СЕРВИСОВ, то КОМАНДА будет применена только к ним."
|
||||
print
|
||||
# print "СЕРВИСЫ можно передавать без приставки 'lis-'"
|
||||
print "Полный список СЕРВИСОВ можно узнать командой './iptv services full'"
|
||||
print "СЕРВИСЫ можно передавать без префикса 'iptv-'"
|
||||
}
|
||||
|
||||
help.rebuild() {
|
||||
@@ -1177,15 +767,11 @@ help.rebuild() {
|
||||
print " ./iptv rebuild [АРГУМЕНТЫ] [СЕРВИСЫ...]"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " -f|--full - перестроить базовые образы (если опущено, будут"
|
||||
print " построены только образы сервисов)"
|
||||
print " --profiles - использовать указанные профили (через запятую)"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
print
|
||||
print "Если указан один и более СЕРВИСОВ, то КОМАНДА будет применена только к ним."
|
||||
print
|
||||
# print "СЕРВИСЫ можно передавать без приставки 'lis-'"
|
||||
print "Полный список СЕРВИСОВ можно узнать командой './iptv services full'"
|
||||
print "СЕРВИСЫ можно передавать без префикса 'iptv-'"
|
||||
}
|
||||
|
||||
help.restart() {
|
||||
@@ -1200,8 +786,7 @@ help.restart() {
|
||||
print
|
||||
print "Если указан один и более СЕРВИСОВ, то КОМАНДА будет применена только к ним."
|
||||
print
|
||||
# print "СЕРВИСЫ можно передавать без приставки 'lis-'"
|
||||
print "Полный список СЕРВИСОВ можно узнать командой './iptv services full'"
|
||||
print "СЕРВИСЫ можно передавать без префикса 'iptv-'"
|
||||
}
|
||||
|
||||
help.purge() {
|
||||
@@ -1215,80 +800,6 @@ help.purge() {
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
}
|
||||
|
||||
help.update() {
|
||||
print "КОМАНДА: update"
|
||||
print "Обновляет окружение разработки, используя 'git fetch'."
|
||||
print
|
||||
print "Использование:"
|
||||
print " ./iptv update [АРГУМЕНТЫ]"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " -p|--pull - использовать 'git pull' вместо 'git fetch'"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
print
|
||||
print "Перед выполнением, необходимо обеспечить чистую рабочую директорию репозитория."
|
||||
}
|
||||
|
||||
help.setenv() {
|
||||
print "КОМАНДА: setenv"
|
||||
print "Переключает среду в каждом сервисе окружения. Устанавливает 'APP_ENV'"
|
||||
print "в файле .env сервиса и переключает git HEAD на тег, указанный в iptv-docker/.env."
|
||||
print
|
||||
print "Использование:"
|
||||
print " ./iptv setenv СРЕДА [АРГУМЕНТЫ]"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
print
|
||||
print "Перед выполнением, необходимо обеспечить чистую рабочие директории репозиториев."
|
||||
}
|
||||
|
||||
help.flame() {
|
||||
print "КОМАНДА: flame"
|
||||
print "Выполняет построение флеймграфа по снимку трейса xdebug."
|
||||
print
|
||||
print "Использование:"
|
||||
print " ./iptv flame АРГУМЕНТЫ"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " -t|--trace ПУТЬ - путь до локального файла трейса"
|
||||
print " -u|--update - сначала обновить генератор"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
}
|
||||
|
||||
help.fix() {
|
||||
print "КОМАНДА: fix"
|
||||
print "В интерактивном режиме пытается исправить локальную среду в случае ошибок."
|
||||
print
|
||||
print "Использование:"
|
||||
print " ./iptv fix [АРГУМЕНТЫ]"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
}
|
||||
|
||||
help.exec() {
|
||||
print "КОМАНДА: exec"
|
||||
print "Выполняет произвольную команду внутри контейнера."
|
||||
print
|
||||
print "Использование:"
|
||||
print " ./iptv exec СЕРВИС [АРГУМЕНТЫ] ВНУТ-КОМАНДА..."
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " -r|--root - выполнить ВНУТ-КОМАНДУ от имени root (если опущено, будет выполнена"
|
||||
print " от имени www-data)"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
print
|
||||
print "Примеры:"
|
||||
print " ./iptv exec arm composer i"
|
||||
print " ./iptv exec core -r chmod 0777 storage/logs"
|
||||
print
|
||||
print "ВНУТ-КОМАНДА, которая должна выполниться внутри контейнера, может иметь свои аргументы."
|
||||
print
|
||||
# print "СЕРВИС можно передавать без приставки 'lis-'"
|
||||
print "Полный список СЕРВИСОВ можно узнать командой './iptv services full'"
|
||||
}
|
||||
|
||||
help.logs() {
|
||||
print "КОМАНДА: logs"
|
||||
print "Выводит логи указанного СЕРВИСА."
|
||||
@@ -1301,60 +812,7 @@ help.logs() {
|
||||
print
|
||||
print "Поддерживаются АРГУМЕНТЫ 'docker logs'."
|
||||
print
|
||||
# print "СЕРВИС можно передавать без приставки 'lis-'"
|
||||
print "Полный список СЕРВИСОВ можно узнать командой './iptv services full'"
|
||||
}
|
||||
|
||||
help.profiles() {
|
||||
print "КОМАНДА: profiles"
|
||||
print "Выводит список возможных профилей для запуска окружения."
|
||||
print
|
||||
print "Использование:"
|
||||
print " ./iptv profiles [АРГУМЕНТЫ]"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
}
|
||||
|
||||
help.services() {
|
||||
print "КОМАНДА: services"
|
||||
print "Выводит список сервисов в указанном ПРОФИЛЕ."
|
||||
print
|
||||
print "Использование:"
|
||||
print " ./iptv services ПРОФИЛЬ [АРГУМЕНТЫ]"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
print
|
||||
print "Полный список ПРОФИЛЕЙ можно узнать командой './iptv profiles'"
|
||||
}
|
||||
|
||||
help.info() {
|
||||
print "КОМАНДА: info"
|
||||
print 'Выводит дату, версии ПО, переменные среды и пр. из контейнера указанного СЕРВИСА.'
|
||||
print
|
||||
print "Использование:"
|
||||
print " ./iptv info СЕРВИС [АРГУМЕНТЫ]"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
print
|
||||
# print "СЕРВИС можно передавать без приставки 'lis-'"
|
||||
print "Полный список СЕРВИСОВ можно узнать командой './iptv services full'"
|
||||
}
|
||||
|
||||
help.status() {
|
||||
print "КОМАНДА: status"
|
||||
print "Выводит состояние СЕРВИСА и его репозитория (при наличии)."
|
||||
print
|
||||
print "Использование:"
|
||||
print " ./iptv status СЕРВИС [АРГУМЕНТЫ]"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
print
|
||||
# print "СЕРВИС можно передавать без приставки 'lis-'"
|
||||
print "Полный список СЕРВИСОВ можно узнать командой './iptv services full'"
|
||||
print "СЕРВИС можно передавать без префикса 'iptv-'"
|
||||
}
|
||||
|
||||
help.stats() {
|
||||
@@ -1371,21 +829,6 @@ help.stats() {
|
||||
print "Рекомендуется использовать вместе с '--no-stream'."
|
||||
}
|
||||
|
||||
help.doxygen() {
|
||||
print "КОМАНДА: doxygen"
|
||||
print "Вызывает doxygen для генерации дкоументации к коду указанного СЕРВИСА и индексной"
|
||||
print "страницы $IPTV_DOXYGEN_OUTPUT/doxygen.html"
|
||||
print
|
||||
print "Использование:"
|
||||
print " ./iptv doxygen СЕРВИС"
|
||||
print
|
||||
print "Доступные АРГУМЕНТЫ:"
|
||||
print " -h|--help - вывести это сообщение и выйти"
|
||||
print
|
||||
# print "СЕРВИС можно передавать без приставки 'lis-'"
|
||||
print "Полный список СЕРВИСОВ можно узнать командой './iptv services full'"
|
||||
}
|
||||
|
||||
########################################################
|
||||
# Точка входа
|
||||
########################################################
|
||||
@@ -1401,18 +844,9 @@ case "$COMMAND" in
|
||||
stop ) stop "$@" ;;
|
||||
r|rebuild ) rebuild "$@" ;;
|
||||
restart ) restart "$@" ;;
|
||||
purge ) purge ;;
|
||||
update ) update ;;
|
||||
s|setenv ) setenv "$@" ;;
|
||||
f|flame ) flame "$@" ;;
|
||||
fix ) fix ;;
|
||||
exec ) exec "$@" ;;
|
||||
purge ) purge ;;
|
||||
logs ) logs "$@" ;;
|
||||
profiles ) profiles ;;
|
||||
services ) services "$1" ;;
|
||||
info ) info "$1" ;;
|
||||
status ) status "$1" ;;
|
||||
stats ) stats "$@" ;;
|
||||
doxygen ) doxygen "$@" ;;
|
||||
* ) die "неизвестная команда. Смотри './iptv help' для справки." ;;
|
||||
esac
|
||||
|
||||
Reference in New Issue
Block a user