昱君-NAS容器管理系统的完整API接口说明
📖 简介
本文档提供了昱君-NAS容器管理系统的完整API接口说明,所有API均支持通过API Key进行认证访问。
💡 基础信息
- 基础URL:
http://your-nas-ip:9527- 响应格式: JSON
- 字符编码: UTF-8
🔑 认证方式
API Key 认证
在所有API请求的HTTP Header中添加以下字段:
X-API-Key: YOUR_API_KEY_HERE
获取API Key
- 登录Web管理界面
- 在左侧找到"API 访问控制"卡片
- 点击"启用"开关
- 点击"刷新"按钮生成新的API Key
- 点击"复制"按钮复制Key
⚠️ 安全建议:
- 请勿将API Key硬编码在公开的代码仓库中
- 建议使用环境变量或配置文件管理API Key
- 如发现Key泄露,请立即在Web界面刷新
- API Key永不过期,除非手动刷新
认证失败响应
{
"success": false,
"message": "未授权"
}
HTTP状态码:401 Unauthorized
🔌 API 端点
1. 获取容器列表
GET /api/containers
获取系统中所有容器的详细信息列表
请求参数
无需参数
请求示例
curl -X GET http://192.168.1.100:9527/api/containers \
-H "X-API-Key: abc123xyz456"
响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
success |
boolean | 请求是否成功 |
data |
array | 容器信息数组 |
data[].id |
string | 容器ID(12位短ID) |
data[].name |
string | 容器名称 |
data[].image |
string | 镜像名称(含标签) |
data[].state |
string | 运行状态:running 或 stopped |
data[].has_update |
boolean | 是否有可用更新 |
data[].auto_update |
boolean | 是否启用自动更新 |
last_check |
string | 最后检查时间(ISO 8601格式) |
成功响应示例
{
"success": true,
"data": [
{
"id": "a1b2c3d4e5f6",
"name": "nginx",
"image": "nginx:latest",
"repository": "nginx",
"tag": "latest",
"is_latest": true,
"status": "running",
"state": "running",
"created": "2025-01-15T10:30:00.000000000Z",
"has_update": false,
"update_status": "up-to-date",
"auto_update": true
},
{
"id": "f6e5d4c3b2a1",
"name": "mysql",
"image": "mysql:8.0",
"repository": "mysql",
"tag": "8.0",
"is_latest": false,
"status": "running",
"state": "running",
"created": "2025-01-14T15:20:00.000000000Z",
"has_update": false,
"update_status": "unknown",
"auto_update": false
}
],
"last_check": "2025-01-15T12:00:00"
}
2. 检查更新
POST /api/check-updates
检查容器镜像是否有可用更新
请求参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
container_name |
string | 可选 | 指定要检查的容器名称。如果不提供,则检查所有容器。示例:"nginx" |
请求示例
# 检查所有容器
curl -X POST http://192.168.1.100:9527/api/check-updates \
-H "X-API-Key: abc123xyz456" \
-H "Content-Type: application/json" \
-d '{}'
# 检查指定容器
curl -X POST http://192.168.1.100:9527/api/check-updates \
-H "X-API-Key: abc123xyz456" \
-H "Content-Type: application/json" \
-d '{"container_name": "nginx"}'
响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
success |
boolean | 请求是否成功 |
data |
array | 检查结果数组 |
data[].container_id |
string | 容器ID |
data[].container_name |
string | 容器名称 |
data[].image |
string | 镜像名称 |
data[].local_digest |
string | 本地镜像摘要(12位) |
data[].remote_digest |
string | 远程镜像摘要(12位) |
data[].has_update |
boolean | 是否有更新 |
data[].status |
string | 更新状态:updatable 或 up-to-date |
成功响应示例
{
"success": true,
"data": [
{
"container_id": "a1b2c3d4e5f6",
"container_name": "nginx",
"image": "nginx:latest",
"local_digest": "sha256:abc123",
"remote_digest": "sha256:def456",
"has_update": true,
"status": "updatable",
"check_method": "online"
},
{
"container_id": "f6e5d4c3b2a1",
"container_name": "redis",
"image": "redis:latest",
"local_digest": "sha256:xyz789",
"remote_digest": "sha256:xyz789",
"has_update": false,
"status": "up-to-date",
"check_method": "online"
}
]
}
💡 说明:
- 只有标签为
latest的容器才会被检查- 检查过程会访问Docker镜像仓库,可能需要几秒到几十秒
- 如果配置了代理,会自动使用代理访问
3. 更新容器
POST /api/update-container
更新指定容器到最新镜像版本
请求参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
container_name |
string | 必填 | 要更新的容器名称。示例:"nginx" |
请求示例
curl -X POST http://192.168.1.100:9527/api/update-container \
-H "X-API-Key: abc123xyz456" \
-H "Content-Type: application/json" \
-d '{"container_name": "nginx"}'
响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
success |
boolean | 请求是否成功提交 |
message |
string | 响应消息 |
成功响应示例
{
"success": true,
"message": "容器 [nginx] 更新任务已启动"
}
失败响应示例
{
"success": false,
"message": "缺少容器名称"
}
⚠️ 重要提示:
- 此接口为异步操作,返回成功仅表示任务已提交
- 实际更新过程包括:拉取镜像 → 停止容器 → 删除旧容器 → 创建新容器 → 启动容器
- 更新进度可通过WebSocket实时获取,或查看日志接口
- 更新过程中容器会短暂停止服务
- 系统会自动保留原容器的所有配置(环境变量、卷、网络、端口等)
更新流程说明
- 拉取镜像: 从仓库下载最新版本镜像
- 停止容器: 优雅停止(10秒超时),超时则强制停止
- 删除旧容器: 删除旧容器实例(保留镜像)
- 创建新容器: 使用新镜像创建容器,保留原配置
- 启动容器: 启动新容器
- 清理镜像: 自动清理悬空的旧镜像
4. 自动更新管理
POST /api/toggle-auto-update
启用或禁用指定容器的自动更新功能
请求参数
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
container_name |
string | 必填 | 容器名称。示例:"nginx" |
enabled |
boolean | 必填 | 是否启用自动更新。true:启用,false:禁用 |
请求示例
# 启用自动更新
curl -X POST http://192.168.1.100:9527/api/toggle-auto-update \
-H "X-API-Key: abc123xyz456" \
-H "Content-Type: application/json" \
-d '{
"container_name": "nginx",
"enabled": true
}'
# 禁用自动更新
curl -X POST http://192.168.1.100:9527/api/toggle-auto-update \
-H "X-API-Key: abc123xyz456" \
-H "Content-Type: application/json" \
-d '{
"container_name": "nginx",
"enabled": false
}'
响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
success |
boolean | 操作是否成功 |
成功响应示例
{
"success": true
}
💡 自动更新说明:
- 启用后,系统会按照设定的时间间隔自动检查并更新容器
- 更新间隔在"自动更新设置"中配置(默认7天)
- 自动更新仅对标签为
latest的容器生效
5. 获取日志
GET /api/logs
获取系统操作日志(最近500条)
请求参数
无需参数
请求示例
curl -X GET http://192.168.1.100:9527/api/logs \
-H "X-API-Key: abc123xyz456"
响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
success |
boolean | 请求是否成功 |
data |
array | 日志条目数组 |
data[].timestamp |
string | 时间戳 |
data[].level |
string | 日志级别:INFO / SUCCESS / WARNING / ERROR |
data[].message |
string | 日志内容 |
data[].type |
string | 日志类型:system / realtime / error |
count |
integer | 日志总数 |
成功响应示例
{
"success": true,
"data": [
{
"timestamp": "2025-01-15 12:00:00",
"level": "INFO",
"message": "🔍 开始检查容器更新(在线模式⚡),共 5 个容器",
"type": "realtime"
},
{
"timestamp": "2025-01-15 12:00:05",
"level": "SUCCESS",
"message": "✅ 检查完成: 共检查 5 个容器,发现 2 个可更新 ⚡",
"type": "realtime"
},
{
"timestamp": "2025-01-15 12:05:00",
"level": "INFO",
"message": "🔄 更新容器: nginx",
"type": "realtime"
},
{
"timestamp": "2025-01-15 12:05:30",
"level": "SUCCESS",
"message": "✅ 容器 [nginx] 更新成功",
"type": "realtime"
}
],
"count": 4
}
6. 获取系统配置
GET /api/config
获取系统当前配置
请求示例
curl -X GET http://192.168.1.100:9527/api/config \
-H "X-API-Key: abc123xyz456"
成功响应示例
{
"success": true,
"data": {
"auto_update_enabled": true,
"update_interval_days": 7,
"update_interval_hours": 0,
"proxy_enabled": false,
"proxy_host": "",
"proxy_port": "",
"auto_update_containers": ["nginx", "redis"],
"api_enabled": true
}
}
💡 完整使用示例
Python 示例
使用 requests 库实现容器自动更新脚本:
#!/usr/bin/env python3
import requests
import time
# ===== 配置 =====
API_KEY = "your_api_key_here"
BASE_URL = "http://192.168.1.100:9527"
HEADERS = {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
}
# ===== 函数定义 =====
def get_containers():
"""获取所有容器列表"""
url = f"{BASE_URL}/api/containers"
response = requests.get(url, headers=HEADERS)
if response.status_code == 200:
result = response.json()
if result["success"]:
return result["data"]
return []
def check_updates(container_name=None):
"""检查容器更新"""
url = f"{BASE_URL}/api/check-updates"
data = {}
if container_name:
data["container_name"] = container_name
response = requests.post(url, headers=HEADERS, json=data)
if response.status_code == 200:
result = response.json()
if result["success"]:
return result["data"]
return []
def update_container(container_name):
"""更新指定容器"""
url = f"{BASE_URL}/api/update-container"
data = {"container_name": container_name}
response = requests.post(url, headers=HEADERS, json=data)
if response.status_code == 200:
result = response.json()
return result.get("success", False)
return False
def enable_auto_update(container_name, enabled=True):
"""启用/禁用自动更新"""
url = f"{BASE_URL}/api/toggle-auto-update"
data = {
"container_name": container_name,
"enabled": enabled
}
response = requests.post(url, headers=HEADERS, json=data)
if response.status_code == 200:
result = response.json()
return result.get("success", False)
return False
# ===== 主程序 =====
def main():
print("=== 昱君-NAS 容器管理脚本 ===\n")
# 1. 获取容器列表
print("📋 获取容器列表...")
containers = get_containers()
print(f"✅ 共找到 {len(containers)} 个容器\n")
for container in containers:
print(f" - {container['name']}: {container['state']}")
# 2. 检查所有容器更新
print("\n🔍 检查容器更新...")
updates = check_updates()
updatable = [u for u in updates if u["has_update"]]
print(f"✅ 发现 {len(updatable)} 个容器可更新\n")
# 3. 更新所有可更新的容器
if updatable:
for update_info in updatable:
container_name = update_info["container_name"]
print(f"🔄 更新容器: {container_name}")
if update_container(container_name):
print(f"✅ {container_name} 更新任务已提交")
# 等待更新完成(实际应该通过WebSocket监听)
time.sleep(30)
else:
print(f"❌ {container_name} 更新失败")
print("\n✅ 所有更新任务已完成")
else:
print("✅ 所有容器均为最新版本")
# 4. 为所有latest容器启用自动更新
print("\n⏰ 配置自动更新...")
for container in containers:
if container["is_latest"]:
name = container["name"]
if enable_auto_update(name, True):
print(f"✅ 已为 {name} 启用自动更新")
else:
print(f"❌ {name} 自动更新配置失败")
if __name__ == "__main__":
try:
main()
except Exception as e:
print(f"❌ 脚本执行失败: {e}")
JavaScript / Node.js 示例
使用 axios 库实现容器管理:
const axios = require('axios');
const API_KEY = 'your_api_key_here';
const BASE_URL = 'http://192.168.1.100:9527';
const client = axios.create({
baseURL: BASE_URL,
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json'
}
});
async function getContainers() {
try {
const response = await client.get('/api/containers');
return response.data.data;
} catch (error) {
console.error('获取容器列表失败:', error.message);
return [];
}
}
async function checkUpdates(containerName = null) {
try {
const data = containerName ? { container_name: containerName } : {};
const response = await client.post('/api/check-updates', data);
return response.data.data;
} catch (error) {
console.error('检查更新失败:', error.message);
return [];
}
}
async function updateContainer(containerName) {
try {
const response = await client.post('/api/update-container', {
container_name: containerName
});
return response.data.success;
} catch (error) {
console.error(`更新容器 ${containerName} 失败:`, error.message);
return false;
}
}
async function main() {
console.log('=== 昱君-NAS 容器管理脚本 ===\n');
// 获取容器列表
const containers = await getContainers();
console.log(`✅ 共找到 ${containers.length} 个容器\n`);
// 检查更新
const updates = await checkUpdates();
const updatable = updates.filter(u => u.has_update);
console.log(`✅ 发现 ${updatable.length} 个容器可更新\n`);
// 更新容器
for (const update of updatable) {
console.log(`🔄 更新容器: ${update.container_name}`);
await updateContainer(update.container_name);
}
console.log('\n✅ 所有任务完成');
}
main().catch(console.error);
Shell / Bash 示例
使用 curl 和 jq 实现简单的更新脚本:
#!/bin/bash
API_KEY="your_api_key_here"
BASE_URL="http://192.168.1.100:9527"
# 获取容器列表
get_containers() {
curl -s -X GET "${BASE_URL}/api/containers" \
-H "X-API-Key: ${API_KEY}"
}
# 检查更新
check_updates() {
curl -s -X POST "${BASE_URL}/api/check-updates" \
-H "X-API-Key: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{}'
}
# 更新容器
update_container() {
local container_name=$1
curl -s -X POST "${BASE_URL}/api/update-container" \
-H "X-API-Key: ${API_KEY}" \
-H "Content-Type: application/json" \
-d "{\"container_name\": \"${container_name}\"}"
}
# 主程序
echo "=== 昱君-NAS 容器管理脚本 ==="
echo
# 检查更新
echo "🔍 检查容器更新..."
updates=$(check_updates)
# 提取可更新的容器
updatable=$(echo "$updates" | jq -r '.data[] | select(.has_update==true) | .container_name')
if [ -z "$updatable" ]; then
echo "✅ 所有容器均为最新版本"
else
echo "发现以下容器可更新:"
echo "$updatable"
echo
# 更新每个容器
for container in $updatable; do
echo "🔄 更新容器: $container"
result=$(update_container "$container")
echo "$result" | jq -r '.message'
sleep 2
done
echo
echo "✅ 所有更新任务已提交"
fi
⚠️ 错误处理
常见HTTP状态码
| 状态码 | 说明 | 解决方案 |
|---|---|---|
200 |
请求成功 | 正常返回 |
400 |
请求参数错误 | 检查请求体格式和参数 |
401 |
未授权 | 检查API Key是否正确 |
404 |
资源不存在 | 检查API端点路径 |
500 |
服务器内部错误 | 查看系统日志 |
错误响应格式
所有错误响应都遵循以下格式:
{
"success": false,
"message": "错误描述信息"
}
常见错误及解决方案
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
| “未授权” | API Key无效或未提供 | 检查Header中的X-API-Key |
| “缺少容器名称” | 请求体中未提供container_name | 添加必需参数 |
| “容器不存在” | 指定的容器名称不存在 | 先调用容器列表接口确认容器名 |
| “容器未运行” | 尝试更新已停止的容器 | 先启动容器或跳过 |
✨ 最佳实践
1. API Key 安全管理
推荐做法:
# 使用环境变量管理密钥
import os
API_KEY = os.getenv("NAS_API_KEY")
if not API_KEY:
raise ValueError("请设置环境变量 NAS_API_KEY")
# 在 .env 文件中配置
NAS_API_KEY=your_actual_api_key_here
NAS_BASE_URL=http://192.168.1.100:9527
不推荐做法:
# ❌ 硬编码在代码中
API_KEY = "abc123xyz456" # 不要这样做!
2. 错误重试机制
import time
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
def create_session_with_retry():
"""创建带重试机制的session"""
session = requests.Session()
retry_strategy = Retry(
total=3, # 最多重试3次
backoff_factor=1, # 重试间隔递增
status_forcelist=[500, 502, 503, 504], # 这些状态码才重试
method_whitelist=["GET", "POST"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("http://", adapter)
session.mount("https://", adapter)
return session
# 使用示例
session = create_session_with_retry()
session.headers.update({"X-API-Key": API_KEY})
response = session.get(f"{BASE_URL}/api/containers")
3. 超时设置
# 始终设置超时,避免永久挂起
response = requests.get(
f"{BASE_URL}/api/containers",
headers={"X-API-Key": API_KEY},
timeout=10 # 10秒超时
)
4. 日志记录
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('nas_api.log'),
logging.StreamHandler()
]
)
def update_container(name):
logging.info(f"开始更新容器: {name}")
try:
response = requests.post(...)
if response.json()["success"]:
logging.info(f"容器 {name} 更新成功")
else:
logging.error(f"容器 {name} 更新失败")
except Exception as e:
logging.exception(f"更新容器 {name} 时发生异常")
5. 异步处理
对于需要更新多个容器的场景,可以使用异步并发:
import asyncio
import aiohttp
async def update_container_async(session, container_name):
url = f"{BASE_URL}/api/update-container"
data = {"container_name": container_name}
async with session.post(url, json=data) as response:
result = await response.json()
return result
async def update_all_containers(container_names):
async with aiohttp.ClientSession(
headers={"X-API-Key": API_KEY}
) as session:
tasks = [
update_container_async(session, name)
for name in container_names
]
results = await asyncio.gather(*tasks)
return results
# 使用
containers_to_update = ["nginx", "redis", "mysql"]
results = asyncio.run(update_all_containers(containers_to_update))
6. 响应验证
def validate_response(response):
"""验证API响应"""
if response.status_code != 200:
raise Exception(f"HTTP错误: {response.status_code}")
data = response.json()
if not data.get("success"):
raise Exception(f"API错误: {data.get('message', '未知错误')}")
return data
# 使用示例
try:
response = requests.get(f"{BASE_URL}/api/containers", headers=headers)
data = validate_response(response)
containers = data["data"]
except Exception as e:
logging.error(f"获取容器列表失败: {e}")
7. 配置文件管理
创建配置文件 config.ini:
[api]
base_url = http://192.168.1.100:9527
api_key = your_api_key_here
timeout = 10
[update]
auto_update = true
check_interval = 3600
max_retries = 3
读取配置:
import configparser
config = configparser.ConfigParser()
config.read('config.ini')
API_KEY = config.get('api', 'api_key')
BASE_URL = config.get('api', 'base_url')
TIMEOUT = config.getint('api', 'timeout')
📊 性能优化建议
1. 批量检查更新
# ✅ 推荐:一次检查所有容器
def check_all_updates():
response = requests.post(
f"{BASE_URL}/api/check-updates",
headers=headers,
json={} # 不指定容器名
)
return response.json()["data"]
# ❌ 不推荐:逐个检查
def check_updates_one_by_one(containers):
results = []
for container in containers:
response = requests.post(
f"{BASE_URL}/api/check-updates",
headers=headers,
json={"container_name": container["name"]}
)
results.append(response.json())
return results
2. 缓存容器列表
import time
class ContainerCache:
def __init__(self, ttl=60):
self.cache = None
self.last_update = 0
self.ttl = ttl # 缓存有效期(秒)
def get_containers(self):
now = time.time()
if self.cache is None or (now - self.last_update) > self.ttl:
# 缓存过期,重新获取
response = requests.get(
f"{BASE_URL}/api/containers",
headers=headers
)
self.cache = response.json()["data"]
self.last_update = now
return self.cache
# 使用
cache = ContainerCache(ttl=300) # 5分钟缓存
containers = cache.get_containers()
3. 连接池复用
# 复用session,避免频繁创建连接
session = requests.Session()
session.headers.update({"X-API-Key": API_KEY})
# 之后所有请求使用同一个session
response1 = session.get(f"{BASE_URL}/api/containers")
response2 = session.post(f"{BASE_URL}/api/check-updates", json={})
🔧 高级用法
定时任务集成
使用 Cron
创建脚本 /usr/local/bin/nas-update.sh:
#!/bin/bash
API_KEY="your_api_key_here"
BASE_URL="http://192.168.1.100:9527"
LOG_FILE="/var/log/nas-update.log"
echo "[$(date)] 开始检查更新" >> "$LOG_FILE"
# 检查更新
updates=$(curl -s -X POST "${BASE_URL}/api/check-updates" \
-H "X-API-Key: ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{}')
# 提取可更新的容器
updatable=$(echo "$updates" | jq -r '.data[] | select(.has_update==true) | .container_name')
if [ -z "$updatable" ]; then
echo "[$(date)] 无可用更新" >> "$LOG_FILE"
else
for container in $updatable; do
echo "[$(date)] 更新容器: $container" >> "$LOG_FILE"
curl -s -X POST "${BASE_URL}/api/update-container" \
-H "X-API-Key: ${API_KEY}" \
-H "Content-Type: application/json" \
-d "{\"container_name\": \"${container}\"}" >> "$LOG_FILE"
done
fi
echo "[$(date)] 检查完成" >> "$LOG_FILE"
添加到crontab(每天凌晨3点执行):
chmod +x /usr/local/bin/nas-update.sh
crontab -e
# 添加以下行
0 3 * * * /usr/local/bin/nas-update.sh
使用 systemd Timer
创建服务文件 /etc/systemd/system/nas-update.service:
[Unit]
Description=NAS Container Update Service
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/nas-update.sh
User=root
[Install]
WantedBy=multi-user.target
创建定时器文件 /etc/systemd/system/nas-update.timer:
[Unit]
Description=NAS Container Update Timer
Requires=nas-update.service
[Timer]
OnCalendar=daily
OnCalendar=03:00
Persistent=true
[Install]
WantedBy=timers.target
启用定时器:
systemctl daemon-reload
systemctl enable nas-update.timer
systemctl start nas-update.timer
# 查看状态
systemctl list-timers --all
Webhook 集成
接收更新通知并自动处理:
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
NAS_API_KEY = "your_api_key_here"
NAS_BASE_URL = "http://192.168.1.100:9527"
@app.route('/webhook/container-update', methods=['POST'])
def handle_update_webhook():
"""处理容器更新webhook"""
data = request.json
container_name = data.get('container_name')
if not container_name:
return jsonify({"error": "缺少容器名称"}), 400
# 调用NAS API更新容器
response = requests.post(
f"{NAS_BASE_URL}/api/update-container",
headers={"X-API-Key": NAS_API_KEY},
json={"container_name": container_name}
)
if response.json().get("success"):
return jsonify({"message": f"容器 {container_name} 更新已触发"}), 200
else:
return jsonify({"error": "更新失败"}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
通知集成
更新完成后发送通知(支持钉钉、企业微信、邮件等):
import requests
def send_dingtalk_notification(message):
"""发送钉钉通知"""
webhook_url = "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN"
data = {
"msgtype": "text",
"text": {
"content": f"【NAS容器更新】\n{message}"
}
}
requests.post(webhook_url, json=data)
def update_with_notification(container_name):
"""更新容器并发送通知"""
# 更新容器
response = requests.post(
f"{BASE_URL}/api/update-container",
headers={"X-API-Key": API_KEY},
json={"container_name": container_name}
)
if response.json().get("success"):
message = f"✅ 容器 [{container_name}] 更新成功"
send_dingtalk_notification(message)
else:
message = f"❌ 容器 [{container_name}] 更新失败"
send_dingtalk_notification(message)
📝 API变更日志
v1.0.0 (2025-01-15)
初始版本发布
- ✅ GET /api/containers - 获取容器列表
- ✅ POST /api/check-updates - 检查更新
- ✅ POST /api/update-container - 更新容器
- ✅ POST /api/toggle-auto-update - 自动更新管理
- ✅ GET /api/logs - 获取日志
- ✅ GET /api/config - 获取配置
- ✅ 支持API Key认证
🔒 安全注意事项
1. API Key保护
- ✅ 使用环境变量或加密配置文件存储
- ✅ 定期轮换API Key
- ✅ 不同应用使用不同的Key(如支持多Key则使用)
- ❌ 不要在公开代码仓库中提交
- ❌ 不要通过URL参数传递
2. 网络安全
- ✅ 在内网环境使用
- ✅ 如需公网访问,使用VPN或堡垒机
- ✅ 配置防火墙规则限制访问IP
- ❌ 不建议直接暴露到公网
3. HTTPS支持
如需加密传输,可在前端使用Nginx反向代理:
server {
listen 443 ssl http2;
server_name nas.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://127.0.0.1:9527;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
🐛 故障排查
常见问题诊断
1. API无法连接
检查清单:
# 检查服务是否运行
docker ps | grep diancup
# 检查端口是否监听
netstat -tuln | grep 9527
# 测试本地连接
curl http://127.0.0.1:9527/api/containers -H "X-API-Key: YOUR_KEY"
# 检查防火墙
iptables -L -n | grep 9527
2. 认证失败
# 验证API Key格式(应该是23位字符)
echo -n "YOUR_API_KEY" | wc -c
# 检查Header格式
curl -v http://192.168.1.100:9527/api/containers \
-H "X-API-Key: YOUR_KEY" 2>&1 | grep "X-API-Key"
3. 更新失败
查看系统日志:
# 查看容器日志
docker logs diancup --tail 100
# 或通过API获取
curl http://192.168.1.100:9527/api/logs \
-H "X-API-Key: YOUR_KEY" | jq '.data[] | select(.level=="ERROR")'
💬 技术支持
获取帮助
如有问题或建议,欢迎通过以下方式联系:
✅ 官方渠道
- 📚 博客文档: https://wiki.929722.xyz
- 📺 Bilibili: @昱君NAS
- 💬 微信: dongqc123
- 🐡 闲鱼: 昱君NAS小店
问题反馈模板
提交问题时,请提供以下信息:
**环境信息:**
- 系统版本:飞牛NAS / UNRAID / 群晖 / 其他
- Docker版本:docker version 输出
- 容器版本:yjnas/diancup:版本号
**问题描述:**
(详细描述遇到的问题)
**复现步骤:**
1. 第一步
2. 第二步
3. ...
**期望结果:**
(描述期望的行为)
**实际结果:**
(描述实际发生的情况)
**日志信息:**
```bash
docker logs diancup --tail 50
截图:
(如适用)
---
## 📚 相关资源
### 官方文档
- [使用文档](/) - 完整的功能说明和使用指南
- [博客教程](https://wiki.929722.xyz) - 详细的图文教程
- [视频教程](https://space.bilibili.com/668023659) - B站视频教程
### 示例代码
- Python示例:见上方"完整使用示例"章节
- JavaScript示例:见上方"完整使用示例"章节
- Shell示例:见上方"完整使用示例"章节
### 第三方集成
- **Home Assistant:** 可通过RESTful集成监控容器状态
- **Grafana:** 配合自定义数据源展示更新历史
- **n8n / Node-RED:** 实现自动化工作流
---
## 🎯 快速参考
### API端点速查表
| 端点 | 方法 | 功能 | 需要参数 |
|------|------|------|----------|
| `/api/containers` | GET | 获取容器列表 | 无 |
| `/api/check-updates` | POST | 检查更新 | container_name (可选) |
| `/api/update-container` | POST | 更新容器 | container_name (必需) |
| `/api/toggle-auto-update` | POST | 自动更新开关 | container_name, enabled (必需) |
| `/api/logs` | GET | 获取日志 | 无 |
| `/api/config` | GET | 获取配置 | 无 |
### HTTP状态码速查
| 状态码 | 含义 | 处理方式 |
|--------|------|----------|
| 200 | 成功 | 解析响应数据 |
| 400 | 参数错误 | 检查请求参数 |
| 401 | 未授权 | 检查API Key |
| 404 | 不存在 | 检查端点路径 |
| 500 | 服务器错误 | 查看日志或重试 |
### 一行命令速查
```bash
# 获取容器列表
curl -H "X-API-Key: KEY" http://IP:9527/api/containers
# 检查所有更新
curl -X POST -H "X-API-Key: KEY" -H "Content-Type: application/json" \
http://IP:9527/api/check-updates -d '{}'
# 更新容器
curl -X POST -H "X-API-Key: KEY" -H "Content-Type: application/json" \
http://IP:9527/api/update-container -d '{"container_name":"nginx"}'
# 获取日志
curl -H "X-API-Key: KEY" http://IP:9527/api/logs | jq '.data[-10:]'
📄 许可证
本API文档和示例代码遵循 MIT License。
Copyright (c) 2025 昱君-NAS
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
🎉 结语
感谢使用昱君-NAS容器管理系统API!
如果这份文档对你有帮助,欢迎:
- ⭐ 在博客评论区留言
- 📺 B站一键三连
- 💬 分享给有需要的朋友
- 🐛 反馈问题和建议
持续更新中,敬请关注!
评论