From 6cebc7659991597c69530f36b5e105dde762e5e2 Mon Sep 17 00:00:00 2001 From: AI Bot Date: Mon, 7 Sep 2026 16:09:04 -0500 Subject: [PATCH] =?UTF-8?q?refactor:=20eliminar=20despliegues=20independie?= =?UTF-8?q?ntes=20fuera=20de=20Coolify=20y=20respetar=20gesti=C3=B3n=20exc?= =?UTF-8?q?lusiva=20de=20Coolify?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 2 +- deploy_dripzone_vps.py | 120 +++-------------------------------------- 2 files changed, 7 insertions(+), 115 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 5f22007..1d809b9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,4 +3,4 @@ - **Autonomía Total**: Ejecuta todas las acciones, ediciones de archivos, comandos de terminal, pruebas y diagnósticos de forma proactiva e inmediata sin solicitar confirmación previa ni esperar aprobaciones intermedias. - **Flujo Completo**: Cuando se solicite un cambio o se reporte un problema, investiga, modifica el código, compila, prueba y entrega la solución terminada. - **Sin Bloqueos**: No te detengas a pedir permisos antes de ejecutar herramientas, llamadas a bases de datos o scripts de verificación. -- **Despliegue y Envío de APK Continuo**: Tras cualquier cambio o ajuste en el código, SIEMPRE compilar el APK Android, desplegar en el servidor VPS de producción y enviar automáticamente el archivo APK actualizado al WhatsApp de Carlos (+57 316 745 5877) sin esperar confirmación. +- **Despliegue y Envío de APK Continuo**: Tras cualquier cambio o ajuste en el código, compilar el APK Android y enviar automáticamente el archivo APK actualizado al WhatsApp de Carlos (+57 316 745 5877) sin esperar confirmación. Los despliegues en el servidor VPS de producción se administran exclusivamente a través de Coolify por parte de Carlos; NUNCA montar, compilar ni levantar contenedores Docker independientes o paralelos fuera de Coolify para evitar duplicidad de instancias y conflictos de enrutamiento en Traefik. diff --git a/deploy_dripzone_vps.py b/deploy_dripzone_vps.py index 43e4547..7860c16 100644 --- a/deploy_dripzone_vps.py +++ b/deploy_dripzone_vps.py @@ -1,127 +1,19 @@ -import paramiko -import tarfile import os import sys import io +import urllib.request +import json # Force UTF-8 stdout on Windows if sys.platform == 'win32': sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace') -HOST = "161.97.93.156" -USER = "carlos" -PASSWORD = "Innova1978+*?" -LOCAL_DIR = r"c:\Users\Carlos\dev\almeira-web\dripzone-app" -ARCHIVE_NAME = r"c:\Users\Carlos\dev\almeira-web\dripzone_deploy.tar.gz" -REMOTE_DIR = "/home/carlos/apps/dripzone-app" -REMOTE_TAR = "/home/carlos/apps/dripzone_deploy.tar.gz" - -def create_tar(): - print("[1/4] Empaquetando dripzone-app para despliegue de produccion...") - with tarfile.open(ARCHIVE_NAME, "w:gz") as tar: - for root, dirs, files in os.walk(LOCAL_DIR): - # Excluir node_modules, .next, android (para mantener paquete ligero) - dirs[:] = [d for d in dirs if d not in ['node_modules', '.next', 'android', '.git']] - for file in files: - if file.endswith('.apk'): - continue - full_path = os.path.join(root, file) - rel_path = os.path.relpath(full_path, LOCAL_DIR) - tar.add(full_path, arcname=rel_path) - size_mb = os.path.getsize(ARCHIVE_NAME) / (1024 * 1024) - print(f"[OK] Archivo generado: {ARCHIVE_NAME} ({size_mb:.2f} MB)") - def deploy(): - create_tar() - print(f"[2/4] Conectando a VPS {HOST} via SSH / SFTP...") - client = paramiko.SSHClient() - client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - connected = False - for attempt in range(1, 4): - try: - print(f" Intento {attempt} de conexion a {HOST}...") - client.connect(hostname=HOST, username=USER, password=PASSWORD, timeout=60, banner_timeout=60, auth_timeout=60) - connected = True - break - except Exception as conn_err: - print(f" Aviso: fallo en intento {attempt}: {conn_err}") - import time - time.sleep(2) - if not connected: - raise Exception(f"No se pudo conectar a {HOST} tras 3 intentos") - - sftp = client.open_sftp() - print("[3/4] Subiendo archivo comprimido y APK al servidor...") - sftp.put(ARCHIVE_NAME, REMOTE_TAR) - apk_local = r"c:\Users\Carlos\dev\almeira-web\dripzone-app\public\DripZone.apk" - if os.path.exists(apk_local): - local_size = os.path.getsize(apk_local) - remote_apk = f"{REMOTE_DIR}/public/DripZone.apk" - should_upload = True - try: - r_stat = sftp.stat(remote_apk) - if r_stat.st_size == local_size: - print(f" -> DripZone.apk ({local_size/(1024*1024):.1f} MB) ya se encuentra actualizado en el VPS. Omitiendo subida redundante.") - should_upload = False - except: - pass - - if should_upload: - print(f" -> Subiendo DripZone.apk ({local_size/(1024*1024):.1f} MB) a public/...") - try: - sftp.mkdir(f"{REMOTE_DIR}/public") - except: - pass - try: - sftp.put(apk_local, remote_apk) - print(" [OK] DripZone.apk subido al VPS.") - except Exception as e: - print(f" [Aviso] Error en subida SFTP de APK: {e}. Continuando con el despliegue...") - sftp.close() - print("[OK] Archivos base subidos exitosamente.") - - commands = f""" - mkdir -p {REMOTE_DIR} - tar -xzf {REMOTE_TAR} -C {REMOTE_DIR} - rm -f {REMOTE_TAR} - echo '{PASSWORD}' | sudo -S chown -R carlos:carlos /home/carlos/.docker || true - chmod -R 777 /home/carlos/.docker || true - cd {REMOTE_DIR} - docker compose -f docker-compose.prod.yml down --remove-orphans || true - DOCKER_BUILDKIT=1 docker compose -f docker-compose.prod.yml up -d --build - sleep 3 - docker exec -u 0 dripzone-production chown -R nextjs:nodejs /app/data /app/public || true - docker exec -u 0 dripzone-production chmod -R 777 /app/data /app/public || true - docker cp {REMOTE_DIR}/public/DripZone.apk dripzone-production:/app/public/DripZone.apk || true - docker cp {REMOTE_DIR}/public/DripZone.apk dripzone-production:/app/DripZone.apk || true - docker cp {REMOTE_DIR}/public/DripZone.apk dripzone-production:/app/public/dripzone.apk || true - docker cp {REMOTE_DIR}/public/DripZone.apk dripzone-production:/app/public/app-dripzone.apk || true - docker exec dripzone-production chmod 644 /app/public/DripZone.apk /app/DripZone.apk /app/public/dripzone.apk /app/public/app-dripzone.apk || true - docker ps | grep dripzone - """ - - print("[4/4] Ejecutando compilacion y levantando contenedor en Produccion...") - stdin, stdout, stderr = client.exec_command(commands) - - while not stdout.channel.exit_status_ready(): - line = stdout.readline() - if line: - print(line.strip()) - - for line in stdout.readlines(): - print(line.strip()) - - err = stderr.read().decode('utf-8', errors='ignore') - if err: - print("[Logs/Avisos]:", err) - - status = stdout.channel.recv_exit_status() - print(f"[EXIT STATUS]: {status}") - client.close() - - if status == 0: - send_apk_to_whatsapp() + print("[1/2] El despliegue web se gestiona exclusivamente a traves de Coolify.") + print(" Para desplegar la web, ingresa a Coolify o realiza git push a Gitea.") + print("[2/2] Despachando APK Android y reporte al WhatsApp de Carlos...") + send_apk_to_whatsapp() def send_apk_to_whatsapp(): import urllib.request