群晖的docker套件从7x以后改名为 Container Manager 实际上还是原来的docker套件
群晖把 Web Station(下文使用web代替)和Container Manager (下文使用docker代替)做了联动,可以通过在docker中配置 【通过 Web Station 设置网页门户】 功能 把docker中的服务直接对公开给外网使用
配置见下图
选择对应的docker容器的端口
门户类型推荐使用 【基于名称】这样就可以直己定义一个三级域名(群晖自带的ddns定义的是二级域名,这个二级域名的证书包含了任意的三级证书)区分不同的服务了
配置好以后 通过配置的主机名就可以直接访问了。
接下来问题就来了,再重启docker 或者 重启系统的时候,你会发现上面配置的映射全都404了,
打开docker套件查看,发现docker中的服务是正常的,
再打开web套件查看,发现配置的门户全都显示服务已禁用
如下图所示
机器每次重启或者docker套件重启,都会导致这个【网络门户】显示【服务已禁用】,我联系过售后技术,也提供了远程链接支持,然并卵,售后技术并没有解决问题
我也尝试翻群晖文档,但是并没有找到相关的api,所以尝试自己在机器上尝试碰运气 看看能不能找到,
最终我在群晖的命令行工具包中找到了一个cli叫 synowebapi 经过不断地尝试,该api是一个万能工具,可以操作群晖的所有功能,基于此工具我写了个自动恢复的脚本(脚本在最后面)
使用该脚本配置了一个定时任务 每分钟触发一次 自动恢复由于docker重启或者机器重启导致的【网络门户】404的问题,配置如下
该脚本使用了如下功能
- 列出系统套件运行状态
- 获取web套件service、portal 列表
- 获取docker套件容器列表
- 停止、运行 docker容器
该脚本会自动检测套件运行状态,并且自动检查对应状态,发现无法访问的【网络门户】则自动重启对应的docker容器
#!/bin/bash DISABLE_COLOR=true BLACK="\e[30m" RED="\e[31m" GREEN="\e[32m" YELLOW="\e[33m" BLUE="\e[34m" MAGENTA="\e[35m" CYAN="\e[36m" LIGHT_GRAY="\e[37m" DARK_GRAY="\e[90m" LIGHT_RED="\e[91m" LIGHT_GREEN="\e[92m" LIGHT_YELLOW="\e[93m" LIGHT_BLUE="\e[94m" LIGHT_MAGENTA="\e[95m" LIGHT_CYAN="\e[96m" WHITE="\e[97m" END="\e[0m" if [ $DISABLE_COLOR == true ]; then BLACK="" RED="" GREEN="" YELLOW="" BLUE="" MAGENTA="" CYAN="" LIGHT_GRAY="" DARK_GRAY="" LIGHT_RED="" LIGHT_GREEN="" LIGHT_YELLOW="" LIGHT_BLUE="" LIGHT_MAGENTA="" LIGHT_CYAN="" WHITE="" END="" fi restartDockerContainer() { stop=$(synowebapi --exec api=SYNO.Docker.Container method=stop version=1 name=$1 2>/dev/null) status=$(jq '.success' <<<$stop) if [ $status == false ]; then echo -e $RED"stop container: $1 error: $stop"$END fi start=$(synowebapi --exec api=SYNO.Docker.Container method=start version=1 name=$1 2>/dev/null) status=$(jq '.success' <<<$start) if [ $status == false ]; then echo -e $RED"start container: $1 error: $stop"$END fi echo "restart container finished: $1" } checkServiceIsOffline() { echo -e "checking container: $GREEN$1$END url: $GREEN$2$END" result=$(curl -I $2 2>/dev/null | grep 200) if [ ${#result} -eq 0 ]; then echo -e "conatiner need restarted: $RED$1$END" return 1 else echo -e "container is$BLUE online$END" return 0 fi } pakcageList=$(synowebapi --exec api=SYNO.Core.Package method=list version=2 additional='["status"]' 2>/dev/null | jq -c '.data.packages | map(select(.id == "WebStation" or .id == "ContainerManager"))') isRunning=$(jq -r 'map(select(.id == "WebStation") | .additional.status) | .[]' <<<$pakcageList) if [ $isRunning != "running" ]; then echo -e "Web Station$RED not running$END exit" exit 0 fi echo "Web Station is running go next step" isRunning=$(jq -r 'map(select(.id == "ContainerManager") | .additional.status) | .[]' <<<$pakcageList) if [ $isRunning != "running" ]; then echo -e "Container Manager$RED not running$END exit" exit 0 fi echo "Container Manager is running go next step" webStationPortal=$(synowebapi --exec api=SYNO.WebStation.WebService.Portal method=list version=1 2>/dev/null | jq -c '.data.portals | map({host: .fqdn, http: .http_port[0], https: .https_port[0], service: .service, display_name: .shortcut.display_name})') webStationPortalCount=$(jq 'length' <<<$webStationPortal) if [ $webStationPortalCount -eq 0 ]; then echo -e $RED"not found Web Station portal"$END exit 0 fi echo -e "found Web Station portal count: $RED$webStationPortalCount"$END webStationService=$(synowebapi --exec api=SYNO.WebStation.WebService.Service method=list version=1 2>/dev/null | jq -c '.data.services | map(select(.category == "Docker"))') webStationServiceCount=$(jq 'length' <<<$webStationService) if [ $webStationServiceCount -eq 0 ]; then echo -e $RED"not found Web Station services exit"$END exit 0 fi echo -e "found Web Station services count: $RED$webStationServiceCount"$END dockerContainer=$(synowebapi --exec api=SYNO.Docker.Container method=list version=1 limit=-1 offset=0 type=all 2>/dev/null | jq -c '.data.containers | map(. | select(.status=="running" and .services[0] != null) | {name: .name, status: .status, id: .id, service: .services[0]})') dockerContainerCount=$(jq 'length' <<<$dockerContainer) echo -e "found docker container count: $RED$dockerContainerCount"$END for idx in $(seq 0 $(($webStationServiceCount - 1))); do echo "-------------------[$((idx + 1))]---------------------" service=$(jq -c ".[$idx]" <<<$webStationService) serviceName=$(jq -r '.display_name' <<<$service) serviceId=$(jq '.service' <<<$service) serviceEnable=$(jq '.enable' <<<$service) portal=$(jq -c "map(select(.service == $serviceId)) | .[]" <<<$webStationPortal) portalHost=$(jq -r '.host' <<<$portal) echo -e "service: $GREEN$serviceName$END enable: $BLUE$serviceEnable$END" if [ $serviceEnable == true ]; then echo -e "reverse proxy: $GREEN$portalHost$END ➡️ $GREEN$serviceName$END is$BLUE running$END skip" continue fi if [ ${#portal} -ne 0 ]; then container=$(jq -c "map(select(.service.service == $serviceId)) | .[]" <<<$dockerContainer) if [ ${#container} -eq 0 ]; then echo "service: $GREEN$serviceName$END container$RED is not found skip$END" continue fi containerName=$(jq -r '.name' <<<$container) containerStatus=$(jq -r '.status' <<<$container) echo -e "service container: $GREEN$containerName$END status: $GREEN$containerStatus$END" if [ $containerStatus != 'running' ]; then echo -e "contianer$GREEN $containerName$END is$RED not running$END skip" continue fi httpPort=$(jq '.http' <<<$portal) httpsPort=$(jq '.https' <<<$portal) proxyTarget=$(jq -r '.proxy_target' <<<$service) httpOffline=0 httpsOffline=0 if [ ${#httpPort} -ne 0 ]; then echo -e "reverse proxy found$GREEN http://$portalHost:$httpsPort $END➡️ $GREEN $proxyTarget $END" checkServiceIsOffline $containerName "http://$portalHost:$httpPort" httpOffline=$? fi if [ ${#httpsPort} -ne 0 ]; then echo -e "reverse proxy found$GREEN https://$portalHost:$httpsPort $END➡️ $GREEN $proxyTarget $END" checkServiceIsOffline $containerName "https://$portalHost:$httpsPort" httpsOffline=$? fi if [[ $httpOffline -eq 1 || $httpsOffline -eq 1 ]]; then restartDockerContainer $containerName else echo "service: $RED$serviceName is$BLUE online$END proccess next" fi else echo -e "service:$RED $serviceName is not found $END" fi done echo "script finished"
1 条回复
[…] 群晖 Web Station 网络门户 Container Manager(Docker) 重启后无法使用问题 […]