mirror of
https://github.com/YuzuZensai/Cloudflare-DDNS-Updater.git
synced 2026-07-29 17:00:56 +00:00
146 lines
4.5 KiB
Markdown
146 lines
4.5 KiB
Markdown
# ☁️ Cloudflare DDNS Updater
|
|
|
|
Keeps Cloudflare DNS records pointed at the machine's current public IPv4 and/or IPv6 address.
|
|
|
|
The container reads:
|
|
|
|
- Environment variables from Docker, usually via `--env-file .env`.
|
|
- DNS update rules from `/home/node/app/configs/UpdaterConfig.json` inside the container.
|
|
|
|
## Quick Start
|
|
|
|
Pull the published image:
|
|
|
|
```sh
|
|
docker pull ghcr.io/yuzuzensai/cloudflare-ddns-updater:latest
|
|
```
|
|
|
|
Create `.env` from the example and set your Cloudflare API token:
|
|
|
|
```sh
|
|
cp .env.example .env
|
|
```
|
|
|
|
```env
|
|
NODE_ENV=production
|
|
EXAMPLE_SITE_TOKEN=replace-with-cloudflare-api-token
|
|
```
|
|
|
|
Create `configs/UpdaterConfig.json`:
|
|
|
|
```json
|
|
[
|
|
{
|
|
"token": "{ENV_TOKEN:EXAMPLE_SITE_TOKEN}",
|
|
"updateInterval": 60,
|
|
"zone": [
|
|
{
|
|
"id": "cloudflare-zone-id",
|
|
"type": "A",
|
|
"name": "example.com",
|
|
"content": "{CURRENT_IPv4}",
|
|
"ttl": 1,
|
|
"proxied": false
|
|
},
|
|
{
|
|
"id": "cloudflare-zone-id",
|
|
"type": "AAAA",
|
|
"name": "example.com",
|
|
"content": "{CURRENT_IPv6}",
|
|
"ttl": 1,
|
|
"proxied": false
|
|
}
|
|
]
|
|
}
|
|
]
|
|
```
|
|
|
|
Run the container:
|
|
|
|
```sh
|
|
docker run -d \
|
|
--name cloudflare-ddns-updater \
|
|
--restart unless-stopped \
|
|
--env-file .env \
|
|
-v "$(pwd)/configs:/home/node/app/configs" \
|
|
ghcr.io/yuzuzensai/cloudflare-ddns-updater:latest
|
|
```
|
|
|
|
View logs:
|
|
|
|
```sh
|
|
docker logs -f cloudflare-ddns-updater
|
|
```
|
|
|
|
## Docker Compose
|
|
|
|
```yaml
|
|
services:
|
|
cloudflare-ddns-updater:
|
|
image: ghcr.io/yuzuzensai/cloudflare-ddns-updater:latest
|
|
container_name: cloudflare-ddns-updater
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
volumes:
|
|
- ./configs:/home/node/app/configs
|
|
```
|
|
|
|
```sh
|
|
docker compose up -d
|
|
```
|
|
|
|
## Configuration
|
|
|
|
`configs/UpdaterConfig.json` is an array of Cloudflare account/token configurations.
|
|
|
|
Each top-level object:
|
|
|
|
| Field | Description |
|
|
| ---------------- | --------------------------------------------------------------------------------------- |
|
|
| `token` | Cloudflare API token, or an environment reference like `{ENV_TOKEN:EXAMPLE_SITE_TOKEN}` |
|
|
| `updateInterval` | Update interval in seconds |
|
|
| `zone` | DNS records to manage |
|
|
|
|
Each `zone` entry:
|
|
|
|
| Field | Description |
|
|
| --------- | ------------------------------------------------------------------------- |
|
|
| `id` | Cloudflare zone ID |
|
|
| `type` | DNS record type, usually `A` or `AAAA` |
|
|
| `name` | DNS record name, e.g. `example.com` or `home.example.com` |
|
|
| `content` | `{CURRENT_IPv4}` for an `A` record, `{CURRENT_IPv6}` for an `AAAA` record |
|
|
| `ttl` | Cloudflare TTL. Use `1` for automatic |
|
|
| `proxied` | Cloudflare proxy status, `true` or `false` |
|
|
|
|
## Cloudflare Zone ID and API Token
|
|
|
|
**Zone ID** — In the [Cloudflare dashboard](https://dash.cloudflare.com/), select the domain, open its overview page, and copy `Zone ID` from the `API` section of the right sidebar into `zone[].id`.
|
|
|
|
**API token** — In the dashboard, go to your profile icon → `My Profile` → `API Tokens` → `Create Token`. Use the built-in `Edit zone DNS` template (recommended) or a custom token with `Zone > DNS > Edit` and `Zone > Zone > Read` permissions. Either way, scope `Zone Resources` to `Include` → `Specific zone` → your domain, then create and copy the token — Cloudflare only shows it once. Don't use your Global API Key; the updater only needs a scoped token for the zones it manages.
|
|
|
|
Put the token in `.env` under any variable name you like, then reference that same name from `UpdaterConfig.json`:
|
|
|
|
```env
|
|
HOME_SITE_TOKEN=your-cloudflare-api-token
|
|
```
|
|
|
|
```json
|
|
"token": "{ENV_TOKEN:HOME_SITE_TOKEN}"
|
|
```
|
|
|
|
Avoid writing the literal token directly into `UpdaterConfig.json` — `{ENV_TOKEN:...}` keeps the secret in `.env`, which is gitignored.
|
|
|
|
## Development
|
|
|
|
```sh
|
|
bun install
|
|
bun run dev # run with --watch
|
|
bun run check # typecheck + format + lint + test
|
|
```
|
|
|
|
## Notes
|
|
|
|
- IPv4 is looked up via `https://api.ipify.org?format=json`, IPv6 via `https://api64.ipify.org/?format=json`.
|
|
- If `configs/UpdaterConfig.json` is missing, the app creates one from the bundled example — edit it before real use.
|