feat: add Docker image build target and deployment docs
This commit is contained in:
29
Makefile
29
Makefile
@@ -1,15 +1,20 @@
|
|||||||
APP_NAME = ddns-updater
|
APP_NAME = ddns-updater
|
||||||
BIN_DIR = bin
|
BIN_DIR = bin
|
||||||
VERSION = 1.0.0
|
VERSION = 1.0.0
|
||||||
|
|
||||||
# Go parameters
|
# Go parameters
|
||||||
GOCMD = go
|
GOCMD = go
|
||||||
GOBUILD = $(GOCMD) build
|
GOBUILD = $(GOCMD) build
|
||||||
GOCLEAN = $(GOCMD) clean
|
GOCLEAN = $(GOCMD) clean
|
||||||
GORUN = $(GOCMD) run
|
GORUN = $(GOCMD) run
|
||||||
|
|
||||||
|
# Docker image (override: make build-dockerimg IMAGE=kccleoc/ddns-updater:latest)
|
||||||
|
IMAGE ?= kccleoc/ddns-updater:latest
|
||||||
|
|
||||||
# Build targets
|
# Build targets
|
||||||
.PHONY: all build clean run init-config install install-linux install-macos service-linux service-macos
|
.PHONY: all build build-all clean run init-config install \
|
||||||
|
install-linux install-macos service-linux service-macos \
|
||||||
|
build-dockerimg push-dockerimg
|
||||||
|
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
@@ -22,8 +27,8 @@ build:
|
|||||||
# Build for multiple platforms
|
# Build for multiple platforms
|
||||||
build-all:
|
build-all:
|
||||||
mkdir -p $(BIN_DIR)
|
mkdir -p $(BIN_DIR)
|
||||||
GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BIN_DIR)/$(APP_NAME)-linux-amd64 main.go
|
GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BIN_DIR)/$(APP_NAME)-linux-amd64 main.go
|
||||||
GOOS=linux GOARCH=arm64 $(GOBUILD) -o $(BIN_DIR)/$(APP_NAME)-linux-arm64 main.go
|
GOOS=linux GOARCH=arm64 $(GOBUILD) -o $(BIN_DIR)/$(APP_NAME)-linux-arm64 main.go
|
||||||
GOOS=darwin GOARCH=amd64 $(GOBUILD) -o $(BIN_DIR)/$(APP_NAME)-darwin-amd64 main.go
|
GOOS=darwin GOARCH=amd64 $(GOBUILD) -o $(BIN_DIR)/$(APP_NAME)-darwin-amd64 main.go
|
||||||
GOOS=darwin GOARCH=arm64 $(GOBUILD) -o $(BIN_DIR)/$(APP_NAME)-darwin-arm64 main.go
|
GOOS=darwin GOARCH=arm64 $(GOBUILD) -o $(BIN_DIR)/$(APP_NAME)-darwin-arm64 main.go
|
||||||
@echo "Built all platform binaries in $(BIN_DIR)/"
|
@echo "Built all platform binaries in $(BIN_DIR)/"
|
||||||
@@ -90,3 +95,13 @@ service-macos:
|
|||||||
@echo " launchctl start com.ddns-updater"
|
@echo " launchctl start com.ddns-updater"
|
||||||
@echo "\nView logs with:"
|
@echo "\nView logs with:"
|
||||||
@echo " tail -f /usr/local/var/log/ddns-updater.log"
|
@echo " tail -f /usr/local/var/log/ddns-updater.log"
|
||||||
|
|
||||||
|
# Build Docker image (parameterized)
|
||||||
|
# Usage: make build-dockerimg IMAGE=kccleoc/ddns-updater:latest
|
||||||
|
build-dockerimg:
|
||||||
|
docker build -t $(IMAGE) .
|
||||||
|
|
||||||
|
# Push Docker image
|
||||||
|
# Usage: make push-dockerimg IMAGE=kccleoc/ddns-updater:latest
|
||||||
|
push-dockerimg:
|
||||||
|
docker push $(IMAGE)
|
||||||
|
|||||||
284
README.md
284
README.md
@@ -13,219 +13,161 @@ A lightweight dynamic DNS updater for Cloudflare written in Go. Automatically de
|
|||||||
- Graceful shutdown handling
|
- Graceful shutdown handling
|
||||||
- Cross-platform (Linux, macOS)
|
- Cross-platform (Linux, macOS)
|
||||||
|
|
||||||
## Quick Start
|
## Building and running
|
||||||
|
|
||||||
### 1. Generate configuration template
|
### 1. Generate config
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make init-config
|
go run main.go -init-config > config.yaml
|
||||||
|
# edit config.yaml with your Cloudflare token, zone_id, zone_name, and subdomains
|
||||||
```
|
```
|
||||||
|
|
||||||
This creates `config.yaml` with default settings.
|
Key fields:
|
||||||
|
|
||||||
### 2. Get Cloudflare credentials
|
|
||||||
|
|
||||||
#### Generate API Token
|
|
||||||
|
|
||||||
1. Log in to [Cloudflare Dashboard](https://dash.cloudflare.com)
|
|
||||||
2. Go to **Profile** → **API Tokens**
|
|
||||||
3. Click **Create Token**
|
|
||||||
4. Use the **Edit zone DNS** template or create a custom token with:
|
|
||||||
- **Permissions**: Zone → DNS → Edit, Zone → Zone → Read
|
|
||||||
- **Zone Resources**: Include → Specific zone → (select your domain)
|
|
||||||
5. Copy the token (you'll only see it once)
|
|
||||||
|
|
||||||
#### Find Zone ID
|
|
||||||
|
|
||||||
1. In Cloudflare Dashboard, select your domain
|
|
||||||
2. Scroll down on the **Overview** page
|
|
||||||
3. Find **Zone ID** in the right sidebar under **API** section
|
|
||||||
4. Copy the Zone ID
|
|
||||||
|
|
||||||
### 3. Configure
|
|
||||||
|
|
||||||
Edit `config.yaml`:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
cloudflare:
|
cloudflare:
|
||||||
api_token: "your-token-here" # From step 2
|
api_token: "your-token"
|
||||||
zone_id: "your-zone-id-here" # From step 2
|
|
||||||
zone_name: "example.com" # Your domain
|
|
||||||
subdomains:
|
|
||||||
- name: "home" # Updates home.example.com
|
|
||||||
proxied: false
|
|
||||||
- name: "vpn"
|
|
||||||
proxied: true # Route through Cloudflare proxy
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Run locally (test)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make run
|
|
||||||
```
|
|
||||||
|
|
||||||
Logs will show IP detection and DNS updates in real-time.
|
|
||||||
|
|
||||||
## Production Deployment
|
|
||||||
|
|
||||||
### Linux (systemd)
|
|
||||||
|
|
||||||
#### Install and set up service
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build and install binary
|
|
||||||
make install-linux
|
|
||||||
|
|
||||||
# Edit config with your credentials
|
|
||||||
sudo nano /etc/ddns-updater/config.yaml
|
|
||||||
|
|
||||||
# Create systemd service
|
|
||||||
make service-linux
|
|
||||||
|
|
||||||
# Enable and start
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
sudo systemctl enable ddns-updater
|
|
||||||
sudo systemctl start ddns-updater
|
|
||||||
|
|
||||||
# Check status
|
|
||||||
sudo systemctl status ddns-updater
|
|
||||||
|
|
||||||
# View logs
|
|
||||||
sudo journalctl -u ddns-updater -f
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Service management
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo systemctl stop ddns-updater # Stop service
|
|
||||||
sudo systemctl restart ddns-updater # Restart service
|
|
||||||
sudo systemctl disable ddns-updater # Disable auto-start
|
|
||||||
```
|
|
||||||
|
|
||||||
### macOS (launchd)
|
|
||||||
|
|
||||||
#### Install and set up service
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build and install binary
|
|
||||||
make install-macos
|
|
||||||
|
|
||||||
# Edit config with your credentials
|
|
||||||
sudo nano /usr/local/etc/ddns-updater.yaml
|
|
||||||
|
|
||||||
# Create launchd service
|
|
||||||
make service-macos
|
|
||||||
|
|
||||||
# Load and start
|
|
||||||
launchctl load ~/Library/LaunchAgents/com.ddns-updater.plist
|
|
||||||
launchctl start com.ddns-updater
|
|
||||||
|
|
||||||
# View logs
|
|
||||||
tail -f /usr/local/var/log/ddns-updater.log
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Service management
|
|
||||||
|
|
||||||
```bash
|
|
||||||
launchctl stop com.ddns-updater # Stop service
|
|
||||||
launchctl unload ~/Library/LaunchAgents/com.ddns-updater.plist # Unload service
|
|
||||||
```
|
|
||||||
|
|
||||||
## Configuration Reference
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Check interval in minutes (how often to check for IP changes)
|
|
||||||
check_interval: 5
|
|
||||||
|
|
||||||
cloudflare:
|
|
||||||
api_token: "your-api-token"
|
|
||||||
zone_id: "your-zone-id"
|
zone_id: "your-zone-id"
|
||||||
zone_name: "example.com"
|
zone_name: "example.com"
|
||||||
subdomains:
|
subdomains:
|
||||||
- name: "subdomain"
|
- name: "lc"
|
||||||
proxied: false # true = route through Cloudflare proxy (orange cloud)
|
proxied: false
|
||||||
|
|
||||||
logging:
|
logging:
|
||||||
file: "ddns-updater.log"
|
file: "/config/logs/ddns-updater.log"
|
||||||
level: "info" # debug, info, warn, error
|
|
||||||
|
|
||||||
retry:
|
|
||||||
max_attempts: 3
|
|
||||||
delay_seconds: 5
|
|
||||||
|
|
||||||
webhook:
|
|
||||||
enabled: false
|
|
||||||
url: "" # Optional webhook for notifications
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Building from Source
|
### 2. Local binary (Linux/macOS)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build for current platform
|
|
||||||
make build
|
make build
|
||||||
|
./bin/ddns-updater -config config.yaml
|
||||||
# Build for all platforms
|
|
||||||
make build-all
|
|
||||||
|
|
||||||
# Clean build artifacts
|
|
||||||
make clean
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Built binaries will be in `./bin/`
|
***
|
||||||
|
|
||||||
## Troubleshooting
|
## Production: Linux (systemd)
|
||||||
|
|
||||||
### Authentication errors
|
1. Install:
|
||||||
|
|
||||||
- Verify API token has correct permissions (Zone → DNS → Edit, Zone → Zone → Read)
|
|
||||||
- Confirm token is scoped to the correct zone
|
|
||||||
- Check token hasn't expired
|
|
||||||
|
|
||||||
### DNS record not found
|
|
||||||
|
|
||||||
- Ensure `zone_name` matches your Cloudflare domain exactly
|
|
||||||
- Verify subdomain exists in Cloudflare DNS settings
|
|
||||||
- Check subdomain name doesn't include the domain (use `home`, not `home.example.com`)
|
|
||||||
|
|
||||||
### Service won't start
|
|
||||||
|
|
||||||
**Linux:**
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo journalctl -u ddns-updater -n 50
|
sudo make install
|
||||||
|
sudo mkdir -p /etc/ddns-updater
|
||||||
|
sudo cp config.yaml /etc/ddns-updater/config.yaml
|
||||||
|
sudo chmod 600 /etc/ddns-updater/config.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
**macOS:**
|
2. Create `/etc/systemd/system/ddns-updater.service`:
|
||||||
|
|
||||||
```bash
|
```ini
|
||||||
cat /usr/local/var/log/ddns-updater.err
|
[Unit]
|
||||||
|
Description=DDNS Updater
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/local/bin/ddns-updater -config /etc/ddns-updater/config.yaml
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
User=root
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
```
|
```
|
||||||
|
|
||||||
### Docker deployment
|
3. Enable:
|
||||||
|
|
||||||
Build the image:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build -t yourname/ddns-updater:latest .
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable --now ddns-updater
|
||||||
|
sudo systemctl status ddns-updater
|
||||||
```
|
```
|
||||||
|
|
||||||
Run with a local config file:
|
***
|
||||||
|
|
||||||
|
## Production: macOS (launchd)
|
||||||
|
|
||||||
|
1. Install:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp config.yaml.example config.yaml # or make init-config
|
sudo make install
|
||||||
# edit config.yaml with your Cloudflare settings
|
sudo mkdir -p /usr/local/etc /usr/local/var/log
|
||||||
|
sudo cp config.yaml /usr/local/etc/ddns-updater.yaml
|
||||||
|
sudo chmod 600 /usr/local/etc/ddns-updater.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Create `~/Library/LaunchAgents/com.ddns-updater.plist` pointing at:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<array>
|
||||||
|
<string>/usr/local/bin/ddns-updater</string>
|
||||||
|
<string>-config</string>
|
||||||
|
<string>/usr/local/etc/ddns-updater.yaml</string>
|
||||||
|
</array>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Load:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
launchctl load ~/Library/LaunchAgents/com.ddns-updater.plist
|
||||||
|
launchctl start com.ddns-updater
|
||||||
|
```
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Docker usage
|
||||||
|
|
||||||
|
### 1. Prepare appdata on host (e.g. Unraid)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p /mnt/user/appdata/ddns-updater/logs
|
||||||
|
cp config.yaml /mnt/user/appdata/ddns-updater/config.yaml
|
||||||
|
chmod -R 775 /mnt/user/appdata/ddns-updater
|
||||||
|
```
|
||||||
|
|
||||||
|
Ensure `logging.file` in `/mnt/user/appdata/ddns-updater/config.yaml` is:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
logging:
|
||||||
|
file: "/config/logs/ddns-updater.log"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Dockerfile (multi-stage)
|
||||||
|
|
||||||
|
Already in repo, using `/config/config.yaml` inside the container and writing logs to `/config/logs`.
|
||||||
|
|
||||||
|
### 3. Run with docker
|
||||||
|
|
||||||
|
```bash
|
||||||
docker run -d \
|
docker run -d \
|
||||||
--name ddns-updater \
|
--name ddns-updater \
|
||||||
--restart unless-stopped \
|
--restart unless-stopped \
|
||||||
-v $(pwd)/config.yaml:/config/config.yaml:ro \
|
-v /mnt/user/appdata/ddns-updater:/config \
|
||||||
yourname/ddns-updater:latest
|
kccleoc/ddns-updater:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
Or with Docker Compose:
|
### 4. Docker Compose (Unraid 7 friendly)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
ddns-updater:
|
||||||
|
image: kccleoc/ddns-updater:latest
|
||||||
|
container_name: ddns-updater
|
||||||
|
restart: unless-stopped
|
||||||
|
user: "0:0"
|
||||||
|
volumes:
|
||||||
|
- /mnt/user/appdata/ddns-updater:/config
|
||||||
|
```
|
||||||
|
|
||||||
|
Bring it up from the Compose UI (or CLI):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
The container runs in the foreground inside Docker; restarts are handled by Docker’s restart policy.
|
## Makefile (Docker image build)
|
||||||
|
|
||||||
|
Usage examples:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make build-dockerimg IMAGE=kccleoc/ddns-updater:latest
|
||||||
|
make push-dockerimg IMAGE=kccleoc/ddns-updater:latest
|
||||||
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user