#!/bin/bash # 馃惓 Script de gesti贸n completa de Docker para GPT Local # Construye, publica y despliega containers en Docker Hub set -e # Cargar variables de entorno if [ -f .env ]; then export $(cat .env | grep -v '^#' | xargs) fi # Colores para output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' print_status() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Variables DOCKER_USERNAME=${DOCKER_USERNAME:-"drtv"} IMAGE_NAME=${DOCKER_IMAGE_NAME:-"gpt-local"} VERSION=${1:-"latest"} FULL_IMAGE_NAME="$DOCKER_USERNAME/$IMAGE_NAME:$VERSION" # Funci贸n para construir imagen build_image() { print_status "Construyendo imagen Docker: $FULL_IMAGE_NAME" # Crear Dockerfile optimizado si no existe una versi贸n reciente create_optimized_dockerfile # Construir imagen if docker build -t "$FULL_IMAGE_NAME" -t "$DOCKER_USERNAME/$IMAGE_NAME:latest" .; then print_success "Imagen construida exitosamente: $FULL_IMAGE_NAME" # Mostrar tama帽o de la imagen local size=$(docker images --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}" | grep "$DOCKER_USERNAME/$IMAGE_NAME" | head -1 | awk '{print $2}') print_status "Tama帽o de la imagen: $size" else print_error "Error construyendo la imagen" return 1 fi } # Funci贸n para crear Dockerfile optimizado create_optimized_dockerfile() { cat > Dockerfile << 'EOF' # 馃 GPT Local - Optimized Docker Container FROM python:3.11-slim # Metadata LABEL maintainer="GPT Local Team" LABEL description="Sistema de chat GPT local con Hugging Face" LABEL version="1.0" # Configurar variables de entorno ENV PYTHONPATH=/app ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 ENV HF_HOME=/app/.cache/huggingface ENV TRANSFORMERS_CACHE=/app/.cache/huggingface ENV TORCH_HOME=/app/.cache/torch # Instalar dependencias del sistema RUN apt-get update && apt-get install -y \ curl \ git \ build-essential \ && rm -rf /var/lib/apt/lists/* \ && apt-get clean # Crear directorio de trabajo WORKDIR /app # Copiar archivos de requirements primero (para cache de Docker) COPY requirements.txt requirements-dev.txt ./ # Instalar dependencias Python RUN pip install --no-cache-dir --upgrade pip && \ pip install --no-cache-dir -r requirements.txt # Copiar c贸digo fuente COPY . . # Crear directorios necesarios RUN mkdir -p models models_cache logs .cache/huggingface .cache/torch # Configurar permisos RUN chmod +x *.py && \ chmod +x *.sh 2>/dev/null || true # Exponer puerto EXPOSE 7860 # Healthcheck HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:7860/ || exit 1 # Comando por defecto (interfaz web) CMD ["python3", "main.py"] EOF print_success "Dockerfile optimizado creado" } # Funci贸n para hacer push a Docker Hub push_image() { print_status "Subiendo imagen a Docker Hub: $FULL_IMAGE_NAME" # Verificar login if ! docker info | grep -q "Username: $DOCKER_USERNAME"; then print_error "No est谩s logueado en Docker Hub como $DOCKER_USERNAME" print_status "Ejecuta: echo 'tu_token' | docker login -u $DOCKER_USERNAME --password-stdin" return 1 fi # Push imagen con tag espec铆fico if docker push "$FULL_IMAGE_NAME"; then print_success "Imagen $FULL_IMAGE_NAME subida exitosamente" else print_error "Error subiendo imagen con tag $VERSION" return 1 fi # Push imagen latest if docker push "$DOCKER_USERNAME/$IMAGE_NAME:latest"; then print_success "Imagen latest subida exitosamente" print_status "Imagen disponible en: https://hub.docker.com/r/$DOCKER_USERNAME/$IMAGE_NAME" else print_error "Error subiendo imagen latest" return 1 fi } # Funci贸n para correr container localmente run_container() { local mode=${1:-"web"} print_status "Ejecutando container en modo: $mode" # Parar container si ya est谩 corriendo docker stop "$DOCKER_USERNAME-$IMAGE_NAME" 2>/dev/null || true docker rm "$DOCKER_USERNAME-$IMAGE_NAME" 2>/dev/null || true case $mode in "web") docker run -d \ --name "$DOCKER_USERNAME-$IMAGE_NAME" \ -p 7860:7860 \ -v "$(pwd)/models_cache:/app/models_cache" \ -v "$(pwd)/logs:/app/logs" \ -e HUGGINGFACE_TOKEN="$HUGGINGFACE_TOKEN" \ -e DEFAULT_MODEL="$DEFAULT_MODEL" \ -e DEVICE="$DEVICE" \ "$FULL_IMAGE_NAME" print_success "Container web ejecut谩ndose en: http://localhost:7860" ;; "terminal") docker run -it \ --name "$DOCKER_USERNAME-$IMAGE_NAME-terminal" \ -v "$(pwd)/models_cache:/app/models_cache" \ -e HUGGINGFACE_TOKEN="$HUGGINGFACE_TOKEN" \ -e DEFAULT_MODEL="$DEFAULT_MODEL" \ -e DEVICE="$DEVICE" \ "$FULL_IMAGE_NAME" \ python3 chat_terminal.py ;; "dev") docker run -it \ --name "$DOCKER_USERNAME-$IMAGE_NAME-dev" \ -p 7860:7860 \ -v "$(pwd):/app" \ -e HUGGINGFACE_TOKEN="$HUGGINGFACE_TOKEN" \ -e DEFAULT_MODEL="$DEFAULT_MODEL" \ -e DEVICE="$DEVICE" \ "$FULL_IMAGE_NAME" \ bash ;; esac } # Funci贸n para correr con docker-compose run_compose() { local service=${1:-"gpt-local-web"} print_status "Ejecutando con docker-compose: $service" # Construir y ejecutar if docker-compose up --build -d "$service"; then print_success "Servicio $service ejecut谩ndose" if [ "$service" = "gpt-local-web" ]; then print_status "Interfaz web disponible en: http://localhost:7860" fi # Mostrar logs print_status "Logs del servicio (Ctrl+C para salir):" docker-compose logs -f "$service" else print_error "Error ejecutando docker-compose" return 1 fi } # Funci贸n para limpiar im谩genes y containers cleanup() { print_status "Limpiando containers e im谩genes..." # Parar todos los containers del proyecto docker stop $(docker ps -q --filter "name=$DOCKER_USERNAME-$IMAGE_NAME") 2>/dev/null || true # Remover containers docker rm $(docker ps -aq --filter "name=$DOCKER_USERNAME-$IMAGE_NAME") 2>/dev/null || true # Remover im谩genes no utilizadas docker image prune -f print_success "Limpieza completada" } # Funci贸n para mostrar estado status() { print_status "Estado de containers GPT Local:" # Containers corriendo echo "Containers corriendo:" docker ps --filter "name=$DOCKER_USERNAME-$IMAGE_NAME" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" echo "" echo "Im谩genes disponibles:" docker images --filter "reference=$DOCKER_USERNAME/$IMAGE_NAME" --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedSince}}" echo "" echo "Uso de espacio Docker:" docker system df } # Funci贸n principal main() { local action=${1:-"help"} local param=${2:-"latest"} case $action in "build") build_image ;; "push") build_image push_image ;; "run") run_container "$param" ;; "compose") run_compose "$param" ;; "cleanup") cleanup ;; "status") status ;; "full") build_image push_image print_status "馃帀 Pipeline completo ejecutado!" ;; *) echo "馃惓 Script de gesti贸n Docker para GPT Local" echo "" echo "Uso: $0 [comando] [par谩metro]" echo "" echo "Comandos:" echo " build - Construir imagen Docker" echo " push - Construir y subir a Docker Hub" echo " run [web|terminal|dev] - Ejecutar container" echo " compose [service] - Ejecutar con docker-compose" echo " cleanup - Limpiar containers e im谩genes" echo " status - Mostrar estado actual" echo " full - Pipeline completo (build + push)" echo "" echo "Ejemplos:" echo " $0 build # Construir imagen" echo " $0 push # Construir y subir" echo " $0 run web # Ejecutar interfaz web" echo " $0 run terminal # Ejecutar chat terminal" echo " $0 compose # Ejecutar con docker-compose" echo "" echo "Variables de entorno (archivo .env):" echo " DOCKER_USERNAME=$DOCKER_USERNAME" echo " DOCKER_IMAGE_NAME=$IMAGE_NAME" echo " HUGGINGFACE_TOKEN=***" ;; esac } # Ejecutar script main "$@"