diff --git a/Makefile b/Makefile index 55d969f..b1de363 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ # pulse-lets-go — Telephone Load Balancer # Сборка Go backend + SvelteKit фронта в единый бинарник. -APP := pulse-lets-go -BINDIR := bin +APP := pulse-lets-go +BINDIR := bin WEB_DIR := web -DATA_DIR := data +PREFIX := /opt/pulse-lets-go -.PHONY: all build build-go build-web clean run test install \ +.PHONY: all build build-go build-web clean run test deploy \ emulate emulate-normal emulate-overload emulate-cpu-low emulate-fail-high \ emulate-node-down emulate-stale emulate-chaos build-emulator \ build-siptest siptest-uas siptest-uac siptest-full @@ -50,21 +50,23 @@ build-prod: rm -rf $(BINDIR)/web && cp -r $(WEB_DIR)/build $(BINDIR)/web CGO_ENABLED=0 go build -ldflags="-s -w" -o $(BINDIR)/$(APP) ./cmd/$(APP) -# Установка: копирует бинарник и статику в /usr/local -install: build - @echo "→ Установка в /usr/local" - mkdir -p /usr/local/share/$(APP)/web - cp -r $(WEB_DIR)/build /usr/local/share/$(APP)/web/ - cp $(BINDIR)/$(APP) /usr/local/bin/$(APP) - chmod +x /usr/local/bin/$(APP) - @echo "✓ Установлен в /usr/local/bin/$(APP)" +# Деплой в PREFIX: бинарник + статика + data + log +deploy: build-prod + @echo "→ Деплой в $(PREFIX)" + install -d $(PREFIX)/bin $(PREFIX)/data $(PREFIX)/web $(PREFIX)/log + install -m 755 $(BINDIR)/$(APP) $(PREFIX)/bin/ + cp -r $(WEB_DIR)/build/. $(PREFIX)/web/ + @echo "✓ Готово: $(PREFIX)" + @echo " $(PREFIX)/bin/$(APP)" + @echo " $(PREFIX)/web/ (SvelteKit статика)" + @echo " $(PREFIX)/data/ (config.json, trunks.json, users.json)" + @echo " $(PREFIX)/log/ (ASCII-лог метрик)" # Установка systemd unit install-systemd: - @echo "→ Установка systemd unit" - cp deploy/$(APP).service /etc/systemd/system/ + install -m 644 deploy/$(APP).service /etc/systemd/system/ systemctl daemon-reload - @echo "✓ systemd unit установлен. Запуск: systemctl start $(APP)" + @echo "✓ systemd unit установлен. Запуск: sudo systemctl start $(APP)" # ============================================================ # Эмулятор метрик diff --git a/README.md b/README.md index 47738fe..de5cdd5 100644 --- a/README.md +++ b/README.md @@ -423,7 +423,7 @@ end ### systemd ```bash -make install # копирует бинарник + web-статику +make deploy # полный деплой в /opt/pulse-lets-go make install-systemd # устанавливает systemd unit ``` @@ -436,16 +436,15 @@ After=network.target [Service] User=pulse Group=pulse -WorkingDirectory=/usr/local/share/pulse-lets-go -Environment=PULSE_DATA_DIR=/etc/pulse-lets-go -ExecStart=/usr/local/bin/pulse-lets-go +ExecStart=/opt/pulse-lets-go/bin/pulse-lets-go +WorkingDirectory=/opt/pulse-lets-go Restart=always RestartSec=5 NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=yes -ReadWritePaths=/etc/pulse-lets-go /var/log/pulse-lets-go +ReadWritePaths=/opt/pulse-lets-go/data /opt/pulse-lets-go/log [Install] WantedBy=multi-user.target @@ -454,14 +453,15 @@ WantedBy=multi-user.target ### Структура директорий ``` -/usr/local/share/pulse-lets-go/ -├── web/build/ # SvelteKit статика -/etc/pulse-lets-go/ -├── config.json # Конфигурация -├── trunks.json # Транки -├── users.json # Пользователи -/var/log/pulse-lets-go/ -└── metrics.YYYY-MM-DD.log # ASCII-лог метрик +/opt/pulse-lets-go/ +├── bin/pulse-lets-go # Бинарник +├── data/ +│ ├── config.json # Конфигурация +│ ├── trunks.json # Транки +│ └── users.json # Пользователи +├── web/ # SvelteKit статика +└── log/ + └── metrics.YYYY-MM-DD.log # ASCII-лог метрик ``` ### Security @@ -497,13 +497,13 @@ fs_cli -x "load mod_curl" # ``` -### Порядок деплоя (7 шагов) +### Порядок деплоя (8 шагов) -**Шаг 1 — Скопировать бинарник и конфиги** +**Шаг 1 — Деплой на сервер** ```bash -make build-prod -scp bin/pulse-lets-go admin@balancer.lan:/usr/local/bin/ -scp -r contrib/route.lua admin@balancer.lan:/tmp/ +make deploy +scp -r /opt/pulse-lets-go admin@balancer.lan:/opt/ +scp contrib/route.lua admin@balancer.lan:/tmp/ ``` **Шаг 2 — NATS сервер** (если не установлен) @@ -562,11 +562,10 @@ curl -X POST .../api/trunks **Шаг 7 — Запуск pulse-lets-go** ```bash -sudo mkdir -p /etc/pulse-lets-go /var/log/pulse-lets-go -# config.json создастся автоматически при первом запуске +# config.json создастся автоматически при первом запуске в /opt/pulse-lets-go/data/ # Добавить esl блок в config.json: # "esl": {"host": "127.0.0.1", "port": 8021, "password": "ClueCon"} -PULSE_DATA_DIR=/etc/pulse-lets-go ./pulse-lets-go +/opt/pulse-lets-go/bin/pulse-lets-go ``` **Шаг 8 — Проверка** diff --git a/cmd/pulse-lets-go/main.go b/cmd/pulse-lets-go/main.go index 7af8535..6bdd82b 100644 --- a/cmd/pulse-lets-go/main.go +++ b/cmd/pulse-lets-go/main.go @@ -27,11 +27,12 @@ import ( func main() { // Определяем рабочую директорию + // По умолчанию data/ — родительская папка от бинарника. + // Пример: /opt/pulse-lets-go/bin/pulse-lets-go → /opt/pulse-lets-go/data exe, _ := os.Executable() exeDir := filepath.Dir(exe) - dataDir := filepath.Join(exeDir, "data") + dataDir := filepath.Join(filepath.Dir(exeDir), "data") - // Разрешаем переопределение через переменную окружения if envDir := os.Getenv("PULSE_DATA_DIR"); envDir != "" { dataDir = envDir } @@ -235,13 +236,13 @@ func main() { } // findWebDir ищет директорию со SvelteKit сборкой (web/build/). -// Пробует по порядку: переменная окружения, рядом с бинарником, в корне проекта, CWD. +// Пробует по порядку: PULSE_WEB_DIR, CWD, ../web/build, рядом с бинарником. func findWebDir(exeDir string) string { candidates := []string{ os.Getenv("PULSE_WEB_DIR"), "web/build", // ./web/build (CWD — dev, systemd working dir) filepath.Join(filepath.Dir(exeDir), "web", "build"), // ../web/build (корень проекта, dev с bin/) - filepath.Join(exeDir, "web", "build"), // рядом с бинарником (production install) + filepath.Join(exeDir, "web", "build"), // рядом с бинарником (production install, make deploy) } for _, d := range candidates { if d == "" { diff --git a/deploy/pulse-lets-go.service b/deploy/pulse-lets-go.service index 35fd6c5..f86cc8e 100644 --- a/deploy/pulse-lets-go.service +++ b/deploy/pulse-lets-go.service @@ -1,16 +1,14 @@ [Unit] Description=pulse-lets-go — Telephone Load Balancer Documentation=https://github.com/pulse-lets-go -After=network.target nats.service -Wants=nats.service +After=network.target [Service] Type=simple User=pulse Group=pulse -ExecStart=/usr/local/bin/pulse-lets-go -WorkingDirectory=/usr/local/share/pulse-lets-go -Environment=PULSE_DATA_DIR=/etc/pulse-lets-go +ExecStart=/opt/pulse-lets-go/bin/pulse-lets-go +WorkingDirectory=/opt/pulse-lets-go Restart=always RestartSec=5 @@ -19,7 +17,7 @@ NoNewPrivileges=yes PrivateTmp=yes ProtectSystem=strict ProtectHome=yes -ReadWritePaths=/etc/pulse-lets-go /var/log/pulse-lets-go +ReadWritePaths=/opt/pulse-lets-go/data /opt/pulse-lets-go/log # Логирование StandardOutput=journal