otomatik sertifika kontrolu ve traefik nudge
Deploy / deploy (push) Successful in 32s

This commit is contained in:
2026-09-23 19:42:44 +03:00
parent bc8b7fa5a5
commit 9a8defb8f2
+53 -1
View File
@@ -176,6 +176,42 @@ def find_container_hostname(name):
return extract_hostname(labels) return extract_hostname(labels)
def cert_issuer(hostname, timeout=5):
"""Traefik'in o hostname icin su an sundugu sertifikanin issuer'ini
dondurur (bos string = baglanti kurulamadi)."""
try:
p1 = subprocess.run(
["openssl", "s_client", "-connect", "traefik:443", "-servername", hostname],
input="", capture_output=True, text=True, timeout=timeout,
)
p2 = subprocess.run(
["openssl", "x509", "-noout", "-issuer"],
input=p1.stdout, capture_output=True, text=True, timeout=timeout,
)
return p2.stdout.strip()
except Exception:
return ""
def wait_for_real_cert(hostname, max_wait=50):
"""Traefik yeni bir hostname icin ilk ACME denemesini DNS/Cloudflare
tam hazir olmadan yapabiliyor ve kendiliginden hizli tekrar
denemiyor. Bu yuzden: gercek (Let's Encrypt) sertifika gelene kadar
bekle; birkac saniye icinde gelmezse Traefik'i bir kez yeniden
baslatarak ACME denemesini zorla tetikle."""
deadline = time.time() + max_wait
nudged = False
while time.time() < deadline:
if "Let's Encrypt" in cert_issuer(hostname):
return True
if not nudged and time.time() > deadline - max_wait + 8:
subprocess.run(["docker", "restart", "traefik"])
nudged = True
time.sleep(3)
time.sleep(2)
return "Let's Encrypt" in cert_issuer(hostname)
def ensure_dns(hostname): def ensure_dns(hostname):
existing = requests.get( existing = requests.get(
f"https://api.cloudflare.com/client/v4/zones/{CF_ZONE_ID}/dns_records", f"https://api.cloudflare.com/client/v4/zones/{CF_ZONE_ID}/dns_records",
@@ -486,7 +522,23 @@ def api_deploy():
f"{name}:latest", f"{name}:latest",
], check=True) ], check=True)
return jsonify({"status": "deployed", "url": f"https://{hostname}"}), 200 cert_ready = wait_for_real_cert(hostname)
return jsonify({
"status": "deployed", "url": f"https://{hostname}", "cert_ready": cert_ready,
}), 200
@app.route("/api/wait-for-cert", methods=["POST"])
def api_wait_for_cert():
if not check_auth():
return jsonify({"error": "unauthorized"}), 401
body = request.get_json(force=True)
hostname = body.get("hostname")
if not hostname:
return jsonify({"error": "hostname required"}), 400
cert_ready = wait_for_real_cert(hostname)
return jsonify({"cert_ready": cert_ready}), 200
@app.route("/api/deploy/<name>", methods=["DELETE"]) @app.route("/api/deploy/<name>", methods=["DELETE"])