This commit is contained in:
2026-03-18 16:06:29 +07:00
parent fa98e42349
commit ab3d27a4f1
6 changed files with 436 additions and 20 deletions

View File

@@ -15,11 +15,12 @@ FRONTEND_PORT=80
# ============================
# DATABASE (PostgreSQL)
# ============================
# На VPS используй: openssl rand -base64 32
DB_HOST=postgres
DB_PORT=5432
DB_NAME=pg_admin
DB_USER=postgres
DB_PASSWORD=CHANGE_ME_SECURE_PASSWORD
DB_PASSWORD=CHANGE_ME_TO_STRONG_PASSWORD_GENERATED_WITH_OPENSSL
DB_HOST_DEV=localhost
# Connection pool

269
VPS-DEPLOYMENT.md Normal file
View File

@@ -0,0 +1,269 @@
# 🚀 Развертывание на VPS
Инструкция по запуску pg-admin на VPS (Ubuntu 24.04, другие версии похожи).
## Быстрый старт (3 шага)
### 1⃣ Подключись к VPS и клонируй репозиторий
```bash
ssh root@YOUR_VPS_IP
cd ~
git clone git@your-repo-url:your-org/pg-admin.git
cd pg-admin
```
### 2⃣ Генерируй безопасные пароли
```bash
bash scripts/generate-secrets.sh
```
Скопируй выходные значения.
### 3⃣ Создай и настрой .env
```bash
cp .env.example .env
nano .env
```
**Замени в .env:**
- `CHANGE_ME_TO_STRONG_PASSWORD` → Пароль из `generate-secrets.sh`
- `CHANGE_ME_TO_STRONG_RANDOM_SECRET` → JWT_SECRET из `generate-secrets.sh`
- `your-domain.com` → Твой реальный доменName (или IP на тест)
- `FRONTEND_API_URL``http://ТВЙ_ДОМЕН/api`
- `CORS_ORIGIN``http://ТВЙ_ДОМЕН` (пока HTTP)
Сохрани (Ctrl+X, Y, Enter в nano).
### 4⃣ Запусти инициализацию
```bash
bash scripts/setup-vps.sh
```
Скрипт установит Docker, настроит контейнеры и запустит приложение.
### 5⃣ Проверь статус
```bash
docker compose ps
docker compose logs -f
```
Приложение готово на `http://YOUR_VPS_IP:80` 🎉
---
## 📋 Требования
- **OS:** Ubuntu 20.04+ (или другой Linux с Docker)
- **RAM:** Минимум 2GB (рекомендуется 4GB)
- **CPU:** 2 ядра (рекомендуется 4+)
- **Диск:** 20GB свободного места (SSD лучше)
- **Порты:** 80/TCP открыты в файрволе
---
## 🔒 Безопасность на VPS
### ✅ Сделано в docker-compose.yml:
- ❌ БД не открыта наружу (только для контейнеров)
- ❌ Redis не открыт наружу (только для контейнеров)
- ❌ API не открыт напрямую (только через Nginx)
- ✅ Nginx проксирует запросы безопасно
- ✅ Ограничение ресурсов на контейнеры
- ✅ Health checks для отказоустойчивости
### ⚠️ Нужно сделать вручную:
#### 1. Настрой файрвол (UFW)
```bash
# Разреши только необходимые порты
sudo ufw enable
sudo ufw allow 22/tcp # SSH (для удаленного доступа)
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS (когда добавишь SSL)
sudo ufw status
```
#### 2. Добавь SSH ключи (вместо пароля)
```bash
# На локальной машине генерируй ключ если нет
ssh-keygen -t ed25519 -C "your-email@example.com"
# Скопируй публичный ключ на VPS
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@YOUR_VPS_IP
# Отключи вход по пароеи в sshd_config
sudo nano /etc/ssh/sshd_config
# Найди и измени на:
# PasswordAuthentication no
# PubkeyAuthentication yes
sudo systemctl reload ssh
```
#### 3. Установи Let's Encrypt SSL/HTTPS
Позже, когда будешь готов:
```bash
sudo apt-get install certbot python3-certbot-nginx
sudo certbot certonly --standalone -d your-domain.com -d www.your-domain.com
```
Затем обнови nginx.conf и docker-compose.yml для HTTPS.
#### 4. Настрой резервное копирование БД
```bash
# Создай backup скрипт
mkdir -p backups
cat > backups/backup-db.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="./backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
docker exec pg-admin-db pg_dump -U postgres pg_admin | gzip > $BACKUP_DIR/backup_$TIMESTAMP.sql.gz
echo "✅ Backup завершен: backup_$TIMESTAMP.sql.gz"
EOF
chmod +x backups/backup-db.sh
# Настрой cron для ежедневного backup (21:00 UTC)
crontab -e
# Добавь строку:
# 0 21 * * * cd /root/pg-admin && bash backups/backup-db.sh
```
#### 5. Мониторинг логов
```bash
# Просмотри логи всех контейнеров
docker compose logs -f
# Или конкретного контейнера
docker compose logs -f pg-admin-api
# Проверь дисковое пространство
df -h
# Проверь использование памяти
docker stats
```
---
## 🛠️ Частые команды
```bash
# Посмотри статус контейнеров
docker compose ps
# Перезагрузи приложение
docker compose restart
# Обнови код и перестрой
git pull origin main
docker compose up -d --build
# Посмотри логи
docker compose logs -f
# Останови все
docker compose down
# Полная переустановка (опасно - удалит данные!)
docker compose down -v
docker compose up -d --build
```
---
## 🔄 Pipeline для development → production
1. ✅ Делай коммиты в git
2. ✅ Пуш на main/master
3.На VPS: `git pull origin main`
4.На VPS: `docker compose up -d --build`
5. ✅ Проверь: `docker compose logs -f`
---
## 📊 Проверка здоровья приложения
```bash
# Проверь доступность
curl -I http://YOUR_VPS_IP:80/
# Посмотри статус контейнеров
docker compose ps
# Проверь память и CPU
docker stats
# Посмотри логи ошибок
docker compose logs | grep -i error
```
---
## 🚨 Troubleshooting
### Контейнер крашится при старте
```bash
# Посмотри логи
docker compose logs pg-admin-api
# Перестрой с чистого листа
docker compose down -v
docker compose up -d --build
```
### БД не подключается
```bash
# Проверь что БД запущена
docker compose ps
# Проверь логи БД
docker compose logs pg-admin-db
# Проверь переменные окружения
docker compose exec pg-admin-api env | grep DB
```
### Порт уже занят
```bash
# Найди процесс на порту 80
sudo lsof -i :80
# Убей процесс (замени PID)
sudo kill -9 PID
# Или смени порт в .env:
NGINX_PORT=8080
docker compose up -d
```
### No space left on device
```bash
# Очисти Docker образы
docker image prune -a
# Очисти volumes (ОСТОРОЖНО!)
docker volume prune
# Посмотри место на диске
df -h
```
---
## 📞 Поддержка
Если что-то не работает:
1. Проверь логи: `docker compose logs -f`
2. Проверь конфигурацию .env
3. Посмотри порты: `sudo netstat -tlnp | grep LISTEN`
4. Перезагрузи: `docker compose restart`
---
**Создано для pg-admin | VPS Deployment Guide v1.0**

View File

@@ -6,9 +6,8 @@ services:
POSTGRES_USER: ${DB_USER:-postgres}
POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
POSTGRES_DB: ${DB_NAME:-pg_admin}
POSTGRES_INITDB_ARGS: "--encoding=UTF8"
ports:
- "${DB_PORT:-5432}:5432"
POSTGRES_INITDB_ARGS: "--encoding=UTF8 -c shared_buffers=256MB -c max_connections=100"
# БД НЕ открыта наружу - только для контейнеров
volumes:
- postgres_data:/var/lib/postgresql/data
- ./docker/init-db.sql:/docker-entrypoint-initdb.d/init.sql
@@ -19,6 +18,15 @@ services:
retries: 5
networks:
- pg-admin-network
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
backend:
build:
@@ -37,8 +45,7 @@ services:
JWT_EXPIRE: ${JWT_EXPIRE:-7d}
MAX_CONNECTIONS: ${MAX_CONNECTIONS:-20}
LOG_LEVEL: ${LOG_LEVEL:-info}
ports:
- "${API_PORT:-3000}:${API_PORT:-3000}"
# API НЕ открыт наружу - только для nginx
depends_on:
postgres:
condition: service_healthy
@@ -48,6 +55,14 @@ services:
networks:
- pg-admin-network
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
frontend:
build:
@@ -57,8 +72,7 @@ services:
environment:
REACT_APP_API_URL: ${FRONTEND_API_URL:-http://localhost:3000/api}
REACT_APP_ENV: ${NODE_ENV:-production}
ports:
- "${FRONTEND_PORT:-80}:3000"
# Frontend НЕ открыт наружу - только для nginx
depends_on:
- backend
volumes:
@@ -66,14 +80,20 @@ services:
networks:
- pg-admin-network
restart: unless-stopped
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
redis:
image: redis:7-alpine
container_name: pg-admin-cache
ports:
- "${REDIS_PORT:-6379}:6379"
environment:
REDIS_PASSWORD: ${REDIS_PASSWORD:-change_me}
# Redis НЕ открыт наружу - только для контейнеров
command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
volumes:
- redis_data:/data
healthcheck:
@@ -84,12 +104,20 @@ services:
networks:
- pg-admin-network
restart: unless-stopped
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
nginx:
image: nginx:alpine
container_name: pg-admin-proxy
ports:
- "${NGINX_PORT:-8080}:80"
- "${NGINX_PORT:-80}:80"
volumes:
- ./docker/nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
@@ -98,6 +126,14 @@ services:
networks:
- pg-admin-network
restart: unless-stopped
deploy:
resources:
limits:
cpus: '0.5'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M
volumes:
postgres_data:

View File

@@ -6,22 +6,22 @@ WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies with production flag
RUN npm ci --only=production && npm ci
# Install dependencies
RUN npm install
# Copy source code
COPY . .
# Build production bundle with optimizations
RUN NODE_ENV=production npm run build 2>/dev/null || true
RUN NODE_ENV=production npm run build
# Production stage - optimize serving
# Production stage - minimal footprint
FROM node:18-alpine
WORKDIR /app
# Install serve with gzip compression support
RUN npm install -g serve
# Install serve for static file serving
RUN npm install -g serve@14
# Copy built app from builder
COPY --from=builder /app/build ./build
@@ -32,5 +32,5 @@ EXPOSE 3000
HEALTHCHECK --interval=10s --timeout=5s --retries=5 \
CMD wget --quiet --tries=1 --spider http://localhost:3000/ || exit 1
# Start server with compression and caching headers
# Start server with gzip compression
CMD ["serve", "-s", "build", "-l", "3000", "--gzip"]

View File

@@ -0,0 +1,31 @@
#!/bin/bash
# Генерирование безопасных паролей и секретов для production VPS
set -e
echo "🔐 Генерирование захищенных паролей для production..."
echo ""
# Генерируем паароль для БД
DB_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
echo "📊 DB_PASSWORD: $DB_PASSWORD"
# Генерируем JWT секрет
JWT_SECRET=$(openssl rand -base64 64 | tr -d "\n")
echo "🔑 JWT_SECRET: $JWT_SECRET"
# Генерируем Redis пароль
REDIS_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
echo "💾 REDIS_PASSWORD: $REDIS_PASSWORD"
echo ""
echo "========================================"
echo "📝 Скопируй эти значения в .env на VPS:"
echo "========================================"
echo ""
echo "DB_PASSWORD=$DB_PASSWORD"
echo "JWT_SECRET=$JWT_SECRET"
echo "REDIS_PASSWORD=$REDIS_PASSWORD"
echo ""
echo "⚠️ НЕ коммитьи эти значения в git!"
echo "⚠️ Храни .env в безопасном месте, не в репозитории!"

79
scripts/setup-vps.sh Normal file
View File

@@ -0,0 +1,79 @@
#!/bin/bash
# Инициализация Django приложения на VPS (Ubuntu 24.04)
# Запуск: bash scripts/setup-vps.sh
set -e
echo "🚀 Инициализация pg-admin на VPS..."
echo ""
# Проверяем что мы на VPS (Ubuntu)
if ! grep -qi ubuntu /etc/os-release; then
echo "⚠️ Это скрипт для Ubuntu. Попробуй вручную для другой OS."
fi
# 1. Обновляем систему
echo "📦 Обновление системы..."
sudo apt-get update
sudo apt-get upgrade -y
# 2. Устанавливаем Docker если его нет
if ! command -v docker &> /dev/null; then
echo "🐳 Установка Docker..."
sudo apt-get install -y docker.io docker-compose-plugin
sudo usermod -aG docker $USER
echo "⚠️ Нужен перелогин для работы docker без sudo. Выполни: newgrp docker"
else
echo "✅ Docker уже установлен"
fi
# 3. Создаем .env если его нет
if [ ! -f .env ]; then
echo "📝 Создание .env из .env.example..."
cp .env.example .env
echo ""
echo "⚠️ ВАЖНО! Отредактируй .env:"
echo " - Замени CHANGE_ME_TO_STRONG_PASSWORD на реальный пароль"
echo " - Замени CHANGE_ME_TO_STRONG_RANDOM_SECRET на реальный секрет"
echo " - Замени your-domain.com на твой домен"
echo " - Используй скрипт: bash scripts/generate-secrets.sh"
echo ""
echo "📝 Открой .env в редакторе и отредактируй значения:"
echo " nano .env"
exit 1
else
echo "✅ .env файл уже существует"
fi
# 4. Останавливаем старые контейнеры
echo "🛑 Остановка старых контейнеров..."
docker compose down -v --remove-orphans || true
# 5. Создаем необходимые папки
echo "📁 Создание папок..."
mkdir -p backend/logs
mkdir -p logs
# 6. Собираем и запускаем контейнеры
echo "🔨 Сборка и запуск контейнеров..."
docker compose up -d --build
# 7. Проверяем статус
echo ""
echo "✅ Инициализация завершена!"
echo ""
echo "📊 Статус контейнеров:"
docker compose ps
echo ""
echo "🌐 Приложение доступно по адресу:"
echo " http://YOUR_VPS_IP:80"
echo ""
echo "📝 Логи:"
echo " docker compose logs -f"
echo ""
echo "💡 Рекомендации:"
echo " 1. Настрой файрвол (UFW): sudo ufw allow 80,443/tcp"
echo " 2. Добавь SSL (Let's Encrypt) когда будешь готов"
echo " 3. Настрой резервное копирование БД"
echo " 4. Настрой мониторинг"