#!/usr/bin/env python3 """LAN SSH setup: Gitea repo + push + Coolify app for ExposedGays.""" import json import os import subprocess import sys try: import paramiko except ImportError: subprocess.check_call([sys.executable, "-m", "pip", "install", "paramiko", "-q"]) import paramiko HOST = "10.10.0.10" USER = "localadministrator" PASS = os.environ.get("COOLIFY_SSH_PASS", "Bbt9115xty9176!") GITEA_TOKEN = os.environ.get("GITEA_TOKEN", "dbf033cee4b0e3be5699f374a15f3fa240e2896a") REPO = "exposedgays" GIT_AUTH = f"https://{USER}:{GITEA_TOKEN}@gitea.onsethost.com/localadministrator/{REPO}.git" def run(host, cmd, timeout=300): c = paramiko.SSHClient() c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect(host, username=USER, password=PASS, timeout=20, allow_agent=False, look_for_keys=False) print(f"$ {cmd[:160]}") _, o, e = c.exec_command(cmd, timeout=timeout) code = o.channel.recv_exit_status() out = (o.read() + e.read()).decode(errors="replace") if out.strip(): print(out[-10000:]) print(f"exit={code}\n") c.close() return code, out def main(): print("=== Create Gitea repo via docker ===") run(HOST, ( "docker exec gitea gitea admin user list 2>/dev/null | head -3; " f"docker exec -u git gitea gitea admin create-repo --owner localadministrator " f"--name {REPO} --private=true 2>&1 || " f"curl -sS -X POST 'http://127.0.0.1:3000/api/v1/user/repos' " f"-H 'Authorization: token {GITEA_TOKEN}' " f"-H 'Content-Type: application/json' " f"-d '{{\"name\":\"{REPO}\",\"private\":true}}'" )) print("=== Push from /tmp/exposedgays ===") run(HOST, ( f"cd /tmp/exposedgays && git remote remove origin 2>/dev/null; " f"git remote add origin {GIT_AUTH} && " f"git push -u origin main --force" )) print("=== Find Coolify project + server UUIDs ===") _, out = run(HOST, ( "docker exec coolify-db psql -U coolify -d coolify -t -A -c " "\"SELECT uuid FROM projects LIMIT 1;\" 2>/dev/null; " "docker exec coolify-db psql -U coolify -d coolify -t -A -c " "\"SELECT uuid FROM servers WHERE deleted_at IS NULL LIMIT 1;\" 2>/dev/null" )) lines = [ln.strip() for ln in out.splitlines() if ln.strip() and len(ln.strip()) > 10 and "exit=" not in ln] project_uuid = lines[0] if len(lines) > 0 else "" server_uuid = lines[1] if len(lines) > 1 else "" print(f"project={project_uuid} server={server_uuid}") print("=== Check if app already exists ===") _, out = run(HOST, ( f"docker exec coolify-db psql -U coolify -d coolify -t -A -c " f"\"SELECT uuid FROM applications WHERE name='exposedgays' LIMIT 1;\"" )) existing = [ln.strip() for ln in out.splitlines() if ln.strip() and "exit=" not in ln and len(ln.strip()) > 8] app_uuid = existing[0] if existing else "" git_public = f"https://gitea.onsethost.com/localadministrator/{REPO}.git" if app_uuid: print(f"App exists: {app_uuid} — updating git source") run(HOST, ( f"docker exec coolify-db psql -U coolify -d coolify -c " f"\"UPDATE applications SET " f"git_repository='{git_public}', " f"git_full_url='{GIT_AUTH}', " f"git_branch='main', " f"build_pack='dockerfile', " f"dockerfile_location='/Dockerfile', " f"fqdn='exposedgays.com,www.exposedgays.com', " f"updated_at=now() " f"WHERE uuid='{app_uuid}';\"" )) else: print("=== Create Coolify app via API on localhost ===") token_cmd = "cat /home/localadministrator/.coolify-token 2>/dev/null | tail -1" payload = json.dumps({ "project_uuid": project_uuid, "server_uuid": server_uuid, "environment_name": "production", "git_repository": git_public, "git_branch": "main", "build_pack": "dockerfile", "dockerfile_location": "/Dockerfile", "ports_exposes": "3000", "name": "exposedgays", "description": "ExposedGays free cruising + shop", "domains": "https://exposedgays.com,https://www.exposedgays.com", "instant_deploy": False, }).replace("'", "'\\''") run(HOST, ( f"TOKEN=$({token_cmd}); " f"curl -sS -X POST 'http://127.0.0.1:8000/api/v1/applications/public' " f"-H \"Authorization: Bearer $TOKEN\" " f"-H 'Content-Type: application/json' " f"-d '{payload}'" )) _, out = run(HOST, ( f"docker exec coolify-db psql -U coolify -d coolify -t -A -c " f"\"SELECT uuid FROM applications WHERE name='exposedgays' LIMIT 1;\"" )) app_uuid = [ln.strip() for ln in out.splitlines() if ln.strip() and "exit=" not in ln][0] if app_uuid: print(f"=== Set env vars on {app_uuid} ===") envs = [ ("NEXT_PUBLIC_SUPABASE_URL", "https://supabase.onsethost.com"), ("NEXT_PUBLIC_SUPABASE_ANON_KEY", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzc2NzEzOTczLCJleHAiOjIwOTIwNzM5NzN9.oRPm6uJt4Gj-ASOixznas7-IC1pCtlZtEFew-SmY9wo"), ("NEXT_PUBLIC_APP_URL", "https://exposedgays.com"), ("NEXT_PUBLIC_DEFAULT_CITY", "Fort Lauderdale"), ("NEXT_PUBLIC_DEFAULT_LAT", "26.1224"), ("NEXT_PUBLIC_DEFAULT_LNG", "-80.1373"), ] for key, val in envs: run(HOST, ( f"TOKEN=$(cat /home/localadministrator/.coolify-token | tail -1); " f"curl -sS -X POST 'http://127.0.0.1:8000/api/v1/applications/{app_uuid}/envs' " f"-H \"Authorization: Bearer $TOKEN\" " f"-H 'Content-Type: application/json' " f"-d '{{\"key\":\"{key}\",\"value\":\"{val}\"}}'" )) print("=== Deploy ===") run(HOST, ( f"TOKEN=$(cat /home/localadministrator/.coolify-token | tail -1); " f"curl -sS -X POST 'http://127.0.0.1:8000/api/v1/deploy?uuid={app_uuid}&force_rebuild=true' " f"-H \"Authorization: Bearer $TOKEN\"" )) print("\n=== DONE ===") print(f"Gitea: https://gitea.onsethost.com/localadministrator/{REPO}") print(f"Coolify app UUID: {app_uuid or 'FAILED — create manually'}") if __name__ == "__main__": main()