I used https://domain.digitalplat.org to get my domain name for this website (https://dockerplaybooks.dpdns.org) and I used https://cloudflare.com for my DNS services.
I run this in crontab every 10 minutes to keeps my public IP updated:
#!/usr/bin/env python3
import requests
# === CONFIGURATION ===
ZONE_NAME = "dockerplaybooks.dpdns.org"
RECORD_NAME = "dockerplaybooks.dpdns.org"
API_TOKEN = "YOUR_API_TOKEN"
# === FUNCTIONS ===
def get_public_ip():
return requests.get("https://api.ipify.org").text.strip()
def get_zone_id():
headers = {"Authorization": f"Bearer {API_TOKEN}"}
r = requests.get("https://api.cloudflare.com/client/v4/zones", headers=headers)
zones = r.json()["result"]
for zone in zones:
if zone["name"] == ZONE_NAME:
return zone["id"]
raise Exception("Zone not found")
def get_record_id(zone_id):
headers = {"Authorization": f"Bearer {API_TOKEN}"}
url = f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records"
r = requests.get(url, headers=headers)
records = r.json()["result"]
for record in records:
if record["name"] == RECORD_NAME and record["type"] == "A":
return record["id"]
raise Exception("A record not found")
def update_dns_record(zone_id, record_id, ip):
headers = {
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json"
}
url = f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{record_id}"
data = {
"type": "A",
"name": RECORD_NAME,
"content": ip,
"ttl": 300,
"proxied": False
}
r = requests.put(url, headers=headers, json=data)
return r.json()
# === MAIN EXECUTION ===
if __name__ == "__main__":
try:
ip = get_public_ip()
zone_id = get_zone_id()
record_id = get_record_id(zone_id)
result = update_dns_record(zone_id, record_id, ip)
print(f"[✓] Updated {RECORD_NAME} to {ip}")
print("Cloudflare response:", result)
except Exception as e:
print(f"[✗] Error: {e}")
If you find my content useful, please consider supporting this page: