refactor: deploy model — all files under /opt/pulse-lets-go
Single prefix deployment: /opt/pulse-lets-go/ contains bin/, data/, web/, log/ — no more split across /usr/local/bin, /etc, /usr/local/share, /var/log. * Makefile: install → deploy target with PREFIX=/opt/pulse-lets-go * deploy/pulse-lets-go.service: all paths under /opt/pulse-lets-go, removed stale nats.service dependency * main.go: default dataDir = parent of exeDir (PREFIX/bin → PREFIX/data) * README: updated all paths, step 1 uses make deploy
This commit is contained in:
parent
2917f4de44
commit
64f9f20500
28
Makefile
28
Makefile
@ -4,9 +4,9 @@
|
|||||||
APP := pulse-lets-go
|
APP := pulse-lets-go
|
||||||
BINDIR := bin
|
BINDIR := bin
|
||||||
WEB_DIR := web
|
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 emulate-normal emulate-overload emulate-cpu-low emulate-fail-high \
|
||||||
emulate-node-down emulate-stale emulate-chaos build-emulator \
|
emulate-node-down emulate-stale emulate-chaos build-emulator \
|
||||||
build-siptest siptest-uas siptest-uac siptest-full
|
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
|
rm -rf $(BINDIR)/web && cp -r $(WEB_DIR)/build $(BINDIR)/web
|
||||||
CGO_ENABLED=0 go build -ldflags="-s -w" -o $(BINDIR)/$(APP) ./cmd/$(APP)
|
CGO_ENABLED=0 go build -ldflags="-s -w" -o $(BINDIR)/$(APP) ./cmd/$(APP)
|
||||||
|
|
||||||
# Установка: копирует бинарник и статику в /usr/local
|
# Деплой в PREFIX: бинарник + статика + data + log
|
||||||
install: build
|
deploy: build-prod
|
||||||
@echo "→ Установка в /usr/local"
|
@echo "→ Деплой в $(PREFIX)"
|
||||||
mkdir -p /usr/local/share/$(APP)/web
|
install -d $(PREFIX)/bin $(PREFIX)/data $(PREFIX)/web $(PREFIX)/log
|
||||||
cp -r $(WEB_DIR)/build /usr/local/share/$(APP)/web/
|
install -m 755 $(BINDIR)/$(APP) $(PREFIX)/bin/
|
||||||
cp $(BINDIR)/$(APP) /usr/local/bin/$(APP)
|
cp -r $(WEB_DIR)/build/. $(PREFIX)/web/
|
||||||
chmod +x /usr/local/bin/$(APP)
|
@echo "✓ Готово: $(PREFIX)"
|
||||||
@echo "✓ Установлен в /usr/local/bin/$(APP)"
|
@echo " $(PREFIX)/bin/$(APP)"
|
||||||
|
@echo " $(PREFIX)/web/ (SvelteKit статика)"
|
||||||
|
@echo " $(PREFIX)/data/ (config.json, trunks.json, users.json)"
|
||||||
|
@echo " $(PREFIX)/log/ (ASCII-лог метрик)"
|
||||||
|
|
||||||
# Установка systemd unit
|
# Установка systemd unit
|
||||||
install-systemd:
|
install-systemd:
|
||||||
@echo "→ Установка systemd unit"
|
install -m 644 deploy/$(APP).service /etc/systemd/system/
|
||||||
cp deploy/$(APP).service /etc/systemd/system/
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
@echo "✓ systemd unit установлен. Запуск: systemctl start $(APP)"
|
@echo "✓ systemd unit установлен. Запуск: sudo systemctl start $(APP)"
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# Эмулятор метрик
|
# Эмулятор метрик
|
||||||
|
|||||||
41
README.md
41
README.md
@ -423,7 +423,7 @@ end
|
|||||||
### systemd
|
### systemd
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make install # копирует бинарник + web-статику
|
make deploy # полный деплой в /opt/pulse-lets-go
|
||||||
make install-systemd # устанавливает systemd unit
|
make install-systemd # устанавливает systemd unit
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -436,16 +436,15 @@ After=network.target
|
|||||||
[Service]
|
[Service]
|
||||||
User=pulse
|
User=pulse
|
||||||
Group=pulse
|
Group=pulse
|
||||||
WorkingDirectory=/usr/local/share/pulse-lets-go
|
ExecStart=/opt/pulse-lets-go/bin/pulse-lets-go
|
||||||
Environment=PULSE_DATA_DIR=/etc/pulse-lets-go
|
WorkingDirectory=/opt/pulse-lets-go
|
||||||
ExecStart=/usr/local/bin/pulse-lets-go
|
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=5
|
RestartSec=5
|
||||||
NoNewPrivileges=true
|
NoNewPrivileges=true
|
||||||
PrivateTmp=true
|
PrivateTmp=true
|
||||||
ProtectSystem=strict
|
ProtectSystem=strict
|
||||||
ProtectHome=yes
|
ProtectHome=yes
|
||||||
ReadWritePaths=/etc/pulse-lets-go /var/log/pulse-lets-go
|
ReadWritePaths=/opt/pulse-lets-go/data /opt/pulse-lets-go/log
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
@ -454,14 +453,15 @@ WantedBy=multi-user.target
|
|||||||
### Структура директорий
|
### Структура директорий
|
||||||
|
|
||||||
```
|
```
|
||||||
/usr/local/share/pulse-lets-go/
|
/opt/pulse-lets-go/
|
||||||
├── web/build/ # SvelteKit статика
|
├── bin/pulse-lets-go # Бинарник
|
||||||
/etc/pulse-lets-go/
|
├── data/
|
||||||
├── config.json # Конфигурация
|
│ ├── config.json # Конфигурация
|
||||||
├── trunks.json # Транки
|
│ ├── trunks.json # Транки
|
||||||
├── users.json # Пользователи
|
│ └── users.json # Пользователи
|
||||||
/var/log/pulse-lets-go/
|
├── web/ # SvelteKit статика
|
||||||
└── metrics.YYYY-MM-DD.log # ASCII-лог метрик
|
└── log/
|
||||||
|
└── metrics.YYYY-MM-DD.log # ASCII-лог метрик
|
||||||
```
|
```
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
@ -497,13 +497,13 @@ fs_cli -x "load mod_curl"
|
|||||||
# <load module="mod_curl"/>
|
# <load module="mod_curl"/>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Порядок деплоя (7 шагов)
|
### Порядок деплоя (8 шагов)
|
||||||
|
|
||||||
**Шаг 1 — Скопировать бинарник и конфиги**
|
**Шаг 1 — Деплой на сервер**
|
||||||
```bash
|
```bash
|
||||||
make build-prod
|
make deploy
|
||||||
scp bin/pulse-lets-go admin@balancer.lan:/usr/local/bin/
|
scp -r /opt/pulse-lets-go admin@balancer.lan:/opt/
|
||||||
scp -r contrib/route.lua admin@balancer.lan:/tmp/
|
scp contrib/route.lua admin@balancer.lan:/tmp/
|
||||||
```
|
```
|
||||||
|
|
||||||
**Шаг 2 — NATS сервер** (если не установлен)
|
**Шаг 2 — NATS сервер** (если не установлен)
|
||||||
@ -562,11 +562,10 @@ curl -X POST .../api/trunks
|
|||||||
|
|
||||||
**Шаг 7 — Запуск pulse-lets-go**
|
**Шаг 7 — Запуск pulse-lets-go**
|
||||||
```bash
|
```bash
|
||||||
sudo mkdir -p /etc/pulse-lets-go /var/log/pulse-lets-go
|
# config.json создастся автоматически при первом запуске в /opt/pulse-lets-go/data/
|
||||||
# config.json создастся автоматически при первом запуске
|
|
||||||
# Добавить esl блок в config.json:
|
# Добавить esl блок в config.json:
|
||||||
# "esl": {"host": "127.0.0.1", "port": 8021, "password": "ClueCon"}
|
# "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 — Проверка**
|
**Шаг 8 — Проверка**
|
||||||
|
|||||||
@ -27,11 +27,12 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Определяем рабочую директорию
|
// Определяем рабочую директорию
|
||||||
|
// По умолчанию data/ — родительская папка от бинарника.
|
||||||
|
// Пример: /opt/pulse-lets-go/bin/pulse-lets-go → /opt/pulse-lets-go/data
|
||||||
exe, _ := os.Executable()
|
exe, _ := os.Executable()
|
||||||
exeDir := filepath.Dir(exe)
|
exeDir := filepath.Dir(exe)
|
||||||
dataDir := filepath.Join(exeDir, "data")
|
dataDir := filepath.Join(filepath.Dir(exeDir), "data")
|
||||||
|
|
||||||
// Разрешаем переопределение через переменную окружения
|
|
||||||
if envDir := os.Getenv("PULSE_DATA_DIR"); envDir != "" {
|
if envDir := os.Getenv("PULSE_DATA_DIR"); envDir != "" {
|
||||||
dataDir = envDir
|
dataDir = envDir
|
||||||
}
|
}
|
||||||
@ -235,13 +236,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// findWebDir ищет директорию со SvelteKit сборкой (web/build/).
|
// findWebDir ищет директорию со SvelteKit сборкой (web/build/).
|
||||||
// Пробует по порядку: переменная окружения, рядом с бинарником, в корне проекта, CWD.
|
// Пробует по порядку: PULSE_WEB_DIR, CWD, ../web/build, рядом с бинарником.
|
||||||
func findWebDir(exeDir string) string {
|
func findWebDir(exeDir string) string {
|
||||||
candidates := []string{
|
candidates := []string{
|
||||||
os.Getenv("PULSE_WEB_DIR"),
|
os.Getenv("PULSE_WEB_DIR"),
|
||||||
"web/build", // ./web/build (CWD — dev, systemd working dir)
|
"web/build", // ./web/build (CWD — dev, systemd working dir)
|
||||||
filepath.Join(filepath.Dir(exeDir), "web", "build"), // ../web/build (корень проекта, dev с bin/)
|
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 {
|
for _, d := range candidates {
|
||||||
if d == "" {
|
if d == "" {
|
||||||
|
|||||||
@ -1,16 +1,14 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=pulse-lets-go — Telephone Load Balancer
|
Description=pulse-lets-go — Telephone Load Balancer
|
||||||
Documentation=https://github.com/pulse-lets-go
|
Documentation=https://github.com/pulse-lets-go
|
||||||
After=network.target nats.service
|
After=network.target
|
||||||
Wants=nats.service
|
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
User=pulse
|
User=pulse
|
||||||
Group=pulse
|
Group=pulse
|
||||||
ExecStart=/usr/local/bin/pulse-lets-go
|
ExecStart=/opt/pulse-lets-go/bin/pulse-lets-go
|
||||||
WorkingDirectory=/usr/local/share/pulse-lets-go
|
WorkingDirectory=/opt/pulse-lets-go
|
||||||
Environment=PULSE_DATA_DIR=/etc/pulse-lets-go
|
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=5
|
RestartSec=5
|
||||||
|
|
||||||
@ -19,7 +17,7 @@ NoNewPrivileges=yes
|
|||||||
PrivateTmp=yes
|
PrivateTmp=yes
|
||||||
ProtectSystem=strict
|
ProtectSystem=strict
|
||||||
ProtectHome=yes
|
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
|
StandardOutput=journal
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user