Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
33 changes: 33 additions & 0 deletions .github/workflows/docker-image.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Docker Image CI

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
schedule:
- cron: '15 0 * * THU,SUN'

jobs:

build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Add current timestamp as env variable
run: |
echo "TIMESTAMP=$(date +%s)" >> $GITHUB_ENV
- name: Login to Docker Hub
env:
DOCKER_USER: ${{secrets.DOCKER_USER}}
DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}}
run: |
docker login -u $DOCKER_USER -p $DOCKER_PASSWORD
- name: Build the Docker image
run: |
docker build . --file Dockerfile --tag ${{secrets.DOCKER_USER}}/digital-ocean-dyndns:$TIMESTAMP && docker build . --file Dockerfile --tag ${{secrets.DOCKER_USER}}/digital-ocean-dyndns:latest
- name: Docker push images
run: docker push --all-tags ${{secrets.DOCKER_USER}}/digital-ocean-dyndns

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
# Secrets file (to keep it secret)
secrets
# Emacs "backup" files, to prevent having tilde files in github
*~
23 changes: 23 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FROM ubuntu:noble-20240801

WORKDIR /apps

# copy over the scripts
COPY get-dns.sh /apps/
COPY update-dns.sh /apps/
COPY timer-job.sh /apps/

# Set execution permissions
RUN chmod 0755 /apps/get-dns.sh
RUN chmod 0755 /apps/update-dns.sh
RUN chmod 0755 /apps/timer-job.sh

# install packages & then cleanup to minimize docker image
RUN apt-get update
RUN apt-get -y install curl
RUN apt-get -y install jq
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*

CMD /apps/timer-job.sh

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
A dependency free bash script to dynamically update your DNS on DigitalOcean.

~~Stolen from~~ _Inspired by_ Nicu Surdu's post: https://surdu.me/2019/07/28/digital-ocean-ddns.html
Forked from [jgillman](https://github.com/CrystalSpore/digital-ocean-dynamic-dns), who said "~~Stolen from~~ _Inspired by_ Nicu Surdu's post: https://surdu.me/2019/07/28/digital-ocean-ddns.html"

I wanted a dynamic DNS updater that I could control. There are a LOT of scripts out there that do it written in PHP, Python, Go, Perl, Node, etc. I couldn't find one (other than Nicu's) that could just run in bash with cURL.

Expand Down
6 changes: 5 additions & 1 deletion get-dns.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ response=$(curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
"https://api.digitalocean.com/v2/domains/$DOMAIN/records")

echo "$response" | grep -Eo '"id":\d*|"type":"\w*"|"name":"\w*"|"data":".*?"'
if ! command -v jq &> /dev/null; then
echo "$response" | grep -Eo '"id":\d*|"type":"\w*"|"name":"\w*"|"data":".*?"'
else
echo $response | jq .domain_records
fi
2 changes: 2 additions & 0 deletions secrets.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ ACCESS_TOKEN=your_token
DOMAIN=example.com
# The IDs of the record(s) you want to update, separated with spaces
RECORD_IDS=(12345 23456)
# Which ip name service checker do you wish to use? (Choose `AWS` or `IPINFO`)
IP_SERVICE=AWS
5 changes: 5 additions & 0 deletions timer-job.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
while true; do
/apps/update-dns.sh
sleep 300s
done
37 changes: 27 additions & 10 deletions update-dns.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,46 @@ check_credentials() {

# Check credentials before proceeding
check_credentials


public_ip=$(curl -s http://checkip.amazonaws.com/)
if [[ "${IP_SERVICE}" == "AWS" ]]; then
public_ip=$(curl -s http://checkip.amazonaws.com/)
elif [[ "${IP_SERVICE}" == "IPINFO" ]]; then
public_ip=$(curl -s http://ipinfo.io/ip)
fi

for ID in "${RECORD_IDS[@]}"; do
local_ip=$(
curl_response=$(
curl \
--fail \
--silent \
-X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
"https://api.digitalocean.com/v2/domains/${DOMAIN}/records/${ID}" | \
--fail \
--silent \
-X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
"https://api.digitalocean.com/v2/domains/${DOMAIN}/records/${ID}" | \
grep -Eo '"data":".*?"' | \
grep -Eo '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'
)
if ! command -v jq &> /dev/null; then
local_ip=$(
echo "${curl_response}" | \
grep -Eo '"data":".*?"' | \
grep -Eo '+[0-9]\.[0-9]+\.[0-9]+\.[0-9]+'
)
else
local_ip=$(
echo "${curl_response}" | \
jq -r '.domain_record.data'
)
fi

# if the IPs are the same just exit

if [ "$local_ip" == "$public_ip" ]; then
echo "IP has not changed for record ${ID}, skipping."
continue
fi

echo "Updating DNS with new IP address: ${public_ip} - IP address was: ${local_ip}"

echo "Updating DNS record ${ID} with new IP address: ${public_ip}"
# --fail silently on server errors
curl \
Expand Down