Add ntfy push and Listmonk newsletter with lightweight Docker deploy tooling.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
eric
2026-06-08 02:24:55 -05:00
parent 47b1ae8514
commit 22a960799c
24 changed files with 846 additions and 3 deletions

View File

@@ -0,0 +1,55 @@
#!/usr/bin/env python3
"""Git pull on production VPS and restart API."""
from __future__ import annotations
import os
import sys
import paramiko
HOST = os.getenv("NOMAD_SSH_HOST", "82.157.112.245")
USER = os.getenv("NOMAD_SSH_USER", "ubuntu")
SSH_PASSWORD = os.getenv("NOMAD_SSH_PASSWORD", "Xiao4669805")
REPO = "/home/ubuntu/gitlab-instance-0a899031_cnomadcna"
GIT_USER = os.getenv("GIT_USER", "eric")
GIT_PASSWORD = os.getenv("GIT_PASSWORD", "")
GIT_REMOTE = os.getenv(
"GIT_REMOTE",
"https://gitea.dsx2020.com/eric/gitlab-instance-0a899031_cnomadcna.git",
)
BRANCH = os.getenv("GIT_BRANCH", "test2")
def run(c: paramiko.SSHClient, cmd: str, timeout: int = 180) -> int:
safe = cmd.replace(GIT_PASSWORD, "***").replace(SSH_PASSWORD, "***")
print(f"\n$ {safe}")
_, o, e = c.exec_command(f"echo '{SSH_PASSWORD}' | sudo -S bash -lc \"{cmd}\"", timeout=timeout, get_pty=True)
out = o.read().decode("utf-8", errors="replace")
err = e.read().decode("utf-8", errors="replace")
code = o.channel.recv_exit_status()
if out:
sys.stdout.buffer.write(out.encode("utf-8", errors="replace"))
if err:
sys.stdout.buffer.write(err.encode("utf-8", errors="replace"))
return code
def main() -> int:
auth_url = GIT_REMOTE.replace("https://", f"https://{GIT_USER}:{GIT_PASSWORD}@")
c = paramiko.SSHClient()
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
c.connect(HOST, username=USER, password=SSH_PASSWORD, timeout=30)
try:
run(c, f"cd {REPO} && git fetch {auth_url} {BRANCH}")
run(c, f"cd {REPO} && git checkout {BRANCH}")
run(c, f"cd {REPO} && git pull {auth_url} {BRANCH}")
run(c, "systemctl restart cnomadcna-api.service")
run(c, "systemctl is-active cnomadcna-api.service")
run(c, f"cd {REPO} && git log -1 --oneline")
return 0
finally:
c.close()
if __name__ == "__main__":
sys.exit(main())