#!/usr/bin/env python3 """Deploy tenant-site feature + SSL for torbatkaracademy.""" from __future__ import annotations import base64 import sys from pathlib import Path import paramiko sys.stdout.reconfigure(encoding="utf-8", errors="replace") ROOT = Path(__file__).resolve().parents[1] PASS = "Moli@5404" REMOTE = "/home/morteza/torbatyar" def connect(host, user): c = paramiko.SSHClient() c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect(host, username=user, password=PASS, timeout=30, allow_agent=False, look_for_keys=False) return c def run(c, cmd, sudo=False, timeout=300): if sudo: b64 = base64.b64encode(cmd.encode()).decode() full = f"echo {PASS!r} | sudo -S -p '' bash -c 'echo {b64} | base64 -d | bash'" else: full = cmd _, o, e = c.exec_command(full, timeout=timeout, get_pty=True) text = (o.read() + e.read()).decode("utf-8", "replace") print(text[-6000:] if len(text) > 6000 else text) return text def main(): files = [ "backend/core-service/app/api/v1/public_tenant.py", "backend/core-service/app/api/v1/__init__.py", "frontend/app/page.tsx", "frontend/app/auth/callback/page.tsx", "frontend/components/SiteHeader.tsx", "frontend/components/TenantSitePage.tsx", "frontend/lib/api.ts", "frontend/lib/auth.ts", "frontend/lib/tenant-host.ts", "frontend/hooks/useTenantHost.ts", "docker-compose.yml", "infrastructure/deploy/.env.production.example", "infrastructure/nginx/torbatyar.ir.conf", ] app = connect("192.168.10.162", "morteza") sftp = app.open_sftp() for rel in files: if rel.startswith("infrastructure/nginx"): continue local = ROOT / rel remote = f"{REMOTE}/{rel}" # ensure parent sftp.put(str(local), remote) print("up", rel) # update .env with PLATFORM_BASE_DOMAIN try: with sftp.file(f"{REMOTE}/.env", "r") as f: env = f.read().decode("utf-8", "replace") except Exception: env = (ROOT / "infrastructure/deploy/.env.production.example").read_text(encoding="utf-8") if "NEXT_PUBLIC_PLATFORM_BASE_DOMAIN" not in env: env += "\nNEXT_PUBLIC_PLATFORM_BASE_DOMAIN=torbatyar.ir\n" with sftp.file(f"{REMOTE}/.env", "w") as f: f.write(env) sftp.close() run( app, f""" cd {REMOTE} docker compose up -d --force-recreate core-service frontend sleep 15 curl -sS -m 10 'http://127.0.0.1:8000/api/v1/public/tenant-site?slug=torbatkaracademy' -H 'Host: torbatkaracademy.torbatyar.ir' echo curl -sS -m 10 -o /dev/null -w 'fe=%{{http_code}}\\n' -H 'Host: torbatkaracademy.torbatyar.ir' http://127.0.0.1:3000/ """, sudo=True, timeout=240, ) app.close() ngx = connect("192.168.10.156", "torbatyaruser") conf = (ROOT / "infrastructure/nginx/torbatyar.ir.conf").read_text(encoding="utf-8") b64 = base64.b64encode(conf.encode()).decode() run( ngx, f""" echo {b64} | base64 -d > /etc/nginx/conf.d/torbatyar.ir.conf certbot certonly --webroot -w /var/www/html --expand --non-interactive --agree-tos --email support@torbatyar.ir \ -d torbatyar.ir -d www.torbatyar.ir -d api.torbatyar.ir -d identity.torbatyar.ir -d auth.torbatyar.ir \ -d torbatkaracademy.torbatyar.ir 2>&1 | tail -n 30 nginx -t && systemctl reload nginx && echo RELOADED curl -sk -m 15 -o /dev/null -w 'tenant_https=%{{http_code}}\\n' --resolve torbatkaracademy.torbatyar.ir:443:192.168.10.156 https://torbatkaracademy.torbatyar.ir/ curl -sk -m 15 --resolve api.torbatyar.ir:443:192.168.10.156 'https://api.torbatyar.ir/api/v1/public/tenant-site?slug=torbatkaracademy' echo """, sudo=True, timeout=300, ) ngx.close() if __name__ == "__main__": main()