feat: add Docker image build target and deployment docs

This commit is contained in:
LC mac
2026-01-14 00:53:58 +08:00
parent f284863f87
commit d7285511f0
2 changed files with 135 additions and 178 deletions

View File

@@ -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
View File

@@ -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 Dockers 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
```