Add interactive install.sh for server deployment
This commit is contained in:
+5
-2
@@ -18,8 +18,11 @@ CADDY_AUTH_API_TOKEN=
|
|||||||
# Опционально: Subscription Page (например https://sub.example.com)
|
# Опционально: Subscription Page (например https://sub.example.com)
|
||||||
REMNAWAVE_SUBSCRIPTION_URL=
|
REMNAWAVE_SUBSCRIPTION_URL=
|
||||||
|
|
||||||
# PostgreSQL (docker-compose подставляет URL к сервису db)
|
# PostgreSQL (должен совпадать с POSTGRES_* ниже; install.sh сгенерирует автоматически)
|
||||||
DATABASE_URL=postgres://tgvpn:tgvpn@db:5432/tgvpn?sslmode=disable
|
POSTGRES_USER=tgvpn
|
||||||
|
POSTGRES_PASSWORD=change_me_strong_password
|
||||||
|
POSTGRES_DB=tgvpn
|
||||||
|
DATABASE_URL=postgres://tgvpn:change_me_strong_password@db:5432/tgvpn?sslmode=disable
|
||||||
|
|
||||||
# Создание пользователей по умолчанию
|
# Создание пользователей по умолчанию
|
||||||
DEFAULT_USER_DAYS=30
|
DEFAULT_USER_DAYS=30
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
### Добавлено
|
### Добавлено
|
||||||
|
|
||||||
|
- `install.sh` — интерактивный установщик на Linux-сервер (опрос параметров, `.env`, Docker)
|
||||||
- PostgreSQL 16 в Docker Compose (`DATABASE_URL`)
|
- PostgreSQL 16 в Docker Compose (`DATABASE_URL`)
|
||||||
- Создание пользователей Remnawave: `/admin user`, `/admin user <логин> [дней]`
|
- Создание пользователей Remnawave: `/admin user`, `/admin user <логин> [дней]`
|
||||||
- Назначение сквадов: external + internal (`/admin assign <логин>`, мастер с кнопками)
|
- Назначение сквадов: external + internal (`/admin assign <логин>`, мастер с кнопками)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Telegram-бот на Go для управления VPN через панель
|
|||||||
## Содержание
|
## Содержание
|
||||||
|
|
||||||
- [Требования](#требования)
|
- [Требования](#требования)
|
||||||
|
- [Установщик (рекомендуется)](#установщик-на-сервере)
|
||||||
- [Быстрый старт](#быстрый-старт-docker-compose)
|
- [Быстрый старт](#быстрый-старт-docker-compose)
|
||||||
- [PostgreSQL](#postgresql)
|
- [PostgreSQL](#postgresql)
|
||||||
- [Развёртывание на VPS](#развёртывание-на-vps-linux)
|
- [Развёртывание на VPS](#развёртывание-на-vps-linux)
|
||||||
@@ -29,6 +30,63 @@ Telegram-бот на Go для управления VPN через панель
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Установщик на сервере
|
||||||
|
|
||||||
|
Интерактивный скрипт запросит все параметры, создаст `.env` и запустит Docker.
|
||||||
|
|
||||||
|
### Требования на сервере
|
||||||
|
|
||||||
|
- Linux (Ubuntu 22.04/24.04, Debian 12)
|
||||||
|
- `curl`, `git` (для клонирования)
|
||||||
|
- Права `sudo` (для установки Docker при необходимости)
|
||||||
|
|
||||||
|
### Установка одной командой
|
||||||
|
|
||||||
|
Если репозиторий уже на сервере:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd tgvpn
|
||||||
|
chmod +x install.sh
|
||||||
|
./install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Или скачайте скрипт и укажите каталог `/opt/tgvpn`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /opt/tgvpn
|
||||||
|
cd /opt/tgvpn
|
||||||
|
git clone <URL-вашего-репозитория> .
|
||||||
|
chmod +x install.sh
|
||||||
|
./install.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Что спрашивает установщик
|
||||||
|
|
||||||
|
| Блок | Параметры |
|
||||||
|
|------|-----------|
|
||||||
|
| Telegram | `BOT_TOKEN`, `TELEGRAM_ADMIN_ID`, `BOT_DEBUG` |
|
||||||
|
| Remnawave | URL панели, API token, Caddy token, subscription URL |
|
||||||
|
| PostgreSQL | пользователь, база, пароль (можно сгенерировать случайный) |
|
||||||
|
| VPN | срок по умолчанию, UUID сквадов (опционально) |
|
||||||
|
| Система | каталог установки, URL git (если не из текущей папки) |
|
||||||
|
|
||||||
|
После завершения: `docker compose up -d --build`, проверка `docker compose ps`.
|
||||||
|
|
||||||
|
### Переменные окружения для PostgreSQL в compose
|
||||||
|
|
||||||
|
В `.env` должны совпадать `POSTGRES_PASSWORD` и пароль в `DATABASE_URL`:
|
||||||
|
|
||||||
|
```env
|
||||||
|
POSTGRES_USER=tgvpn
|
||||||
|
POSTGRES_PASSWORD=ваш_сильный_пароль
|
||||||
|
POSTGRES_DB=tgvpn
|
||||||
|
DATABASE_URL=postgres://tgvpn:ваш_сильный_пароль@db:5432/tgvpn?sslmode=disable
|
||||||
|
```
|
||||||
|
|
||||||
|
Установщик заполняет это автоматически.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Быстрый старт (Docker Compose)
|
## Быстрый старт (Docker Compose)
|
||||||
|
|
||||||
### 1. Клонирование
|
### 1. Клонирование
|
||||||
@@ -645,6 +703,7 @@ tgvpn/
|
|||||||
│ │ └── migrations/ # SQL-миграции (001_init.sql)
|
│ │ └── migrations/ # SQL-миграции (001_init.sql)
|
||||||
│ └── remnawave/ # API панели (users, squads)
|
│ └── remnawave/ # API панели (users, squads)
|
||||||
├── Dockerfile # multi-stage сборка
|
├── Dockerfile # multi-stage сборка
|
||||||
|
├── install.sh # интерактивный установщик на сервер
|
||||||
├── docker-compose.yml # bot + PostgreSQL (volume pgdata)
|
├── docker-compose.yml # bot + PostgreSQL (volume pgdata)
|
||||||
├── .env.example # шаблон переменных
|
├── .env.example # шаблон переменных
|
||||||
├── .dockerignore
|
├── .dockerignore
|
||||||
|
|||||||
+6
-4
@@ -4,9 +4,11 @@ services:
|
|||||||
container_name: tgvpn-db
|
container_name: tgvpn-db
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: tgvpn
|
POSTGRES_USER: ${POSTGRES_USER:-tgvpn}
|
||||||
POSTGRES_PASSWORD: tgvpn
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-tgvpn}
|
||||||
POSTGRES_DB: tgvpn
|
POSTGRES_DB: ${POSTGRES_DB:-tgvpn}
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
volumes:
|
volumes:
|
||||||
- pgdata:/var/lib/postgresql/data
|
- pgdata:/var/lib/postgresql/data
|
||||||
healthcheck:
|
healthcheck:
|
||||||
@@ -29,7 +31,7 @@ services:
|
|||||||
- .env
|
- .env
|
||||||
environment:
|
environment:
|
||||||
BOT_DEBUG: ${BOT_DEBUG:-false}
|
BOT_DEBUG: ${BOT_DEBUG:-false}
|
||||||
DATABASE_URL: postgres://tgvpn:tgvpn@db:5432/tgvpn?sslmode=disable
|
DATABASE_URL: ${DATABASE_URL:-postgres://tgvpn:tgvpn@db:5432/tgvpn?sslmode=disable}
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
pgdata:
|
pgdata:
|
||||||
|
|||||||
+281
@@ -0,0 +1,281 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Интерактивная установка tgvpn на Linux-сервер (Docker + PostgreSQL)
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
INSTALL_DIR="${INSTALL_DIR:-/opt/tgvpn}"
|
||||||
|
REPO_URL=""
|
||||||
|
USE_CURRENT_DIR=false
|
||||||
|
SKIP_DOCKER_INSTALL=false
|
||||||
|
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
info() { echo -e "${CYAN}[*]${NC} $*"; }
|
||||||
|
ok() { echo -e "${GREEN}[✓]${NC} $*"; }
|
||||||
|
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
|
||||||
|
fail() { echo -e "${RED}[✗]${NC} $*" >&2; exit 1; }
|
||||||
|
|
||||||
|
prompt() {
|
||||||
|
local label="$1"
|
||||||
|
local default="${2:-}"
|
||||||
|
local val
|
||||||
|
if [[ -n "$default" ]]; then
|
||||||
|
read -r -p "$label [$default]: " val
|
||||||
|
echo "${val:-$default}"
|
||||||
|
else
|
||||||
|
read -r -p "$label: " val
|
||||||
|
echo "$val"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_required() {
|
||||||
|
local label="$1"
|
||||||
|
local val=""
|
||||||
|
while [[ -z "$val" ]]; do
|
||||||
|
read -r -p "$label: " val
|
||||||
|
[[ -z "$val" ]] && warn "Поле обязательно."
|
||||||
|
done
|
||||||
|
echo "$val"
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_secret() {
|
||||||
|
local label="$1"
|
||||||
|
local val=""
|
||||||
|
while [[ -z "$val" ]]; do
|
||||||
|
read -r -s -p "$label: " val
|
||||||
|
echo ""
|
||||||
|
[[ -z "$val" ]] && warn "Поле обязательно."
|
||||||
|
done
|
||||||
|
echo "$val"
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_yn() {
|
||||||
|
local label="$1"
|
||||||
|
local default="${2:-y}"
|
||||||
|
local hint="Y/n"
|
||||||
|
[[ "$default" == "n" ]] && hint="y/N"
|
||||||
|
local ans
|
||||||
|
read -r -p "$label [$hint]: " ans
|
||||||
|
ans="${ans:-$default}"
|
||||||
|
[[ "$ans" =~ ^[Yy] ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
need_cmd() {
|
||||||
|
command -v "$1" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
check_docker() {
|
||||||
|
need_cmd docker && docker compose version >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
install_docker() {
|
||||||
|
info "Установка Docker (официальный репозиторий)..."
|
||||||
|
if need_cmd apt-get; then
|
||||||
|
sudo apt-get update -qq
|
||||||
|
sudo apt-get install -y ca-certificates curl
|
||||||
|
sudo install -m 0755 -d /etc/apt/keyrings
|
||||||
|
if [[ ! -f /etc/apt/keyrings/docker.asc ]]; then
|
||||||
|
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||||||
|
sudo chmod a+r /etc/apt/keyrings/docker.asc
|
||||||
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
|
||||||
|
$(. /etc/os-release && echo "${VERSION_CODENAME}") stable" | \
|
||||||
|
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
fi
|
||||||
|
sudo apt-get update -qq
|
||||||
|
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||||
|
sudo usermod -aG docker "$USER" 2>/dev/null || true
|
||||||
|
ok "Docker установлен. Если команда docker требует sudo — перелогиньтесь или выполните: newgrp docker"
|
||||||
|
else
|
||||||
|
fail "Автоустановка Docker поддерживается только для Debian/Ubuntu (apt). Установите Docker вручную: https://docs.docker.com/engine/install/"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
write_env() {
|
||||||
|
local env_file="$1"
|
||||||
|
cat > "$env_file" <<EOF
|
||||||
|
# Сгенерировано install.sh $(date -Iseconds)
|
||||||
|
BOT_TOKEN=${BOT_TOKEN}
|
||||||
|
BOT_DEBUG=${BOT_DEBUG}
|
||||||
|
TELEGRAM_ADMIN_ID=${TELEGRAM_ADMIN_ID}
|
||||||
|
|
||||||
|
REMNAWAVE_PANEL_NAME=${REMNAWAVE_PANEL_NAME}
|
||||||
|
REMNAWAVE_PANEL_URL=${REMNAWAVE_PANEL_URL}
|
||||||
|
REMNAWAVE_API_TOKEN=${REMNAWAVE_API_TOKEN}
|
||||||
|
CADDY_AUTH_API_TOKEN=${CADDY_AUTH_API_TOKEN}
|
||||||
|
REMNAWAVE_SUBSCRIPTION_URL=${REMNAWAVE_SUBSCRIPTION_URL}
|
||||||
|
|
||||||
|
POSTGRES_USER=${POSTGRES_USER}
|
||||||
|
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||||
|
POSTGRES_DB=${POSTGRES_DB}
|
||||||
|
DATABASE_URL=${DATABASE_URL}
|
||||||
|
|
||||||
|
DEFAULT_USER_DAYS=${DEFAULT_USER_DAYS}
|
||||||
|
DEFAULT_EXTERNAL_SQUAD_UUID=${DEFAULT_EXTERNAL_SQUAD_UUID}
|
||||||
|
DEFAULT_INTERNAL_SQUAD_UUIDS=${DEFAULT_INTERNAL_SQUAD_UUIDS}
|
||||||
|
EOF
|
||||||
|
chmod 600 "$env_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
banner() {
|
||||||
|
echo ""
|
||||||
|
echo "========================================"
|
||||||
|
echo " tgvpn — установщик Telegram-бота"
|
||||||
|
echo " Remnawave + PostgreSQL + Docker"
|
||||||
|
echo "========================================"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
validate_db_password() {
|
||||||
|
if [[ "$POSTGRES_PASSWORD" =~ [:@/?#\[\] ] ]]; then
|
||||||
|
warn "В пароле PostgreSQL есть спецсимволы. Рекомендуется сгенерировать пароль (буквы/цифры)."
|
||||||
|
if ! prompt_yn "Продолжить с этим паролем?" "n"; then
|
||||||
|
fail "Укажите другой пароль или сгенерируйте автоматически."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
banner
|
||||||
|
|
||||||
|
local script_dir
|
||||||
|
script_dir="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
if [[ -f "$script_dir/docker-compose.yml" ]] && [[ -f "$script_dir/main.go" ]]; then
|
||||||
|
if prompt_yn "Запустить установку из текущей папки ($script_dir)?" "y"; then
|
||||||
|
USE_CURRENT_DIR=true
|
||||||
|
INSTALL_DIR="$script_dir"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! $USE_CURRENT_DIR; then
|
||||||
|
INSTALL_DIR="$(prompt "Каталог установки" "$INSTALL_DIR")"
|
||||||
|
REPO_URL="$(prompt "URL git-репозитория (пусто — только каталог, код уже должен быть там)" "")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
info "=== Telegram ==="
|
||||||
|
BOT_TOKEN="$(prompt_secret "BOT_TOKEN (от @BotFather)")"
|
||||||
|
TELEGRAM_ADMIN_ID="$(prompt_required "TELEGRAM_ADMIN_ID (числовой ID от @userinfobot)")"
|
||||||
|
if [[ ! "$TELEGRAM_ADMIN_ID" =~ ^[0-9]+$ ]]; then
|
||||||
|
fail "TELEGRAM_ADMIN_ID должен быть числом"
|
||||||
|
fi
|
||||||
|
if prompt_yn "Включить BOT_DEBUG (подробные логи)?" "n"; then
|
||||||
|
BOT_DEBUG=true
|
||||||
|
else
|
||||||
|
BOT_DEBUG=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
info "=== Remnawave ==="
|
||||||
|
REMNAWAVE_PANEL_NAME="$(prompt "Название панели в боте" "Панель 1")"
|
||||||
|
REMNAWAVE_PANEL_URL="$(prompt_required "REMNAWAVE_PANEL_URL (https://panel.example.com)")"
|
||||||
|
if [[ ! "$REMNAWAVE_PANEL_URL" =~ ^https?:// ]]; then
|
||||||
|
fail "URL панели должен начинаться с http:// или https://"
|
||||||
|
fi
|
||||||
|
REMNAWAVE_PANEL_URL="${REMNAWAVE_PANEL_URL%/}"
|
||||||
|
REMNAWAVE_API_TOKEN="$(prompt_secret "REMNAWAVE_API_TOKEN (Settings → API Tokens)")"
|
||||||
|
CADDY_AUTH_API_TOKEN="$(prompt "CADDY_AUTH_API_TOKEN (опционально, Enter — пропустить)" "")"
|
||||||
|
REMNAWAVE_SUBSCRIPTION_URL="$(prompt "REMNAWAVE_SUBSCRIPTION_URL (опционально)" "")"
|
||||||
|
if [[ -n "$REMNAWAVE_SUBSCRIPTION_URL" ]]; then
|
||||||
|
REMNAWAVE_SUBSCRIPTION_URL="${REMNAWAVE_SUBSCRIPTION_URL%/}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
info "=== PostgreSQL ==="
|
||||||
|
POSTGRES_USER="$(prompt "Пользователь БД" "tgvpn")"
|
||||||
|
POSTGRES_DB="$(prompt "Имя базы" "tgvpn")"
|
||||||
|
if prompt_yn "Сгенерировать случайный пароль PostgreSQL?" "y"; then
|
||||||
|
POSTGRES_PASSWORD="$(openssl rand -hex 16 2>/dev/null || head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 24)"
|
||||||
|
ok "Пароль сгенерирован (сохранён в .env)"
|
||||||
|
else
|
||||||
|
POSTGRES_PASSWORD="$(prompt_secret "POSTGRES_PASSWORD")"
|
||||||
|
fi
|
||||||
|
validate_db_password
|
||||||
|
DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?sslmode=disable"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
info "=== Пользователи VPN (по умолчанию) ==="
|
||||||
|
DEFAULT_USER_DAYS="$(prompt "Срок подписки по умолчанию (дней)" "30")"
|
||||||
|
DEFAULT_EXTERNAL_SQUAD_UUID="$(prompt "DEFAULT_EXTERNAL_SQUAD_UUID (опционально)" "")"
|
||||||
|
DEFAULT_INTERNAL_SQUAD_UUIDS="$(prompt "DEFAULT_INTERNAL_SQUAD_UUIDS через запятую (опционально)" "")"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
if ! check_docker; then
|
||||||
|
warn "Docker или Docker Compose не найдены."
|
||||||
|
if prompt_yn "Установить Docker автоматически (Ubuntu/Debian)?" "y"; then
|
||||||
|
install_docker
|
||||||
|
if ! check_docker; then
|
||||||
|
warn "После установки может потребоваться перелогин. Запустите скрипт снова или: sudo docker compose ..."
|
||||||
|
SKIP_DOCKER_INSTALL=true
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
fail "Нужны Docker и плагин compose. Установите вручную и запустите скрипт снова."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
ok "Docker и Docker Compose найдены"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
info "=== Установка файлов ==="
|
||||||
|
|
||||||
|
if ! $USE_CURRENT_DIR; then
|
||||||
|
sudo mkdir -p "$INSTALL_DIR"
|
||||||
|
sudo chown "$USER:$USER" "$INSTALL_DIR"
|
||||||
|
if [[ -n "$REPO_URL" ]]; then
|
||||||
|
if [[ -d "$INSTALL_DIR/.git" ]]; then
|
||||||
|
info "Обновление репозитория..."
|
||||||
|
git -C "$INSTALL_DIR" pull --ff-only || warn "git pull не выполнен"
|
||||||
|
else
|
||||||
|
git clone "$REPO_URL" "$INSTALL_DIR"
|
||||||
|
fi
|
||||||
|
elif [[ ! -f "$INSTALL_DIR/docker-compose.yml" ]]; then
|
||||||
|
fail "В $INSTALL_DIR нет docker-compose.yml. Укажите URL репозитория или запустите скрипт из папки проекта."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$INSTALL_DIR"
|
||||||
|
|
||||||
|
if [[ -f .env ]]; then
|
||||||
|
if ! prompt_yn ".env уже существует. Перезаписать?" "n"; then
|
||||||
|
fail "Установка отменена. Отредактируйте .env вручную."
|
||||||
|
fi
|
||||||
|
cp .env ".env.bak.$(date +%s)" 2>/dev/null || true
|
||||||
|
warn "Старая копия: .env.bak.*"
|
||||||
|
fi
|
||||||
|
|
||||||
|
write_env ".env"
|
||||||
|
ok "Создан .env"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
info "=== Запуск контейнеров ==="
|
||||||
|
DC="docker compose"
|
||||||
|
if ! docker compose version >/dev/null 2>&1; then
|
||||||
|
DC="sudo docker compose"
|
||||||
|
fi
|
||||||
|
|
||||||
|
$DC pull db 2>/dev/null || true
|
||||||
|
$DC up -d --build
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
sleep 3
|
||||||
|
$DC ps
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
ok "Установка завершена!"
|
||||||
|
echo ""
|
||||||
|
echo " Каталог: $INSTALL_DIR"
|
||||||
|
echo " Логи бота: $DC logs -f bot"
|
||||||
|
echo " Логи БД: $DC logs -f db"
|
||||||
|
echo " Перезапуск: $DC up -d --build"
|
||||||
|
echo ""
|
||||||
|
echo " В Telegram (аккаунт админа $TELEGRAM_ADMIN_ID):"
|
||||||
|
echo " /start"
|
||||||
|
echo " /admin check"
|
||||||
|
echo " /admin squads"
|
||||||
|
echo " /admin user"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Reference in New Issue
Block a user