Форк 3x-ui с поддержкой конфигурации через переменные окружения. Два варианта установки: Docker и нативная (systemd).
.env хранится в корне проекта рядом с docker-compose.yml.
cp .env.example .env
nano .env
sudo docker compose up -d --buildМеньше потребление памяти (~20-40 МБ vs ~60-100 МБ в Docker).
.env — общий для обоих вариантов (симлинк /etc/x-ui/.env → .env в проекте).
git clone https://github.com/Wasdalt/3x-ui.git && cd 3x-ui
cp .env.example .env # опционально: можно оставить пустым и дать скрипту сгенерировать локальные значения
nano .env # опционально: домен, порт, логирование, админ и т.д.
sudo bash native-install.shСкрипт автоматически:
- Устанавливает официальный 3x-ui, если он ещё не установлен.
- Делает бэкап БД перед установкой/обновлением и восстанавливает его при ошибке.
- Создаёт симлинк
/etc/x-ui/.env→.envв проекте. - Настраивает systemd на чтение
.envпри каждом старте. - Запускает
init-config.shперед каждым стартом панели. - Копирует fork-обвязку в
/usr/local/x-ui/и ставит единый CLIx-ui-fork. - Настраивает certbot + автообновление сертификатов через
certbot.timerили cron fallback.
Применение изменений .env:
nano .env # редактируешь в проекте
sudo systemctl restart x-ui # применяется автоматическиОбновление (upstream 3x-ui + fork-слой):
cd /path/to/3x-ui
sudo bash native-update.shЕдиный CLI для upstream + fork:
sudo x-ui-fork menu # открыть официальное меню автора
sudo x-ui-fork apply # применить fork-обвязку (.env/init-config/certbot)
sudo x-ui-fork update # обновить официальный 3x-ui и снова применить fork
sudo x-ui-fork restart # перезапустить systemd-сервис x-ui
x-ui-fork url # показать текущий URL панели из БД
x-ui-fork env # показать путь активного .envДля обновлений на сервере используйте
sudo x-ui-fork update, а не обычныйx-ui update: команда обновит официальный 3x-ui и затем заново применит fork-слой.
Удаление .env-дополнений (оставляет 3x-ui):
sudo bash native-uninstall.sh| Переменная | Описание | По умолчанию |
|---|---|---|
XUI_PORT |
Порт панели (HTTPS); если пусто и БД пустая, генерируется свободный порт 40000-59999 |
авто/2053 |
XUI_DOMAIN |
Домен панели для HTTPS. Если пусто, берётся только webDomain из БД |
— |
XUI_ADMIN_EMAIL |
Email для Let's Encrypt. Если пусто, используется регистрация certbot без email | — |
XUI_BASE_PATH |
Базовый путь панели; если пусто и БД пустая, генерируется скрытый путь | авто// |
XUI_ADMIN_USERNAME |
Логин администратора | — |
XUI_ADMIN_PASSWORD |
Пароль администратора | — |
| Переменная | Описание | По умолчанию |
|---|---|---|
XUI_SUB_PORT |
Порт подписок | 2096 |
XUI_SUB_PATH |
Путь подписок | /sub/ |
XUI_SUB_ENABLE |
Включить подписки | true |
| Переменная | Описание | По умолчанию |
|---|---|---|
XUI_XRAY_ACCESS_LOG |
Путь к access log | ./access.log |
XUI_XRAY_ERROR_LOG |
Путь к error log | — |
XUI_XRAY_LOG_LEVEL |
Уровень: debug/info/warning/error/none | info |
Важно: Для работы torrent/iplimit блокировщиков нужен уровень
infoилиdebug.
| Переменная | Описание | По умолчанию |
|---|---|---|
XUI_SESSION_TIMEOUT |
Таймаут сессии (минуты) | 60 |
XUI_SECRET_KEY |
Секретный ключ сессии | — |
XUI_ENABLE_FAIL2BAN |
Fail2Ban защита | true |
Полный список переменных см. в .env.example.
- При старте native-сервиса systemd читает
/etc/x-ui/.env. - Перед запуском панели
/usr/local/x-ui/fork-sync.shподтягивает свежий fork-слой из проекта, если он доступен. - Затем выполняется
/usr/local/x-ui/init-config.sh. - Скрипт применяет заданные переменные окружения в БД
/etc/x-ui/x-ui.db. x-ui-fork-db-apply.pathследит за изменением/etc/x-ui/x-ui.dbи запускает fork-применение после restore backup через панель/API.- Если
XUI_PORTпустой иwebPortв БД пустой, генерируется свободный порт и записывается только в БД. - Если
XUI_BASE_PATHпустой иwebBasePathв БД пустой, генерируется скрытый путь и записывается только в БД. - Если
XUI_DOMAINзадан и отличается отwebDomainиз БД, сначала пробуется домен из.env. - Если
XUI_DOMAINпустой, домен берётся только изwebDomainв БД. - Если домена нет ни в
.env, ни вwebDomain, SSL-сертификат не выпускается. - Если enabled inbound с TLS ссылается на отсутствующий сертификат, путь автоматически заменяется на сертификат
XUI_DOMAIN. - Если
xrayTemplateConfigне существует, он создаётся изconfig.json. - Применяются настройки логов Xray через
jq. - Панель стартует с применёнными настройками.
Значения из .env имеют приоритет над БД. Если переменная не задана или закомментирована, сохраняется значение из БД.
Сертификаты Let's Encrypt получаются автоматически, если есть домен в XUI_DOMAIN или webDomain в БД.
Домен для панели берётся только из:
XUI_DOMAIN -> webDomain
subDomain не используется как fallback для домена панели.
Сертификаты внутри inbound хранятся отдельно в inbounds.stream_settings. Fork автоматически исправляет только сломанные ссылки enabled inbound, когда certificateFile или keyFile не существуют на диске, а сертификат для XUI_DOMAIN уже есть. Чтобы отключить это поведение:
XUI_SYNC_INBOUND_CERTS=falseАвтоматика native-режима:
systemctl restart x-ui / reboot
-> fork-sync.sh
-> init-config.sh
restore backup через панель/API или изменение /etc/x-ui/x-ui.db
-> x-ui-fork-db-apply.path
-> fork-db-apply.sh
-> fork-sync.sh
-> init-config.sh
fork-db-apply.sh использует debounce 20 секунд, чтобы собственные записи init-config.sh в БД не запускали бесконечный цикл. Переопределить можно через:
XUI_FORK_DB_APPLY_DEBOUNCE=20В native-режиме устанавливается deploy-hook:
/etc/letsencrypt/renewal-hooks/deploy/restart-x-ui.sh
После успешного certbot renew hook отправляет SIGHUP процессу x-ui (in-process reload: ~1-2 сек вместо ~10 сек при полном restart). Xray и web-сервер перезагружаются, подхватывая новый сертификат. Если сервис не запущен — выполняется обычный systemctl restart как fallback.
Сертификат не перевыпускается повторно, если уже существует и действителен более 24 часов.
Автообновление работает через системный certbot.timer. Если timer недоступен, используется cron fallback с запуском certbot renew --quiet каждые 12 часов.
Docker-режим использует контейнер certbot, который запускает renew loop каждые 12 часов.
sudo ./ssl-setup.sh yourdomain.com [email protected]
sudo systemctl restart x-uihttps://yourdomain.com:<webPort><webBasePath>
Текущий URL можно вывести из БД:
x-ui-fork url# На локальном компьютере
ssh -N -L 8080:localhost:<webPort> user@server-ipЗатем: http://localhost:8080<webBasePath>
В .env:
XUI_ALLOW_HTTP=trueЗатем: http://server-ip:<webPort><webBasePath>
Если .env и БД пустые, native-установщик сгенерирует свободный webPort и скрытый webBasePath, а затем покажет URL в консоли.
Автоматическая блокировка, работает сразу.
XUI_ENABLE_FAIL2BAN=true
XUI_FAIL2BAN_BANTIME=30 # минутыОтправляет нарушения на ваш API.
XUI_ENABLE_FAIL2BAN=false
XUI_IP_WEBHOOK_ENABLE=true
XUI_IP_WEBHOOK_URL=https://your-api.com/webhookЗапуск с профилем:
sudo docker compose --profile iplimit up -dsudo docker compose --profile torrent up -dПодробнее см. xray-torrent-blocker/README.md.
| Действие | Команда |
|---|---|
Изменил .env |
sudo docker compose up -d --force-recreate |
| Изменил скрипты | sudo docker compose up -d --build |
| Полный перезапуск | sudo docker compose down && sudo docker compose up -d --build |
| Действие | Команда |
|---|---|
Изменил .env |
sudo systemctl restart x-ui |
| Обновил fork-скрипты | sudo x-ui-fork apply или sudo bash native-apply.sh |
| Обновить официальный 3x-ui + fork-слой | sudo bash native-update.sh или sudo x-ui-fork update |
| Показать URL панели | x-ui-fork url |
⚠️ Важно:
- Docker:
docker compose restartНЕ перечитывает.env— используйтеup -d --force-recreate- Значения из
.envимеют приоритет над значениями в БД- Если переменная не задана или закомментирована — сохраняется значение из БД
- Обычный
x-ui updateобновляет только авторскую часть; для сохранения fork-обвязки используйтеsudo x-ui-fork update
sudo docker logs 3xui_app -f # Логи
sudo docker exec 3xui_app sqlite3 /etc/x-ui/x-ui.db \
"SELECT key, value FROM settings;" # Настройки в БДsudo journalctl -u x-ui -f # Логи
sudo sqlite3 /etc/x-ui/x-ui.db \
"SELECT key, value FROM settings;" # Настройки в БД
sudo systemctl status x-ui # Статус
x-ui-fork url # URL панели
sudo bash native-update.sh # upstream update + fork overlay
sudo x-ui-fork update # то же самое через CLI# Проверить что занимает место
sudo docker ps -a # Контейнеры
sudo docker images # Образы
sudo docker volume ls # Тома
# Удалить неиспользуемые образы, контейнеры, тома
sudo docker system prune -a --volumes
# Удалить конкретный образ/том
sudo docker image rm ИМЯ_ОБРАЗА
sudo docker volume rm ИМЯ_ТОМА
⚠️ prune -a --volumesудаляет ВСЁ неиспользуемое — образы, остановленные контейнеры, анонимные тома. Работающие контейнеры и их тома не затрагиваются.