feat: Server deployment scripts + Database init
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled

NEW FILES:
- deploy.sh: One-command setup script (installs deps, creates venv, init db)
- start.sh: Quick start script (launches both backend & frontend)
- backend/scripts/init_db.py: Database initialization with schema + seed data

CHANGES:
- README: Added one-command setup instructions
- All scripts made executable

SERVER DEPLOYMENT:
1. git pull
2. chmod +x deploy.sh && ./deploy.sh
3. ./start.sh (or use PM2/Docker)

The init_db.py script:
- Creates all database tables
- Seeds basic TLD info (com, net, org, io, etc.)
- Works with both SQLite and PostgreSQL
This commit is contained in:
yves.gugger
2025-12-08 16:54:14 +01:00
parent 0de9648b49
commit 163c8d6ec7
4 changed files with 353 additions and 10 deletions

View File

@ -204,14 +204,34 @@ pounce/
- Node.js 18+
- npm or yarn
### 1. Clone Repository
### 🚀 One-Command Setup (Recommended)
```bash
# Clone repository
git clone https://git.6bit.ch/yvg/pounce.git
cd pounce
# Run deployment script (sets up everything)
chmod +x deploy.sh
./deploy.sh
# Start both services
chmod +x start.sh
./start.sh
```
That's it! Open http://localhost:3000
### Manual Setup
#### 1. Clone Repository
```bash
git clone https://git.6bit.ch/yvg/pounce.git
cd pounce
```
### 2. Backend Setup
#### 2. Backend Setup
```bash
cd backend
@ -229,13 +249,10 @@ cp env.example .env
# Generate secret key and add to .env
python -c "import secrets; print(f'SECRET_KEY={secrets.token_hex(32)}')"
```
# Edit .env with your SECRET_KEY
Edit `.env`:
```env
DATABASE_URL=sqlite+aiosqlite:///./domainwatch.db
SECRET_KEY=your-generated-secret-key
CORS_ORIGINS=http://localhost:3000,http://127.0.0.1:3000
# Initialize database
python scripts/init_db.py
```
Start backend:
@ -243,7 +260,7 @@ Start backend:
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
```
### 3. Frontend Setup
#### 3. Frontend Setup
```bash
cd frontend
@ -258,7 +275,7 @@ echo "NEXT_PUBLIC_API_URL=http://localhost:8000" > .env.local
npm run dev
```
### 4. Access Application
#### 4. Access Application
- **Frontend:** http://localhost:3000
- **Backend API:** http://localhost:8000

105
backend/scripts/init_db.py Executable file
View File

@ -0,0 +1,105 @@
#!/usr/bin/env python3
"""
Database initialization script.
Creates all tables and seeds initial data.
Usage:
python scripts/init_db.py
"""
import asyncio
import sys
import os
# Add parent directory to path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from app.database import engine, Base
# Import all models to register them with SQLAlchemy
from app.models import user, domain, tld_price, newsletter, portfolio, price_alert
async def init_database():
"""Initialize database tables."""
print("🔧 Initializing database...")
async with engine.begin() as conn:
# Create all tables
await conn.run_sync(Base.metadata.create_all)
print("✅ Database tables created successfully!")
print("")
print("Tables created:")
for table in Base.metadata.tables.keys():
print(f" - {table}")
async def seed_tld_data():
"""Seed initial TLD data."""
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import sessionmaker
from app.models.tld_price import TLDInfo
from sqlalchemy import select
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
# Basic TLD data
tld_data = [
{"tld": "com", "type": "generic", "description": "Commercial", "popularity_rank": 1},
{"tld": "net", "type": "generic", "description": "Network", "popularity_rank": 2},
{"tld": "org", "type": "generic", "description": "Organization", "popularity_rank": 3},
{"tld": "io", "type": "country", "description": "Tech startups", "popularity_rank": 4},
{"tld": "co", "type": "country", "description": "Company/Colombia", "popularity_rank": 5},
{"tld": "ai", "type": "country", "description": "AI/Anguilla", "popularity_rank": 6},
{"tld": "dev", "type": "generic", "description": "Developers", "popularity_rank": 7},
{"tld": "app", "type": "generic", "description": "Applications", "popularity_rank": 8},
{"tld": "xyz", "type": "generic", "description": "Generation XYZ", "popularity_rank": 9},
{"tld": "me", "type": "country", "description": "Personal/Montenegro", "popularity_rank": 10},
{"tld": "ch", "type": "country", "description": "Switzerland", "popularity_rank": 11},
{"tld": "de", "type": "country", "description": "Germany", "popularity_rank": 12},
{"tld": "uk", "type": "country", "description": "United Kingdom", "popularity_rank": 13},
{"tld": "fr", "type": "country", "description": "France", "popularity_rank": 14},
{"tld": "nl", "type": "country", "description": "Netherlands", "popularity_rank": 15},
]
async with AsyncSessionLocal() as session:
for data in tld_data:
# Check if exists
result = await session.execute(
select(TLDInfo).where(TLDInfo.tld == data["tld"])
)
existing = result.scalar_one_or_none()
if not existing:
tld_info = TLDInfo(**data)
session.add(tld_info)
print(f" Added: .{data['tld']}")
await session.commit()
print("✅ TLD data seeded!")
async def main():
"""Run all initialization steps."""
print("=" * 50)
print("POUNCE Database Initialization")
print("=" * 50)
print("")
await init_database()
print("")
print("🌱 Seeding initial data...")
await seed_tld_data()
print("")
print("=" * 50)
print("✅ Database initialization complete!")
print("=" * 50)
if __name__ == "__main__":
asyncio.run(main())

156
deploy.sh Executable file
View File

@ -0,0 +1,156 @@
#!/bin/bash
#
# POUNCE Deployment Script
# Usage: ./deploy.sh [dev|prod]
#
set -e
MODE=${1:-dev}
echo "================================================"
echo " POUNCE Deployment - Mode: $MODE"
echo "================================================"
echo ""
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Functions
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# ============================================
# 1. Check prerequisites
# ============================================
log_info "Checking prerequisites..."
if ! command -v python3 &> /dev/null; then
log_error "Python3 not found. Please install Python 3.10+"
exit 1
fi
if ! command -v node &> /dev/null; then
log_error "Node.js not found. Please install Node.js 18+"
exit 1
fi
if ! command -v npm &> /dev/null; then
log_error "npm not found. Please install npm"
exit 1
fi
log_info "Prerequisites OK!"
echo ""
# ============================================
# 2. Setup Backend
# ============================================
log_info "Setting up Backend..."
cd backend
# Create virtual environment if not exists
if [ ! -d "venv" ]; then
log_info "Creating Python virtual environment..."
python3 -m venv venv
fi
# Activate venv
source venv/bin/activate
# Install dependencies
log_info "Installing Python dependencies..."
pip install -q --upgrade pip
pip install -q -r requirements.txt
# Create .env if not exists
if [ ! -f ".env" ]; then
log_warn ".env file not found, copying from env.example..."
if [ -f "env.example" ]; then
cp env.example .env
log_warn "Please edit backend/.env with your settings!"
else
log_error "env.example not found!"
fi
fi
# Initialize database
log_info "Initializing database..."
python scripts/init_db.py
cd ..
log_info "Backend setup complete!"
echo ""
# ============================================
# 3. Setup Frontend
# ============================================
log_info "Setting up Frontend..."
cd frontend
# Install dependencies
log_info "Installing npm dependencies..."
npm install --silent
# Create .env.local if not exists
if [ ! -f ".env.local" ]; then
log_warn ".env.local not found, creating..."
echo "NEXT_PUBLIC_API_URL=http://localhost:8000" > .env.local
fi
# Build for production
if [ "$MODE" == "prod" ]; then
log_info "Building for production..."
npm run build
fi
cd ..
log_info "Frontend setup complete!"
echo ""
# ============================================
# 4. Start Services
# ============================================
if [ "$MODE" == "dev" ]; then
echo ""
echo "================================================"
echo " Development Setup Complete!"
echo "================================================"
echo ""
echo "To start the services:"
echo ""
echo " Backend (Terminal 1):"
echo " cd backend && source venv/bin/activate"
echo " uvicorn app.main:app --reload --host 0.0.0.0 --port 8000"
echo ""
echo " Frontend (Terminal 2):"
echo " cd frontend && npm run dev"
echo ""
echo "Then open: http://localhost:3000"
echo ""
else
echo ""
echo "================================================"
echo " Production Setup Complete!"
echo "================================================"
echo ""
echo "To start with PM2:"
echo ""
echo " # Backend"
echo " cd backend && source venv/bin/activate"
echo " pm2 start 'uvicorn app.main:app --host 0.0.0.0 --port 8000' --name pounce-backend"
echo ""
echo " # Frontend"
echo " cd frontend"
echo " pm2 start 'npm start' --name pounce-frontend"
echo ""
echo "Or use Docker:"
echo " docker-compose up -d"
echo ""
fi

65
start.sh Executable file
View File

@ -0,0 +1,65 @@
#!/bin/bash
#
# POUNCE Quick Start Script
# Starts both backend and frontend for development
#
set -e
echo "🐆 Starting POUNCE..."
echo ""
# Check if backend venv exists
if [ ! -d "backend/venv" ]; then
echo "❌ Backend not set up. Run ./deploy.sh first!"
exit 1
fi
# Kill any existing processes on our ports
echo "🔧 Cleaning up old processes..."
lsof -ti:8000 | xargs kill -9 2>/dev/null || true
lsof -ti:3000 | xargs kill -9 2>/dev/null || true
sleep 1
# Start Backend
echo "🚀 Starting Backend on port 8000..."
cd backend
source venv/bin/activate
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 &
BACKEND_PID=$!
cd ..
# Wait for backend to start
sleep 3
# Check if backend is running
if curl -s http://localhost:8000/health > /dev/null 2>&1; then
echo "✅ Backend running!"
else
echo "❌ Backend failed to start. Check logs."
exit 1
fi
# Start Frontend
echo "🚀 Starting Frontend on port 3000..."
cd frontend
npm run dev &
FRONTEND_PID=$!
cd ..
echo ""
echo "================================================"
echo " POUNCE is starting..."
echo "================================================"
echo ""
echo " Backend: http://localhost:8000"
echo " Frontend: http://localhost:3000"
echo " API Docs: http://localhost:8000/docs"
echo ""
echo " Press Ctrl+C to stop all services"
echo ""
# Wait for both processes
trap "kill $BACKEND_PID $FRONTEND_PID 2>/dev/null" EXIT
wait