Compare commits
4 Commits
dp-old-version
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| a28d7a6954 | |||
| 009506f915 | |||
| e84d77f248 | |||
| f52e035d8a |
@@ -1,3 +1,4 @@
|
||||
checker/
|
||||
client/.env
|
||||
client/coverage/
|
||||
backups/
|
||||
|
||||
@@ -26,6 +26,8 @@ services:
|
||||
DB_USERNAME: ${POSTGRES_USER}
|
||||
DB_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
DB_NAME: ${POSTGRES_DB}
|
||||
DB_SYNCHRONIZE: "true"
|
||||
DB_MIGRATIONS_RUN: "false"
|
||||
JWT_SECRET: ${JWT_SECRET}
|
||||
ADMIN_LOGIN: ${ADMIN_LOGIN}
|
||||
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
|
||||
|
||||
@@ -469,6 +469,8 @@ services:
|
||||
DB_USERNAME: admin
|
||||
DB_PASSWORD: ${DB_PASS}
|
||||
DB_NAME: 3dp_manager
|
||||
DB_SYNCHRONIZE: "true"
|
||||
DB_MIGRATIONS_RUN: "false"
|
||||
JWT_SECRET: ${JWT_SECRET}
|
||||
ADMIN_LOGIN: ${ADMIN_USER}
|
||||
ADMIN_PASSWORD: ${ADMIN_PASS}
|
||||
@@ -580,6 +582,8 @@ services:
|
||||
DB_USERNAME: admin
|
||||
DB_PASSWORD: ${DB_PASS}
|
||||
DB_NAME: 3dp_manager
|
||||
DB_SYNCHRONIZE: "true"
|
||||
DB_MIGRATIONS_RUN: "false"
|
||||
JWT_SECRET: ${JWT_SECRET}
|
||||
ADMIN_LOGIN: ${ADMIN_USER}
|
||||
ADMIN_PASSWORD: ${ADMIN_PASS}
|
||||
|
||||
@@ -24,6 +24,9 @@ import { Tunnel } from './tunnels/entities/tunnel.entity';
|
||||
import { SessionModule } from './session/session.module';
|
||||
import { Node } from './nodes/entities/node.entity';
|
||||
import { NodesModule } from './nodes/nodes.module';
|
||||
import { AddNodesAndNodeRelations1765960000000 } from './migrations/1765960000000-add-nodes-and-node-relations';
|
||||
import { AddNodeIpFlagAndInboundLabels1770000000000 } from './migrations/1770000000000-add-node-ip-flag-and-inbound-labels';
|
||||
import { AddNodeDomain1770000000001 } from './migrations/1770000000001-add-node-domain';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -44,7 +47,13 @@ import { NodesModule } from './nodes/nodes.module';
|
||||
password: process.env.DB_PASSWORD,
|
||||
database: process.env.DB_NAME,
|
||||
entities: [Setting, Domain, Subscription, Inbound, Tunnel, Node],
|
||||
synchronize: true,
|
||||
migrations: [
|
||||
AddNodesAndNodeRelations1765960000000,
|
||||
AddNodeIpFlagAndInboundLabels1770000000000,
|
||||
AddNodeDomain1770000000001,
|
||||
],
|
||||
synchronize: process.env.DB_SYNCHRONIZE !== 'false',
|
||||
migrationsRun: process.env.DB_MIGRATIONS_RUN === 'true',
|
||||
}),
|
||||
SessionModule,
|
||||
XuiModule,
|
||||
|
||||
@@ -469,7 +469,6 @@ export class InboundBuilderService {
|
||||
content: '',
|
||||
dir: '',
|
||||
headers: {},
|
||||
insecure: true,
|
||||
rewriteHost: false,
|
||||
statusCode: 0,
|
||||
type: 'proxy',
|
||||
@@ -703,7 +702,6 @@ export class InboundBuilderService {
|
||||
const auth = settings.clients?.[0]?.auth || settings.clients?.[0]?.password || password;
|
||||
const finalmask = stream.finalmask?.udp?.[0];
|
||||
const params = new URLSearchParams();
|
||||
params.set('insecure', '1');
|
||||
params.set('security', 'tls');
|
||||
params.set('fp', 'chrome');
|
||||
params.set('alpn', 'h3');
|
||||
@@ -769,7 +767,6 @@ export class InboundBuilderService {
|
||||
}
|
||||
|
||||
const params = new URLSearchParams();
|
||||
params.set('insecure', '1');
|
||||
params.set('security', 'tls');
|
||||
params.set('fp', 'chrome');
|
||||
params.set('alpn', 'h3');
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddNodeDomain1770000000001 implements MigrationInterface {
|
||||
name = 'AddNodeDomain1770000000001';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE "node"
|
||||
ADD COLUMN IF NOT EXISTS "domain" character varying
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "node" DROP COLUMN IF EXISTS "domain"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -38,9 +38,8 @@ check_containers_running() {
|
||||
# Формат: NAME\tSTATUS (например: "3dp-postgres\tUp 2 days" или "3dp-postgres\tError")
|
||||
while IFS=$'\t' read -r container_name status; do
|
||||
if [ -n "$container_name" ] && [ -n "$status" ]; then
|
||||
# Проверяем, что статус содержит Up/running/healthy/restarting
|
||||
# Up, Up 2 days, Up Less than a second, (healthy), running, restarting
|
||||
if ! echo "$status" | grep -qiE "^up|running|healthy|restarting"; then
|
||||
# Restarting означает, что контейнер не смог стабильно запуститься.
|
||||
if ! echo "$status" | grep -qiE "^up|running|healthy"; then
|
||||
failed=1
|
||||
warn "Контейнер $container_name в статусе: $status"
|
||||
fi
|
||||
@@ -284,6 +283,52 @@ remove_hysteria_mount() {
|
||||
mv "$tmp_file" "$compose_file"
|
||||
}
|
||||
|
||||
ensure_safe_database_mode() {
|
||||
local compose_file="$1"
|
||||
[[ -f "$compose_file" ]] || return 0
|
||||
|
||||
local tmp_file
|
||||
tmp_file="$(mktemp)"
|
||||
|
||||
awk '
|
||||
/^[[:space:]]+DB_SYNCHRONIZE:/ { next }
|
||||
/^[[:space:]]+DB_MIGRATIONS_RUN:/ { next }
|
||||
{
|
||||
print $0
|
||||
if ($0 ~ /^[[:space:]]+DB_NAME:/) {
|
||||
match($0, /^[[:space:]]+/)
|
||||
indent = substr($0, RSTART, RLENGTH)
|
||||
print indent "DB_SYNCHRONIZE: \"false\""
|
||||
print indent "DB_MIGRATIONS_RUN: \"true\""
|
||||
}
|
||||
}
|
||||
' "$compose_file" > "$tmp_file"
|
||||
|
||||
mv "$tmp_file" "$compose_file"
|
||||
}
|
||||
|
||||
get_node_count() {
|
||||
docker exec 3dp-postgres sh -c '
|
||||
psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Atqc "
|
||||
SELECT CASE
|
||||
WHEN to_regclass('\''public.node'\'') IS NULL THEN 0
|
||||
ELSE (SELECT count(*) FROM node)
|
||||
END
|
||||
"
|
||||
' 2>/dev/null | tr -d '[:space:]'
|
||||
}
|
||||
|
||||
backup_database() {
|
||||
local backup_dir="$PROJECT_DIR/backups"
|
||||
BACKUP_FILE="$backup_dir/pre-update-$(date +%Y%m%d-%H%M%S).sql.gz"
|
||||
|
||||
mkdir -p "$backup_dir"
|
||||
log "Создание резервной копии базы данных: $BACKUP_FILE"
|
||||
docker exec 3dp-postgres sh -c \
|
||||
'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB"' | gzip > "$BACKUP_FILE"
|
||||
chmod 600 "$BACKUP_FILE"
|
||||
}
|
||||
|
||||
need_root() {
|
||||
[[ $EUID -eq 0 ]] || die "Запускать только от root"
|
||||
}
|
||||
@@ -314,7 +359,11 @@ log "Compose команда: ${COMPOSE_CMD[*]}"
|
||||
#################################
|
||||
# CHECK AND FIX CREDENTIALS
|
||||
#################################
|
||||
check_and_fix_credentials || true
|
||||
# Обновление не должно менять пароль уже инициализированной PostgreSQL:
|
||||
# изменение только .env делает существующую базу недоступной.
|
||||
if [[ ! -f ".env" ]]; then
|
||||
die "Файл .env не найден. Обновление остановлено, чтобы не потерять доступ к существующей базе данных"
|
||||
fi
|
||||
|
||||
#################################
|
||||
# FIX NGINX CONFIG
|
||||
@@ -322,6 +371,16 @@ check_and_fix_credentials || true
|
||||
ensure_nginx_api_timeouts "$PROJECT_DIR/client/nginx-client.conf"
|
||||
ensure_bus_location "$PROJECT_DIR/client/nginx-client.conf"
|
||||
remove_hysteria_mount "$PROJECT_DIR/docker-compose.yml"
|
||||
ensure_safe_database_mode "$PROJECT_DIR/docker-compose.yml"
|
||||
|
||||
#################################
|
||||
# BACKUP DATABASE
|
||||
#################################
|
||||
node_count_before="$(get_node_count)"
|
||||
[[ "$node_count_before" =~ ^[0-9]+$ ]] || die "Не удалось проверить количество нод перед обновлением"
|
||||
backup_database
|
||||
backup_file="$BACKUP_FILE"
|
||||
[[ -s "$backup_file" ]] || die "Не удалось создать резервную копию базы данных"
|
||||
|
||||
#################################
|
||||
# REBUILD BACKEND
|
||||
@@ -341,11 +400,18 @@ log "Пересоздание контейнеров..."
|
||||
|
||||
# Проверка: все ли контейнеры запустились
|
||||
if ! check_containers_running 60; then
|
||||
error "Не удалось запустить контейнеры. Логи:"
|
||||
warn "Не удалось запустить контейнеры. Логи:"
|
||||
"${COMPOSE_CMD[@]}" logs --tail=50
|
||||
die "Обновление прервано из-за ошибки запуска контейнеров"
|
||||
fi
|
||||
|
||||
node_count_after="$(get_node_count)"
|
||||
[[ "$node_count_after" =~ ^[0-9]+$ ]] || die "Не удалось проверить количество нод после обновления. Резервная копия: $backup_file"
|
||||
if (( node_count_after < node_count_before )); then
|
||||
"${COMPOSE_CMD[@]}" stop backend || true
|
||||
die "Количество нод уменьшилось с $node_count_before до $node_count_after. Обновление остановлено, резервная копия: $backup_file"
|
||||
fi
|
||||
|
||||
log "Очистка старых Docker-образов (освобождение места)..."
|
||||
docker image prune -f
|
||||
|
||||
|
||||
Reference in New Issue
Block a user