scense / entrypoint.sh
Charan5775's picture
Update entrypoint.sh
6343933 verified
#!/bin/bash
set -e
# Environment variables
export UVICORN_PORT=8000
export NEXT_PORT=3000
export HF_SPACES_PORT=7860
export POSTGRES_USER=postgres
export POSTGRES_PASSWORD=postgres
export POSTGRES_DB=surfsense
export REDIS_PORT=6379
echo "πŸš€ Starting SurfSense all-in-one container..."
# Function to wait for a service to be ready
wait_for_service() {
local host=$1
local port=$2
local service=$3
echo "⏳ Waiting for $service to be ready on $host:$port..."
while ! nc -z -w 1 $host $port 2>/dev/null; do
sleep 1
done
echo "βœ… $service is ready!"
}
# Check if using external database
if [ -n "$EXTERNAL_DATABASE_URL" ]; then
echo "🌍 Using external database, skipping local PostgreSQL setup..."
else
# Initialize PostgreSQL data directory if it doesn't exist
if [ ! -d "/var/lib/postgresql/14/main" ]; then
echo "πŸ’Ύ Initializing PostgreSQL database..."
mkdir -p /var/lib/postgresql/14/main
chown -R postgres:postgres /var/lib/postgresql/14/main
chmod 0700 /var/lib/postgresql/14/main
# Initialize database cluster
sudo -u postgres /usr/lib/postgresql/14/bin/initdb -D /var/lib/postgresql/14/main
# Configure PostgreSQL to accept connections
echo "listen_addresses = '*'" >> /var/lib/postgresql/14/main/postgresql.conf
echo "host all all 0.0.0.0/0 trust" >> /var/lib/postgresql/14/main/pg_hba.conf
fi
# Start PostgreSQL in background
echo "πŸ”„ Starting PostgreSQL server..."
sudo -u postgres /usr/lib/postgresql/14/bin/postgres -D /var/lib/postgresql/14/main &
POSTGRES_PID=$!
export POSTGRES_PID
# Wait for PostgreSQL to be ready
wait_for_service localhost 5432 "PostgreSQL"
# Create database and enable pgvector extension if needed
echo "πŸ”§ Setting up database..."
sudo -u postgres psql -c "SELECT 1 FROM pg_database WHERE datname = '$POSTGRES_DB'" | grep -q 1 || \
sudo -u postgres psql -c "CREATE DATABASE $POSTGRES_DB"
sudo -u postgres psql -d $POSTGRES_DB -c "CREATE EXTENSION IF NOT EXISTS vector;"
fi
# Start Redis in background
echo "πŸ”„ Starting Redis server..."
redis-server --port $REDIS_PORT --bind 0.0.0.0 --protected-mode no --dir /var/lib/redis &
REDIS_PID=$!
export REDIS_PID
# Wait for Redis to be ready
wait_for_service localhost $REDIS_PORT "Redis"
# Set up backend environment variables
echo "βš™οΈ Configuring backend environment..."
cd /app/surfsense_backend
# Determine DATABASE_URL
if [ -n "$EXTERNAL_DATABASE_URL" ]; then
echo "🌍 Using external database URL..."
DATABASE_URL="$EXTERNAL_DATABASE_URL"
else
echo "🏠 Using local PostgreSQL URL..."
DATABASE_URL="postgresql+asyncpg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}"
fi
# Create .env file with all required variables
cat > .env << EOF
DATABASE_URL=${DATABASE_URL}
SECRET_KEY=$(openssl rand -hex 32)
NEXT_FRONTEND_URL=https://charan5775-scense.hf.space
AUTH_TYPE=LOCAL
EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2
RERANKERS_MODEL_NAME=ms-marco-MiniLM-L-12-v2
RERANKERS_MODEL_TYPE=flashrank
TTS_SERVICE=local/kokoro
STT_SERVICE=local/base
ETL_SERVICE=DOCLING
CELERY_BROKER_URL=redis://localhost:${REDIS_PORT}/0
CELERY_RESULT_BACKEND=redis://localhost:${REDIS_PORT}/0
REGISTRATION_ENABLED=TRUE
UVICORN_HOST=0.0.0.0
UVICORN_PORT=${UVICORN_PORT}
EOF
# Set up frontend environment variables
echo "βš™οΈ Configuring frontend environment..."
cd /app/surfsense_web
cat > .env << EOF
NEXT_PUBLIC_FASTAPI_BACKEND_URL=https://charan5775-scense.hf.space/pi
NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE=LOCAL
NEXT_PUBLIC_ETL_SERVICE=DOCLING
EOF
# Start backend in background
echo "πŸ”„ Starting backend server..."
cd /app/surfsense_backend
. .venv/bin/activate
#uvicorn main:app --host 0.0.0.0 --port $UVICORN_PORT &
uv run main.py &
BACKEND_PID=$!
export BACKEND_PID
# Wait for backend to be ready
wait_for_service localhost $UVICORN_PORT "Backend API"
# Start Celery worker in background
echo "πŸ”„ Starting Celery worker..."
celery -A celery_worker.celery_app worker --loglevel=info --concurrency=1 --pool=solo &
CELERY_WORKER_PID=$!
export CELERY_WORKER_PID
# Start Celery beat in background
echo "πŸ”„ Starting Celery beat..."
celery -A celery_worker.celery_app beat --loglevel=info &
CELERY_BEAT_PID=$!
export CELERY_BEAT_PID
# Start frontend in background
echo "πŸ”„ Starting frontend server..."
cd /app/surfsense_web
pnpm run build && pnpm run start &
#pnpm run dev &
FRONTEND_PID=$!
export FRONTEND_PID
# Wait for frontend to be ready
wait_for_service localhost $NEXT_PORT "Frontend"
# Configure Nginx dynamically
echo "βš™οΈ Configuring Nginx reverse proxy..."
cat > /etc/nginx/sites-available/surfsense << EOF
server {
listen ${HF_SPACES_PORT};
server_name localhost;
# Backend API routes
location /pi/ {
proxy_pass http://localhost:${UVICORN_PORT}/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
# Frontend routes
location / {
proxy_pass http://localhost:${NEXT_PORT}/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
# Health check endpoint for Hugging Face
location /health {
return 200 'OK';
add_header Content-Type text/plain;
}
}
EOF
# Enable the Nginx configuration
rm -f /etc/nginx/sites-enabled/default
ln -sf /etc/nginx/sites-available/surfsense /etc/nginx/sites-enabled/
# Test Nginx configuration
echo "πŸ” Testing Nginx configuration..."
nginx -t
# Start Nginx in foreground (this will keep the container running)
echo "πŸš€ Starting Nginx reverse proxy on port ${HF_SPACES_PORT}..."
echo "πŸŽ‰ SurfSense is ready! Access it at http://localhost:${HF_SPACES_PORT}"
# Set up cleanup function for graceful shutdown
cleanup() {
echo "πŸ›‘ Shutting down services..."
# Stop services in reverse order of startup
if [ ! -z "$NGINX_PID" ]; then
echo "Stopping Nginx..."
kill -TERM $NGINX_PID 2>/dev/null || true
fi
if [ ! -z "$FRONTEND_PID" ]; then
echo "Stopping frontend..."
kill -TERM $FRONTEND_PID 2>/dev/null || true
fi
if [ ! -z "$CELERY_BEAT_PID" ]; then
echo "Stopping Celery beat..."
kill -TERM $CELERY_BEAT_PID 2>/dev/null || true
fi
if [ ! -z "$CELERY_WORKER_PID" ]; then
echo "Stopping Celery worker..."
kill -TERM $CELERY_WORKER_PID 2>/dev/null || true
fi
if [ ! -z "$BACKEND_PID" ]; then
echo "Stopping backend..."
kill -TERM $BACKEND_PID 2>/dev/null || true
fi
if [ ! -z "$REDIS_PID" ]; then
echo "Stopping Redis..."
kill -TERM $REDIS_PID 2>/dev/null || true
fi
if [ ! -z "$POSTGRES_PID" ]; then
echo "Stopping PostgreSQL..."
sudo -u postgres /usr/lib/postgresql/14/bin/pg_ctl -D /var/lib/postgresql/14/main stop -m fast
fi
echo "βœ… All services stopped"
exit 0
}
# Trap termination signals
trap cleanup TERM INT
# Start Nginx in the foreground (this keeps the container running)
nginx -g "daemon off;"
# This line should never be reached, but just in case
wait