Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ pipeline {
-v ${WORKSPACE}:/mnt \
-e AWS_ACCESS_KEY_ID=\"${S3_KEY}\" \
-e AWS_SECRET_ACCESS_KEY=\"${S3_SECRET}\" \
ghcr.io/linuxserver/baseimage-alpine:3 s6-envdir -fn -- /var/run/s6/container_environment /bin/bash -c "\
ghcr.io/linuxserver/baseimage-alpine:3.23 s6-envdir -fn -- /var/run/s6/container_environment /bin/bash -c "\
apk add --no-cache python3 && \
python3 -m venv /lsiopy && \
pip install --no-cache-dir -U pip && \
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ The architectures supported by this image are:

- Go to the [duckdns website](https://duckdns.org/), register your subdomain(s) and retrieve your token.
- Create a container with your subdomain(s) and token. If you own `user.duckdns.org`, you set `SUBDOMAINS=user`. You would NOT set a sub subdomain like `overseerr` from `overseerr.user.ducksdns.org`.
- It will update your IP with the DuckDNS service every 5 minutes (with a random jitter).
- It will update your IP with the DuckDNS service at a configurable interval (default: every 5 minutes, with a random jitter). Use the `UPDATE_INTERVAL` environment variable to customize the update frequency.

## Notice regarding automatic detection

Expand All @@ -76,7 +76,7 @@ This image can be run with a read-only container filesystem. For details please
To help you get started creating a container from this image you can either use docker-compose or the docker cli.

>[!NOTE]
>Unless a parameter is flaged as 'optional', it is *mandatory* and a value must be provided.
>Unless a parameter is flagged as 'optional', it is *mandatory* and a value must be provided.

### docker-compose (recommended, [click here for more info](https://docs.linuxserver.io/general/docker-compose))

Expand All @@ -94,6 +94,7 @@ services:
- SUBDOMAINS=subdomain1,subdomain2
- TOKEN=token
- UPDATE_IP=ipv4 #optional
- UPDATE_INTERVAL=5m #optional
- LOG_FILE=false #optional
volumes:
- /path/to/duckdns/config:/config #optional
Expand All @@ -112,6 +113,7 @@ docker run -d \
-e SUBDOMAINS=subdomain1,subdomain2 \
-e TOKEN=token \
-e UPDATE_IP=ipv4 `#optional` \
-e UPDATE_INTERVAL=5m `#optional` \
-e LOG_FILE=false `#optional` \
-v /path/to/duckdns/config:/config `#optional` \
--restart unless-stopped \
Expand All @@ -131,6 +133,7 @@ Containers are configured using parameters passed at runtime (such as those abov
| `-e SUBDOMAINS=subdomain1,subdomain2` | multiple subdomains allowed, comma separated, no spaces, if your domain is user.duckdns.org you put user, not a sub-subdomain |
| `-e TOKEN=token` | DuckDNS token |
| `-e UPDATE_IP=ipv4` | Set to `ipv6` or `ipv4` to update **only** your public IPv4/6 address. Set to `both` to update IPv6 and IPv4 address. This variable makes use of a [third-party service](#notice-regarding-automatic-detection). Omitting this variable uses DuckDNS for detection and only supports IPv4. `both` and `ipv6` modes needs [host networking](#networking-net). |
| `-e UPDATE_INTERVAL=5m` | Set the update interval. Format: `[number][m|h]` where `m` is minutes (5-60) or `h` is hours (1-24). Examples: `5m` (every 5 minutes), `30m` (every 30 minutes), `2h` (every 2 hours). Default is `5m`. |
| `-e LOG_FILE=false` | Set to `true` to log to file (also need to map /config). |
| `-v /config` | Persistent config files. Also set `LOG_FILE=true` to keep address history. |
| `--read-only=true` | Run container with a read-only filesystem. Please [read the docs](https://docs.linuxserver.io/misc/read-only/). |
Expand Down Expand Up @@ -299,6 +302,7 @@ Once registered you can define the dockerfile to use with `-f Dockerfile.aarch64

## Versions

* **18.02.26:** - Add configurable update interval via UPDATE_INTERVAL environment variable.
* **27.07.25:** - Rebase to Alpine 3.22.
* **27.01.25:** - Rebase to Alpine 3.21.
* **24.06.24:** - Rebase to Alpine 3.20.
Expand Down
4 changes: 3 additions & 1 deletion readme-vars.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ param_env_vars:
opt_param_usage_include_env: true
opt_param_env_vars:
- {env_var: "UPDATE_IP", env_value: "ipv4", desc: "Set to `ipv6` or `ipv4` to update **only** your public IPv4/6 address. Set to `both` to update IPv6 and IPv4 address. This variable makes use of a [third-party service](#notice-regarding-automatic-detection). Omitting this variable uses DuckDNS for detection and only supports IPv4. `both` and `ipv6` modes needs [host networking](#networking-net).", env_options: ["", "ipv4", "ipv6", "both"]}
- {env_var: "UPDATE_INTERVAL", env_value: "5m", desc: "Set the update interval. Format: `[number][m|h]` where `m` is minutes (5-60) or `h` is hours (1-24). Examples: `5m` (every 5 minutes), `30m` (every 30 minutes), `2h` (every 2 hours). Default is `5m`.", env_options: ["5m", "30m", "1h", "2h"]}
- {env_var: "LOG_FILE", env_value: "false", desc: "Set to `true` to log to file (also need to map /config).", env_options: ["false", "true"]}
opt_param_usage_include_vols: true
opt_param_volumes:
Expand All @@ -36,7 +37,7 @@ app_setup_block_enabled: true
app_setup_block: |
- Go to the [duckdns website]({{project_url}}), register your subdomain(s) and retrieve your token.
- Create a container with your subdomain(s) and token. If you own `user.duckdns.org`, you set `SUBDOMAINS=user`. You would NOT set a sub subdomain like `overseerr` from `overseerr.user.ducksdns.org`.
- It will update your IP with the DuckDNS service every 5 minutes (with a random jitter).
- It will update your IP with the DuckDNS service at a configurable interval (default: every 5 minutes, with a random jitter). Use the `UPDATE_INTERVAL` environment variable to customize the update frequency.

## Notice regarding automatic detection

Expand Down Expand Up @@ -85,6 +86,7 @@ init_diagram: |
"duckdns:latest" <- Base Images
# changelog
changelogs:
- {date: "18.02.26:", desc: "Add configurable update interval via UPDATE_INTERVAL environment variable."}
- {date: "27.07.25:", desc: "Rebase to Alpine 3.22."}
- {date: "27.01.25:", desc: "Rebase to Alpine 3.21."}
- {date: "24.06.24:", desc: "Rebase to Alpine 3.20."}
Expand Down
1 change: 1 addition & 0 deletions root/app/duck.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ if [[ "${LOG_FILE,,}" = "true" ]]; then
touch /config/logrotate.status
chmod 640 /config/logrotate.status
/usr/sbin/logrotate -s /config/logrotate.status /config/logrotate.conf
echo "duck.sh invoked at $(date)" >> "${DUCK_LOG}"
else
DUCK_LOG="/dev/null"
fi
Expand Down
2 changes: 2 additions & 0 deletions root/defaults/abc.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# min . hour day month weekday command
${MINUTES} ${HOURS} * * * sleep $((60 + $RANDOM % 230)); /app/duck.sh 2>&1
2 changes: 0 additions & 2 deletions root/etc/crontabs/abc

This file was deleted.

37 changes: 36 additions & 1 deletion root/etc/s6-overlay/s6-rc.d/init-duckdns/run
Original file line number Diff line number Diff line change
@@ -1,12 +1,47 @@
#!/usr/bin/with-contenv bash
# shellcheck shell=bash

#Check to make sure the subdomain and token are set
# Check to make sure the subdomain and token are set
if [ -z "${SUBDOMAINS}" ] || [ -z "${TOKEN}" ]; then
echo "Please pass both your subdomain(s) and token as environment variables in your docker run command. See the readme for more details."
sleep infinity
fi

# Render template into real crontab with default interval if not provided
UPDATE_INTERVAL=${UPDATE_INTERVAL:-5m}
if [[ ! "$UPDATE_INTERVAL" =~ ^[0-9]+[mh]?$ ]]; then
echo "Invalid interval format: \"$UPDATE_INTERVAL\", expected format \"[0-9]+[mh]?\""
exit 1
fi

case "$UPDATE_INTERVAL" in
*h)
HOURS=${UPDATE_INTERVAL%h}
if (( HOURS < 1 || HOURS > 24 )); then
echo "Update interval must be between 1-24 hours"
exit 1
fi
HOURS="*/$HOURS"

# We want a single run per selected hour, with the template's jitter handling
# the exact seconds.
MINUTES="0"
;;
*)
MINUTES=${UPDATE_INTERVAL%m}
if (( MINUTES < 5 || MINUTES > 60 )); then
echo "Update interval must be between 5-60 minutes"
exit 1
fi
MINUTES="*/$MINUTES"

HOURS="*"
;;
esac

sed "s|\${MINUTES} \${HOURS}|$MINUTES $HOURS|g" < /defaults/abc.tmpl > /etc/crontabs/abc
chmod 644 /etc/crontabs/abc

if [[ ! -f /config/logrotate.conf ]]; then
cp /defaults/logrotate.conf /config/logrotate.conf
chmod 640 /config/logrotate.conf
Expand Down