🪟 Windows TippsAndroid 17: Neue Version ist hier – Das ist alles neu(16.09.2026 um 11:40 Uhr)
🕵️ Hacking12 Best CASB Solutions Compared (2026): Features & Pricing(16.09.2026 um 09:31 Uhr)
🕵️ Hacking12 Best CIEM Tools Compared (2026): Features & Pricing(16.09.2026 um 09:37 Uhr)
🪟 Windows TippsAndroid 17: Neue Version ist hier – Das ist alles neu(16.09.2026 um 11:40 Uhr)
🕵️ Hacking12 Best CASB Solutions Compared (2026): Features & Pricing(16.09.2026 um 09:31 Uhr)
🕵️ Hacking12 Best CIEM Tools Compared (2026): Features & Pricing(16.09.2026 um 09:37 Uhr)

🔧 Programmierung 🕛 vor 1 Jahr 8 Min Lesezeit
0

Dynamic DNS sync with Cloudflare

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




Dynamic DNS sync with Cloudflare



If you ever get yourself a Raspberry Pi, NAS, or turn an old computer into a server, you start to think about accessing it from outside of your network. This usually requires you to open a port on your router and forward to the IP of your device. Some of the services you might want to access could be a Wireguard/OpenVPN VPN or some other service.



One note about VPN, there is a way to get into your network without opening a port. You can use and the port you have for your VPN or other service might not work. If you need to have a dedicate subdomain for VPN, you can modify the code below and have it update two records. That's how I have setup.



Another note on syncing IPs with cloudflare: there are already some tools that can do this for you. I went this path, because I wanted to understand how it works under the hood and it was fun! If you are interested in writing some code to automate some tasks, this post is for you!






Assumptions




  • Your domain is on Cloudflare (or you are willing to change your domain provider to Cloudflare)

  • You can run a docker container in your server

  • You have deno installed on your computer

  • You are comfortable writing some TypeScript code to check IP and update it using Cloudflare APIs






Get started






Cloudflare Domain Settings



Create an A record for your Dynamic DNS subdomain or full domain for your public IP.



You can skip this step, if you already have an A record for your public IP.





You want to only allow Zone DNS Edit/Read permissions.








Code



We will be using TypeScript and Deno.






Cloudflare Worker



You need to make sure you have some secrets set:





  • WORKER_API_KEY: API key to authenticate with the Cloudflare worker


  • API_KEY: Cloudflare API key you created earlier


  • DNS_ZONE_ID: Cloudflare Zone ID. You can get it by making a GET request to . It will return an array of DNS records. Grab the id of the record you want to update.



wrangler.toml: These are the environment variables for the worker




CODE
[vars]
DDNS_NAME="ddns.YOUR_DOMAIN.com"
DDNS_COMMENT="DDNS for my server"
DDNS_PROXIED=true






index.ts




CODE
import { getIp } from "./get-ip";
import { updateDnsRecord } from "./update-dns-record";

export default {
async fetch(request, env): Promise<Response> {
const WORKER_API_KEY = env.WORKER_API_KEY
const API_KEY = request.headers.get('Authorization')

if (API_KEY !== WORKER_API_KEY) {
return new Response('Not Authorized', { status: 403 })
}

if (request.method === 'PUT') {
const { ip } = await request.json() as { ip: string }
return updateDnsRecord(ip, env)
} else {
return getIp(env)
}
},
} satisfies ExportedHandler<Env>;






get-ip.ts




CODE
export async function getIp(env: Env) {
const options = {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${env.API_KEY}`,
}
};

try {
const response = await fetch(
`https://api.cloudflare.com/client/v4/zones/${env.DNS_ZONE_ID}/dns_records/${env.DNS_RECORD_ID}`,
options
)

const { result: { content: ip } } = await response.json() as { result: { content: string } }

return new Response(JSON.stringify({ ip }), { headers: { 'Content-Type': 'application/json' } });
} catch (err) {
console.error(err)
return new Response(JSON.stringify(err))
}
}






update-dns-record.ts




CODE
export async function updateDnsRecord(ip: string, env: Env) {
if (ip) {
// snake_case because Cloudflare API uses snake_case :)
const zone_id = env.DNS_ZONE_ID

const id = env.DNS_RECORD_ID
const name = env.DDNS_NAME
const comment = env.DDNS_COMMENT
const proxied = env.DDNS_PROXIED

try {
const update = {
id,
zone_id,
name,
comment,
type: "A",
content: ip,
proxied
}
const body = JSON.stringify(update);

const options = {
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${env.API_KEY}`,
},
body,
};

const response = await fetch(
`https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records/${update.id}`,
options
)

const responseBody = await response.json()

return new Response(JSON.stringify(responseBody), { headers: { 'Content-Type': 'application/json' } });
} catch (err) {
console.error(err)
return new Response(JSON.stringify(err))
}
}

return new Response(JSON.stringify({ message: 'bad request' }));
}









Docker Container



You can get started by installing deno on your machine and generate a new deno app with deno init ddns_sync.



I used Deno in this example, because it is so easy to get started and have a running code without installing bunch of stuff. Deno is so awesome for that. I installed zero packages to achieve cron and HTTP requests.



Dockerfile




CODE
FROM denoland/deno:alpine-2.1.4

WORKDIR /app

ADD *.ts .
ADD *.json .

RUN deno cache main.ts

ENTRYPOINT ["deno", "task", "start"]






main.ts




CODE
Deno.cron("Sample cron job", "*/1 * * * *", async () => {
const currentDateTime = new Date().toISOString()
try {
const [publicIp, ddnsIp] = await Promise.all([
getPublicIp(),
getExistingDdnsIp(),
]);

if (publicIp === ddnsIp) {
console.log(currentDateTime, "IP address did not change");
} else {
const updatedIp = await updateDdnsIp(publicIp);
console.log(
currentDateTime,
updatedIp === publicIp
? "DDNS IP has been updated"
: "DDNS failed to update"
);
}
} catch (error) {
console.error(currentDateTime, 'Error: ', error)
}
});

async function getPublicIp(): Promise<string> {
const response = await fetch("https://api.ipify.org/?format=json");
const body = await response.json();

return body.ip;
}

async function getExistingDdnsIp(): Promise<string> {
const response = await fetch(Deno.env.get("WORKER_URL"), {
headers: { Authorization: Deno.env.get("API_KEY") },
});
const body = await response.json();

return body.ip;
}

async function updateDdnsIp(ip: string) {
const options = {
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: Deno.env.get("API_KEY"),
},
body: JSON.stringify({ ip }),
};

const response = await fetch(Deno.env.get("WORKER_URL"), options);
const body = await response.json();

return body.result.content;
}






deno.json




CODE
{
"tasks": {
"dev": "deno run --unstable-cron --allow-net --allow-env --watch main.ts",
"start": "deno run --unstable-cron --allow-env --allow-net main.ts"
},
"imports": {
"@std/assert": "jsr:@std/assert@1"
}
}






You can build your docker image and run it on your server like this:




CODE
docker build -t ddns-sync .
docker run -d --name ddns-sync \
-e API_KEY=WORKER_API_KEY \
-e WORKER_URL="http://ddns.YOUR_USERNAME.workers.dev" \
--restart unless-stopped ddns-sync






That’s it. That should have you check your public IP every minute and compare it against the DNS record. If your public IP changes, this will automatically update it. You will get about a minute of outage if this happens.



I recently had to do this and decided to document it as a blog post. I hope someone finds this helpful!



The code quality is at the level of a homelab project, so there is definitely room for improvement. Let me know if you have suggestions on how to improve this.



If you have any questions or corrections, definitely leave a comment. I am more than happy to answer them.

Vollständiger Original-Artikel
Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
2 Quellen
CVE-2026-88255 | ZenHive mpp up to 0.16.1 Duplicate Submission Gate lib/mpp/replay.ex reserve_hash_atomic input validation (EUVD-2026-80256)
1 Quelle
Android 17: Neue Version ist hier – Das ist alles neu
1 Quelle
Die entscheidende Hürde: Xpeng will deutsch und nicht chinesisch sein
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Dynamic DNS sync with Cloudflare

Thematisch verwandte Begriffe: Dynamic, sync, with, Cloudflare · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...