refactor: eliminar despliegues independientes fuera de Coolify y respetar gestión exclusiva de Coolify
This commit is contained in:
parent
17fd5f5da0
commit
6cebc76599
@ -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.
|
- **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.
|
- **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.
|
- **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.
|
||||||
|
|||||||
@ -1,127 +1,19 @@
|
|||||||
import paramiko
|
|
||||||
import tarfile
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import io
|
import io
|
||||||
|
import urllib.request
|
||||||
|
import json
|
||||||
|
|
||||||
# Force UTF-8 stdout on Windows
|
# Force UTF-8 stdout on Windows
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
|
||||||
sys.stderr = io.TextIOWrapper(sys.stderr.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():
|
def deploy():
|
||||||
create_tar()
|
print("[1/2] El despliegue web se gestiona exclusivamente a traves de Coolify.")
|
||||||
print(f"[2/4] Conectando a VPS {HOST} via SSH / SFTP...")
|
print(" Para desplegar la web, ingresa a Coolify o realiza git push a Gitea.")
|
||||||
client = paramiko.SSHClient()
|
print("[2/2] Despachando APK Android y reporte al WhatsApp de Carlos...")
|
||||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
send_apk_to_whatsapp()
|
||||||
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()
|
|
||||||
|
|
||||||
def send_apk_to_whatsapp():
|
def send_apk_to_whatsapp():
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user