mirror of
https://github.com/cupcakearmy/docker-ddns-cloudflare.git
synced 2024-12-24 08:36:24 +00:00
Compare commits
3 Commits
144d5abeb6
...
e0af9cd82e
Author | SHA1 | Date | |
---|---|---|---|
e0af9cd82e | |||
3ca15c532f | |||
500d7b2423 |
@ -1,5 +1,4 @@
|
|||||||
*
|
*
|
||||||
!src
|
!src
|
||||||
!tsconfig.json
|
|
||||||
!package.json
|
!package.json
|
||||||
!pnpm-lock.yaml
|
!bun.lockb
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,4 @@
|
|||||||
.env
|
.env
|
||||||
ip.log
|
ip.log
|
||||||
dist
|
|
||||||
node_modules
|
node_modules
|
||||||
.vscode
|
.vscode
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Required
|
# Required
|
||||||
TOKEn=myapitoken
|
TOKEN=myapitoken
|
||||||
ZONE=example.org
|
ZONE=example.org
|
||||||
DNS_RECORD=some.example.org
|
DNS_RECORD=some.example.org
|
||||||
|
|
||||||
|
13
CHANGELOG.md
13
CHANGELOG.md
@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [1.4.1] - 2024-02-27
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Use the alpine `bun` image to half the image size.
|
||||||
|
|
||||||
|
## [1.4.0] - 2024-02-27
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Moved to bun.
|
||||||
|
- Removed some dependencies.
|
||||||
|
|
||||||
## [1.3.4] - 2024-02-27
|
## [1.3.4] - 2024-02-27
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
25
Dockerfile
25
Dockerfile
@ -1,23 +1,10 @@
|
|||||||
FROM node:20-alpine as base
|
FROM oven/bun:1-alpine as base
|
||||||
# PNPM
|
|
||||||
ENV PNPM_HOME="/pnpm"
|
|
||||||
ENV PATH="$PNPM_HOME:$PATH"
|
|
||||||
RUN corepack enable
|
|
||||||
# Setup
|
|
||||||
ENV CI=true
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ADD ./package.json ./pnpm-lock.yaml ./
|
COPY package.json bun.lockb /app/
|
||||||
|
RUN bun install --production --frozen-lockfile
|
||||||
|
|
||||||
|
COPY . .
|
||||||
FROM base as builder
|
|
||||||
RUN pnpm install
|
|
||||||
ADD . .
|
|
||||||
RUN pnpm run build
|
|
||||||
|
|
||||||
FROM base
|
|
||||||
RUN pnpm install --prod
|
|
||||||
COPY --from=builder /app/dist/ /app/dist/
|
|
||||||
|
|
||||||
STOPSIGNAL SIGTERM
|
STOPSIGNAL SIGTERM
|
||||||
|
CMD ["bun", "."]
|
||||||
CMD ["pnpm", "start"]
|
|
||||||
|
@ -51,7 +51,7 @@ docker-compose up -d
|
|||||||
| `ZONE` | | Cloudflare zone where your domain is. |
|
| `ZONE` | | Cloudflare zone where your domain is. |
|
||||||
| `DNS_RECORD` | | The actual DNS record that should be updated. |
|
| `DNS_RECORD` | | The actual DNS record that should be updated. |
|
||||||
| `PROXIED` | `true` | Whether the record is proxied by CloudFlare or not. |
|
| `PROXIED` | `true` | Whether the record is proxied by CloudFlare or not. |
|
||||||
| `CRON` | `*/5 * * * *` | Frequency of updates. |
|
| `CRON` | `*/5 * * * *` | Frequency of updates. The [following syntax](https://croner.56k.guru/usage/pattern/) is supported |
|
||||||
| `RESOLVER` | `https://api.ipify.org/` | The endpoint used to determine your public ip. |
|
| `RESOLVER` | `https://api.ipify.org/` | The endpoint used to determine your public ip. |
|
||||||
| `LOG_LEVEL` | `info` | Log level to run at. See [winston](https://github.com/winstonjs/winston#logging-levels) for possible values |
|
| `LOG_LEVEL` | `info` | Log level to run at. See [winston](https://github.com/winstonjs/winston#logging-levels) for possible values |
|
||||||
|
|
||||||
|
19
package.json
19
package.json
@ -1,23 +1,20 @@
|
|||||||
{
|
{
|
||||||
"version": "1.3.4",
|
"version": "1.4.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist",
|
"main": "./src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"check": "tsc --noEmit",
|
||||||
"dev": "tsc -w",
|
"dev": "bun --watch ./src/index.ts",
|
||||||
"start": "node ."
|
"start": "bun ./src/index.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.7",
|
"axios": "^1.6.7",
|
||||||
"dotenv": "^16.4.5",
|
"croner": "^8.0.1",
|
||||||
"node-cron": "^3.0.3",
|
|
||||||
"winston": "^3.11.0"
|
"winston": "^3.11.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.11.20",
|
"@types/bun": "^1.0.7",
|
||||||
"@types/node-cron": "^3.0.11",
|
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
},
|
}
|
||||||
"packageManager": "pnpm@8.15.4"
|
|
||||||
}
|
}
|
||||||
|
310
pnpm-lock.yaml
generated
310
pnpm-lock.yaml
generated
@ -1,310 +0,0 @@
|
|||||||
lockfileVersion: '6.0'
|
|
||||||
|
|
||||||
settings:
|
|
||||||
autoInstallPeers: true
|
|
||||||
excludeLinksFromLockfile: false
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
axios:
|
|
||||||
specifier: ^1.6.7
|
|
||||||
version: 1.6.7
|
|
||||||
dotenv:
|
|
||||||
specifier: ^16.4.5
|
|
||||||
version: 16.4.5
|
|
||||||
node-cron:
|
|
||||||
specifier: ^3.0.3
|
|
||||||
version: 3.0.3
|
|
||||||
winston:
|
|
||||||
specifier: ^3.11.0
|
|
||||||
version: 3.11.0
|
|
||||||
|
|
||||||
devDependencies:
|
|
||||||
'@types/node':
|
|
||||||
specifier: ^20.11.20
|
|
||||||
version: 20.11.20
|
|
||||||
'@types/node-cron':
|
|
||||||
specifier: ^3.0.11
|
|
||||||
version: 3.0.11
|
|
||||||
typescript:
|
|
||||||
specifier: ^5.3.3
|
|
||||||
version: 5.3.3
|
|
||||||
|
|
||||||
packages:
|
|
||||||
|
|
||||||
/@colors/colors@1.6.0:
|
|
||||||
resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==}
|
|
||||||
engines: {node: '>=0.1.90'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@dabh/diagnostics@2.0.3:
|
|
||||||
resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==}
|
|
||||||
dependencies:
|
|
||||||
colorspace: 1.1.4
|
|
||||||
enabled: 2.0.0
|
|
||||||
kuler: 2.0.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@types/node-cron@3.0.11:
|
|
||||||
resolution: {integrity: sha512-0ikrnug3/IyneSHqCBeslAhlK2aBfYek1fGo4bP4QnZPmiqSGRK+Oy7ZMisLWkesffJvQ1cqAcBnJC+8+nxIAg==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@types/node@20.11.20:
|
|
||||||
resolution: {integrity: sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==}
|
|
||||||
dependencies:
|
|
||||||
undici-types: 5.26.5
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@types/triple-beam@1.3.5:
|
|
||||||
resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/async@3.2.5:
|
|
||||||
resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/asynckit@0.4.0:
|
|
||||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/axios@1.6.7:
|
|
||||||
resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==}
|
|
||||||
dependencies:
|
|
||||||
follow-redirects: 1.15.5
|
|
||||||
form-data: 4.0.0
|
|
||||||
proxy-from-env: 1.1.0
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- debug
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/color-convert@1.9.3:
|
|
||||||
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
|
||||||
dependencies:
|
|
||||||
color-name: 1.1.3
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/color-name@1.1.3:
|
|
||||||
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/color-name@1.1.4:
|
|
||||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/color-string@1.9.1:
|
|
||||||
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
|
|
||||||
dependencies:
|
|
||||||
color-name: 1.1.4
|
|
||||||
simple-swizzle: 0.2.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/color@3.2.1:
|
|
||||||
resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==}
|
|
||||||
dependencies:
|
|
||||||
color-convert: 1.9.3
|
|
||||||
color-string: 1.9.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/colorspace@1.1.4:
|
|
||||||
resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==}
|
|
||||||
dependencies:
|
|
||||||
color: 3.2.1
|
|
||||||
text-hex: 1.0.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/combined-stream@1.0.8:
|
|
||||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
|
||||||
engines: {node: '>= 0.8'}
|
|
||||||
dependencies:
|
|
||||||
delayed-stream: 1.0.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/delayed-stream@1.0.0:
|
|
||||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
|
||||||
engines: {node: '>=0.4.0'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/dotenv@16.4.5:
|
|
||||||
resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/enabled@2.0.0:
|
|
||||||
resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/fecha@4.2.3:
|
|
||||||
resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/fn.name@1.1.0:
|
|
||||||
resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/follow-redirects@1.15.5:
|
|
||||||
resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==}
|
|
||||||
engines: {node: '>=4.0'}
|
|
||||||
peerDependencies:
|
|
||||||
debug: '*'
|
|
||||||
peerDependenciesMeta:
|
|
||||||
debug:
|
|
||||||
optional: true
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/form-data@4.0.0:
|
|
||||||
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
|
||||||
engines: {node: '>= 6'}
|
|
||||||
dependencies:
|
|
||||||
asynckit: 0.4.0
|
|
||||||
combined-stream: 1.0.8
|
|
||||||
mime-types: 2.1.35
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/inherits@2.0.4:
|
|
||||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/is-arrayish@0.3.2:
|
|
||||||
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/is-stream@2.0.1:
|
|
||||||
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
|
|
||||||
engines: {node: '>=8'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/kuler@2.0.0:
|
|
||||||
resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/logform@2.6.0:
|
|
||||||
resolution: {integrity: sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==}
|
|
||||||
engines: {node: '>= 12.0.0'}
|
|
||||||
dependencies:
|
|
||||||
'@colors/colors': 1.6.0
|
|
||||||
'@types/triple-beam': 1.3.5
|
|
||||||
fecha: 4.2.3
|
|
||||||
ms: 2.1.3
|
|
||||||
safe-stable-stringify: 2.4.3
|
|
||||||
triple-beam: 1.4.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/mime-db@1.52.0:
|
|
||||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
|
||||||
engines: {node: '>= 0.6'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/mime-types@2.1.35:
|
|
||||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
|
||||||
engines: {node: '>= 0.6'}
|
|
||||||
dependencies:
|
|
||||||
mime-db: 1.52.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/ms@2.1.3:
|
|
||||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/node-cron@3.0.3:
|
|
||||||
resolution: {integrity: sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==}
|
|
||||||
engines: {node: '>=6.0.0'}
|
|
||||||
dependencies:
|
|
||||||
uuid: 8.3.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/one-time@1.0.0:
|
|
||||||
resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==}
|
|
||||||
dependencies:
|
|
||||||
fn.name: 1.1.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/proxy-from-env@1.1.0:
|
|
||||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/readable-stream@3.6.2:
|
|
||||||
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
|
||||||
engines: {node: '>= 6'}
|
|
||||||
dependencies:
|
|
||||||
inherits: 2.0.4
|
|
||||||
string_decoder: 1.3.0
|
|
||||||
util-deprecate: 1.0.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/safe-buffer@5.2.1:
|
|
||||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/safe-stable-stringify@2.4.3:
|
|
||||||
resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==}
|
|
||||||
engines: {node: '>=10'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/simple-swizzle@0.2.2:
|
|
||||||
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
|
||||||
dependencies:
|
|
||||||
is-arrayish: 0.3.2
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/stack-trace@0.0.10:
|
|
||||||
resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/string_decoder@1.3.0:
|
|
||||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
|
||||||
dependencies:
|
|
||||||
safe-buffer: 5.2.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/text-hex@1.0.0:
|
|
||||||
resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/triple-beam@1.4.1:
|
|
||||||
resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==}
|
|
||||||
engines: {node: '>= 14.0.0'}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/typescript@5.3.3:
|
|
||||||
resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==}
|
|
||||||
engines: {node: '>=14.17'}
|
|
||||||
hasBin: true
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/undici-types@5.26.5:
|
|
||||||
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/util-deprecate@1.0.2:
|
|
||||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/uuid@8.3.2:
|
|
||||||
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
|
||||||
hasBin: true
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/winston-transport@4.7.0:
|
|
||||||
resolution: {integrity: sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==}
|
|
||||||
engines: {node: '>= 12.0.0'}
|
|
||||||
dependencies:
|
|
||||||
logform: 2.6.0
|
|
||||||
readable-stream: 3.6.2
|
|
||||||
triple-beam: 1.4.1
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/winston@3.11.0:
|
|
||||||
resolution: {integrity: sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==}
|
|
||||||
engines: {node: '>= 12.0.0'}
|
|
||||||
dependencies:
|
|
||||||
'@colors/colors': 1.6.0
|
|
||||||
'@dabh/diagnostics': 2.0.3
|
|
||||||
async: 3.2.5
|
|
||||||
is-stream: 2.0.1
|
|
||||||
logform: 2.6.0
|
|
||||||
one-time: 1.0.0
|
|
||||||
readable-stream: 3.6.2
|
|
||||||
safe-stable-stringify: 2.4.3
|
|
||||||
stack-trace: 0.0.10
|
|
||||||
triple-beam: 1.4.1
|
|
||||||
winston-transport: 4.7.0
|
|
||||||
dev: false
|
|
@ -20,6 +20,8 @@ type DNSRecord = {
|
|||||||
type DNSRecordCreate = Pick<DNSRecord, 'name' | 'type' | 'ttl' | 'proxied' | 'content'>
|
type DNSRecordCreate = Pick<DNSRecord, 'name' | 'type' | 'ttl' | 'proxied' | 'content'>
|
||||||
type DNSRecordPatch = Partial<DNSRecordCreate>
|
type DNSRecordPatch = Partial<DNSRecordCreate>
|
||||||
|
|
||||||
|
const l = logger.child({ context: 'cloudflare' })
|
||||||
|
|
||||||
const Base = axios.create({
|
const Base = axios.create({
|
||||||
baseURL: 'https://api.cloudflare.com/client/v4',
|
baseURL: 'https://api.cloudflare.com/client/v4',
|
||||||
headers: {
|
headers: {
|
||||||
@ -80,27 +82,27 @@ export const API = {
|
|||||||
export async function update(ip: string) {
|
export async function update(ip: string) {
|
||||||
// Find zone
|
// Find zone
|
||||||
if (!Cache.has('zone')) {
|
if (!Cache.has('zone')) {
|
||||||
logger.debug('Fetching zone')
|
l.debug('Fetching zone')
|
||||||
const zone = await API.zones.findByName(Config.dns.zone)
|
const zone = await API.zones.findByName(Config.dns.zone)
|
||||||
if (!zone) {
|
if (!zone) {
|
||||||
logger.error(`Zone "${Config.dns.zone}"" not found`)
|
l.error(`Zone "${Config.dns.zone}" not found`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
Cache.set('zone', zone)
|
Cache.set('zone', zone)
|
||||||
}
|
}
|
||||||
|
|
||||||
const zoneId = Cache.get('zone')!
|
const zoneId = Cache.get('zone')!
|
||||||
logger.debug(`Zone ID: ${zoneId}`)
|
l.debug(`Zone ID: ${zoneId}`)
|
||||||
|
|
||||||
// Set record
|
// Set record
|
||||||
const records = await API.records.find(zoneId)
|
const records = await API.records.find(zoneId)
|
||||||
|
|
||||||
logger.debug('Updating record', ip)
|
l.debug('Updating record', ip)
|
||||||
|
|
||||||
switch (records.length) {
|
switch (records.length) {
|
||||||
case 0:
|
case 0:
|
||||||
// Create DNS Record
|
// Create DNS Record
|
||||||
logger.debug('Creating DNS record')
|
l.debug('Creating DNS record')
|
||||||
await API.records.create(zoneId, {
|
await API.records.create(zoneId, {
|
||||||
content: ip,
|
content: ip,
|
||||||
name: Config.dns.record,
|
name: Config.dns.record,
|
||||||
@ -114,7 +116,7 @@ export async function update(ip: string) {
|
|||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
// More than one record, delete all but the first
|
// More than one record, delete all but the first
|
||||||
logger.debug('Deleting other DNS records')
|
l.debug('Deleting other DNS records')
|
||||||
for (const record of records.slice(1)) {
|
for (const record of records.slice(1)) {
|
||||||
await API.records.remove(zoneId, record.id)
|
await API.records.remove(zoneId, record.id)
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import { config } from 'dotenv'
|
import { Cron } from 'croner'
|
||||||
import { validate } from 'node-cron'
|
import pkg from '../package.json'
|
||||||
|
|
||||||
config()
|
|
||||||
|
|
||||||
function getEnv(key: string, fallback: string, parse?: undefined, validator?: (s: string) => boolean): string
|
function getEnv(key: string, fallback: string, parse?: undefined, validator?: (s: string) => boolean): string
|
||||||
function getEnv<T>(key: string, fallback: T, parse: (value: string) => T, validator?: (T: string) => boolean): T
|
function getEnv<T>(key: string, fallback: T, parse: (value: string) => T, validator?: (T: string) => boolean): T
|
||||||
@ -31,7 +29,7 @@ function isPresent(s: string): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const Config = {
|
export const Config = {
|
||||||
version: getEnv('npm_package_version', 'unknown'),
|
version: pkg.version,
|
||||||
logging: {
|
logging: {
|
||||||
level: getEnv('LOG_LEVEL', 'info'),
|
level: getEnv('LOG_LEVEL', 'info'),
|
||||||
},
|
},
|
||||||
@ -44,7 +42,14 @@ export const Config = {
|
|||||||
proxied: getEnv('PROXIED', false, parseBoolean),
|
proxied: getEnv('PROXIED', false, parseBoolean),
|
||||||
},
|
},
|
||||||
runner: {
|
runner: {
|
||||||
cron: getEnv('CRON', '*/5 * * * *', undefined, (s) => validate(s)),
|
cron: getEnv('CRON', '*/5 * * * *', undefined, (s) => {
|
||||||
|
try {
|
||||||
|
new Cron(s)
|
||||||
|
return true
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}),
|
||||||
resolver: getEnv('RESOLVER', 'https://api.ipify.org'),
|
resolver: getEnv('RESOLVER', 'https://api.ipify.org'),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
16
src/index.ts
16
src/index.ts
@ -1,14 +1,20 @@
|
|||||||
import { schedule } from 'node-cron'
|
import { Cron } from 'croner'
|
||||||
import process from 'process'
|
import process from 'node:process'
|
||||||
|
|
||||||
import { Config } from './config.js'
|
import { Config } from './config.js'
|
||||||
import { logger } from './logger.js'
|
import { logger } from './logger.js'
|
||||||
import { loop } from './runner.js'
|
import { loop } from './runner.js'
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const cron = schedule(Config.runner.cron, loop)
|
const cron = new Cron(Config.runner.cron, { protect: true }, loop)
|
||||||
logger.info('Started service.', { version: Config.version })
|
logger.info('started service', { version: Config.version })
|
||||||
logger.debug('Config', Config)
|
logger.debug('config', Config)
|
||||||
|
|
||||||
|
const nextRun = cron.nextRun()
|
||||||
|
if (nextRun) {
|
||||||
|
const pretty = new Intl.DateTimeFormat(undefined, { dateStyle: 'long', timeStyle: 'long' }).format(nextRun)
|
||||||
|
logger.info(`next run scheduled for ${pretty}`, { nextRunAt: nextRun })
|
||||||
|
}
|
||||||
|
|
||||||
function terminate() {
|
function terminate() {
|
||||||
logger.info('Stopping service.')
|
logger.info('Stopping service.')
|
||||||
|
@ -2,17 +2,19 @@ import { update } from './cloudflare.js'
|
|||||||
import { checkIfUpdateIsRequired, getCurrentIp } from './ip.js'
|
import { checkIfUpdateIsRequired, getCurrentIp } from './ip.js'
|
||||||
import { logger } from './logger.js'
|
import { logger } from './logger.js'
|
||||||
|
|
||||||
|
const l = logger.child({ context: 'runner' })
|
||||||
|
|
||||||
export async function loop() {
|
export async function loop() {
|
||||||
const ip = await getCurrentIp()
|
const ip = await getCurrentIp()
|
||||||
const changed = checkIfUpdateIsRequired(ip)
|
const changed = checkIfUpdateIsRequired(ip)
|
||||||
logger.info(`Running. Update required: ${!!changed}`)
|
l.info(`Running. Update required: ${!!changed}`)
|
||||||
if (changed) {
|
if (changed) {
|
||||||
try {
|
try {
|
||||||
await update(ip)
|
await update(ip)
|
||||||
logger.info('Successfully updated DNS record')
|
l.info('Successfully updated DNS record')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error(e)
|
l.error(e)
|
||||||
logger.error('Failed to update DNS record')
|
l.error('Failed to update DNS record')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
"target": "ES2022",
|
"target": "ES2022",
|
||||||
"module": "ES2022",
|
"module": "ES2022",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "Bundler",
|
||||||
"outDir": "./dist",
|
"noEmit": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"skipLibCheck": true
|
"skipLibCheck": true
|
||||||
|
Loading…
Reference in New Issue
Block a user