import paramiko import tarfile import os import sys import io # 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()) client.connect(hostname=HOST, username=USER, password=PASSWORD, timeout=30) sftp = client.open_sftp() print("[3/4] Subiendo archivo al servidor...") sftp.put(ARCHIVE_NAME, REMOTE_TAR) sftp.close() print("[OK] Archivo subido 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 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 __name__ == "__main__": deploy()