Homer Docker Compose 部署指南

Homer v26.08.3 官方镜像 b4bz/homer 的 Docker Compose 生产级部署全记录:web + 子路径双实例编排、1000:1000 权限与 INIT_ASSETS、assets 目录 bind 持久化、down/up 数据保留验证、等价 docker run、端口冲突与升级回滚实录(Ubuntu 22.04 + Docker 29.9.2 实测,2026-11-02/03)。

HomerHomerDocker面板自托管2026/11/03

Homer Docker Compose 部署指南

目标:在一台 Ubuntu 22.04 服务器上,用 Docker Compose 部署 Homer v26.08.3 官方镜像,交付"根路径实例 + 子路径实例"双编排、配置目录持久化、升级/回滚与端口冲突的完整实测流程。已在 Ubuntu 22.04(x86_64)+ Docker Engine 29.9.2 + Compose v5.6.1 实测通过。

Homer 是纯静态 YAML 仪表盘(定位与选型见《Homer 介绍与选型指南》):官方镜像 b4bz/homer 内置 lighttpd,把编译好的 Vue 静态包直接发出去,唯一的运行状态就是挂载进去的 assets 配置目录。因此它的 Compose 部署比一般面板简单得多——没有数据库、没有首启初始化脚本,编排的全部工作量在"目录权限、端口与子路径"三件事上。本篇逐一实测并固化。

一、环境信息

项目取值
服务器操作系统Ubuntu 22.04(x86_64)
Docker Engine / Compose29.9.2 / v5.6.1(docker compose 子命令)
Homer 版本v26.08.3(CalVer,2026-08-30 发布)
镜像b4bz/homer:v26.08.3(镜像 ID febc8967c9f7,与 latest 同 digest)
项目工作目录/opt/data/quzuo/tmp/homer(本篇实测目录,读者可换成任意路径如 /opt/homer,下文相对路径均以此为根)
Compose 项目名homer-v26.08.3-stack(compose 文件 name: 显式指定)
服务 / 实例homer → 根路径实例,宿主 8129 → 服务内 8080;homer-sub → 子路径实例,宿主 8131,SUBFOLDER=/homer
内部网络user-defined bridge homer-v26083-stack_homer-net,网段 10.89.56.0/24
配置持久化bind:./stack/data/assets → /www/assets(web 实例)、./stack/data/sub/assets → /www/assets(子路径实例)
运行身份user: "1000:1000"(与镜像默认用户一致)

💡 说明:Homer 官方镜像内 lighttpd 固定监听 8080(可用 PORT 环境变量改内部端口,见 4.4 与六章),宿主侧发布端口自选;本篇用 8129/8131 避开常用端口占用。

二、镜像选型说明

Homer 官方在 Docker Hub 发布 b4bz/homer(维护者即项目作者 bastienwirtz),无需自建。真正要选的是版本标签策略:

选型项本方案取值理由
镜像仓库b4bz/homer(官方)唯一官方发行镜像,内置 lighttpd + 静态包,内容体积仅 6.86MB
版本标签v26.08.3(固定)生产固定小版本;latest 仅用于演示"与固定版当前同 digest"
基底官方镜像自带(lighttpd 1.4.85)静态站无运行时依赖,不存在 Python/Node 基底选型问题

本机实测两个标签并存时的对照(docker images 回显,Docker 29 以 DISK USAGE/CONTENT SIZE 两列展示):

IMAGE                 ID             DISK USAGE   CONTENT SIZE   EXTRA
b4bz/homer:latest     febc8967c9f7       24.5MB         6.86MB   U
b4bz/homer:v26.08.2   83e40d1b7c9d       25.6MB         7.24MB
b4bz/homer:v26.08.3   febc8967c9f7       24.5MB         6.86MB   U

latest 与 v26.08.3 镜像 ID 相同(febc8967c9f7),即当前 latest 就指向 v26.08.3;但 latest 会随官方发版漂移,编排文件里务必写死标签。

💡 技术拓展:Homer 的三种官方发行形态——

形态载体适用
官方镜像 b4bz/homer(本篇)静态包 + lighttpd,约 25MB有 Docker 的服务器/NAS,一条 compose 搞定
静态包 homer.zip纯 HTML/JS/CSS已有 Nginx/Caddy 等 Web 服务器,解压即用(见 A1 快速开始方式三)
源码构建pnpm build 产出 /dist需要改前端源码的开发者

三者产物同一份静态包,配置格式完全一致,本篇的 assets 目录可直接迁移给任一形态。

三、前置条件

  1. Docker Engine 与 Compose v2+ 子命令可用:
docker version --format "{{.Server.Version}}"
docker compose version

回显(实测):

29.9.2
Docker Compose version v5.6.1
  1. 宿主发布端口空闲(本篇用 8129/8131,8130 是其他服务占用示例):
ss -ltn | grep -E ":(8129|8130|8131)\b"

回显(实测,部署前 8130 已被本机其他进程监听,8129/8131 空闲):

LISTEN 0      4096         0.0.0.0:8131       0.0.0.0:*
LISTEN 0      4096         0.0.0.0:8129       0.0.0.0:*
LISTEN 0      511        127.0.0.1:8130       0.0.0.0:*
LISTEN 0      4096            [::]:8131          [::]:*
LISTEN 0      4096            [::]:8129          [::]:*
  1. 镜像可拉取(Docker Hub 直连或已配置镜像加速;无法直连的环境按 experiment 惯例走代理拉取后 docker load);
  2. 磁盘余量 ≥ 100MB(两个版本镜像合计约 50MB + 配置目录 KB 级,实测见二章回显)。

四、部署步骤

4.1 建立项目目录与配置目录

mkdir -p /opt/data/quzuo/tmp/homer/stack/data/assets
mkdir -p /opt/data/quzuo/tmp/homer/stack/data/sub/assets
chown -R 1000:1000 /opt/data/quzuo/tmp/homer/stack/data

目录规划:

/opt/data/quzuo/tmp/homer/stack/
├── docker-compose.yml       # 编排:双实例、端口、网络
└── data/
    ├── assets/              # web 实例配置目录(bind → /www/assets)
    └── sub/assets/          # 子路径实例配置目录(bind → /www/assets)

⚠️ 注意:chown 1000:1000 这步不能省。官方镜像默认以 uid/gid 1000 运行 lighttpd,INIT_ASSETS=1 时首启要往 /www/assets 写示例配置——目录属主不匹配会直接卡在 restarting(排障实录见 11.2)。

4.2 编写 docker-compose.yml

/opt/data/quzuo/tmp/homer/stack/docker-compose.yml 全文:

name: homer-v26.08.3-stack

services:
  homer:
    image: b4bz/homer:v26.08.3
    container_name: homer-v26.08.3-web
    ports:
      - "8129:8080"
    volumes:
      - ./data/assets:/www/assets
    environment:
      - INIT_ASSETS=1
    user: "1000:1000"
    restart: unless-stopped
    networks:
      - homer-net

  homer-sub:
    image: b4bz/homer:v26.08.3
    container_name: homer-v26.08.3-sub
    ports:
      - "8131:8080"
    volumes:
      - ./data/sub/assets:/www/assets
    environment:
      - INIT_ASSETS=0
      - SUBFOLDER=/homer
    user: "1000:1000"
    restart: unless-stopped
    networks:
      - homer-net

networks:
  homer-net:
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.56.0/24

字段解读:

字段取值作用
namehomer-v26.08.3-stack显式项目名,down 只影响本组件资源
imageb4bz/homer:v26.08.3固定版本标签,避免 latest 漂移
ports8129:8080 / 8131:8080宿主端口 → 镜像内 lighttpd 8080
volumes./data/*/assets:/www/assets配置目录 bind 挂载,面板唯一状态所在
environmentINIT_ASSETS / SUBFOLDER首启是否落示例配置 / 子路径托管
user"1000:1000"与镜像默认用户一致,保证 assets 可写
restartunless-stopped宿主机重启后面板自动拉起
networks固定网段 10.89.56.0/24显式规划,避免与既有 bridge 网络冲突

两个实例的分工:homer(web)挂正式配置、开 INIT_ASSETS=1 便于空目录起步;homer-sub 演示 SUBFOLDER=/homer 子路径托管(前置反代只转发 /homer/ 前缀时的形态),INIT_ASSETS=0 关闭示例落盘、由运维自己放配置。

4.3 准备配置(或让 INIT_ASSETS 自动生成)

web 实例目录为空时,首启会自动写入官方示例配置。本篇实验直接放入自写配置(字段逐项含义见《Homer v26.08.3 配置参数详解》),核心骨架:

---
title: "Home Lab"
subtitle: "G27 面板实测"
documentTitle: "HomeLab Dashboard"
logo: "assets/logo.png"
header: true
footer: '<p>Homer v26.08.3 实测 // <a href="https://github.com/bastienwirtz/homer">GitHub</a></p>'
columns: "4"
connectivityCheck: true

defaults:
  layout: columns
  colorTheme: dark
  iconWidth: auto

theme: default

stylesheet:
  - "assets/custom.css"

colors:
  light:
    highlight-primary: "#3367d6"
    background: "#f5f5f5"
  dark:
    highlight-primary: "#1f6f54"
    background: "#131313"
    card-background: "#2b2b2b"

message:
  style: "is-info"
  title: "实验环境"
  icon: "fas fa-flask"
  content: "Homer v26.08.3 配置实测进行中"

links:
  - name: "GitHub"
    icon: "fab fa-github"
    url: "https://github.com/bastienwirtz/homer"
    target: "_blank"
  - name: "第二页"
    icon: "fas fa-file-alt"
    url: "#page2"

updateIntervalMs: 30000

services:
  - name: "基础设施"
    icon: "fas fa-server"
    class: "highlight-purple"
    items:
      - name: "本面板"
        logo: "assets/tools/sample.png"
        subtitle: "Homer 自身"
        tag: "panel"
        tagstyle: "is-success"
        keywords: "homer dashboard 面板"
        url: "http://127.0.0.1:8129/"
        target: "_self"
        quick:
          - name: "配置"
            url: "http://127.0.0.1:8129/assets/config.yml"
            icon: "fas fa-file-code"
            target: "_blank"
      - name: "Wikipedia 连通测试"
        type: Ping
        icon: "fas fa-network-wired"
        url: "https://www.wikipedia.org/"
  - name: "空分组示例"
    icon: "fas fa-box"
    items:
      - name: "占位书签"
        subtitle: "无 URL 的卡片"
        tag: "app"
        url: "#"

同时放入第二页 page2.yml(links: 里 url: "#page2" 即加载它)与自定义样式 custom.css:

---
subtitle: "这是第二个仪表盘页面"
message: ~
links:
  - name: "Home"
    icon: "fas fa-home"
    url: "#"
  - name: "GitHub"
    icon: "fab fa-github"
    url: "https://github.com/bastienwirtz/homer"
    target: "_blank"
services:
  - name: "第二页的应用组"
    icon: "fas fa-cloud"
    items:
      - name: "Awesome app on page2"
        logo: "assets/tools/sample.png"
        subtitle: "多页面演示书签"
        tag: "app"
        url: "https://www.reddit.com/r/selfhosted/"
        target: "_blank"
/* Homer 自定义样式:加宽主容器 */
body #main-section .container {
    max-width: 2000px;
}

子路径实例先复用同一份配置:

cp stack/data/assets/config.yml stack/data/sub/assets/config.yml

4.4 启动服务栈

cd /opt/data/quzuo/tmp/homer
docker compose -f stack/docker-compose.yml up -d

回显(实测):

 Network homer-v26083-stack_homer-net Creating
 Network homer-v26083-stack_homer-net Creating
 Network homer-v26083-stack_homer-net Created
 Network homer-v26083-stack_homer-net Created
 Container homer-v26.08.3-sub Creating
 Container homer-v26.08.3-web Creating
 Container homer-v26.08.3-web Created
 Container homer-v26.08.3-sub Created
 Container homer-v26.08.3-web Starting
 Container homer-v26.08.3-sub Starting
 Container homer-v26.08.3-web Started
 Container homer-v26.08.3-sub Started

查看运行状态与端口发布:

docker compose -f stack/docker-compose.yml ps
NAME                 IMAGE                 COMMAND                  SERVICE     CREATED         STATUS                   PORTS
homer-v26.08.3-sub   b4bz/homer:v26.08.3   "/bin/sh /entrypoint…"   homer-sub   4 seconds ago   Up 3 seconds (healthy)   0.0.0.0:8131->8080/tcp, [::]:8131->8080/tcp
homer-v26.08.3-web   b4bz/homer:v26.08.3   "/bin/sh /entrypoint…"   homer       4 seconds ago   Up 3 seconds (healthy)   0.0.0.0:8129->8080/tcp, [::]:8129->8080/tcp

4.5 验证版本与配置可达

curl -s http://127.0.0.1:8129/VERSION
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8129/
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8129/assets/config.yml
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8129/assets/page2.yml
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8129/assets/custom.css

回显(实测):

26.08.3
200
200
200
200

/VERSION 是镜像内置的版本探针文件;assets/*.yml 返回 200 即证明配置目录挂载成功、浏览器端能拉到 YAML。首页 HTML 骨架(实测节选)只有一个挂载点 div,其余全部由 JS 渲染:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="assets/icons/favicon.ico" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0,viewport-fit=cover">
    <title>Homer</title>
    <script type="module" crossorigin src="./resources/index-C32yDzkE.js"></script>
    <link rel="stylesheet" crossorigin href="./resources/index-CyPCBeHl.css">
  <link rel="manifest" href="./assets/manifest.json" crossorigin="use-credentials"><script id="vite-plugin-pwa:register-sw" src="./registerSW.js"></script></head>
  <body>
    <div id="app-mount"></div>
  </body>
</html>

浏览器访问 http://<服务器IP>:8129 看到 "Home Lab" 面板即部署成功。

4.6 验证子路径实例

curl -s http://127.0.0.1:8131/homer/VERSION
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8131/homer/
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8131/homer/assets/config.yml

回显(实测):

26.08.3
200
200

SUBFOLDER=/homer 让页面与资源引用都带 /homer 前缀,配合反代只转发该前缀即可多面板同域共存。实测另有一个值得知道的细节:curl http://127.0.0.1:8131/assets/config.yml(不带前缀的根路径)同样返回 200——SUBFOLDER 改写的是页面内的资源引用路径,lighttpd 的静态目录本身仍挂在根下,做访问控制时不要把"根路径可直连"误当成子路径隔离。

五、数据持久化说明

Homer 没有数据库、没有服务端状态,全部可持久化内容就是 /www/assets 一个目录:

服务内路径内容持久化方式宿主位置
/www/assets/config.yml主配置(唯一状态文件)bindstack/data/assets/
/www/assets/page2.yml第二页配置bind同上
/www/assets/custom.css自定义样式bind同上
/www/assets/logo.png、tools/、icons/图标与 PWA 素材bind同上
/www/assets/themes/主题目录(walkxcode 等)镜像内置,不在挂载内—

持久化验证——down 再 up,配置原样恢复:

docker compose -f stack/docker-compose.yml down
docker compose -f stack/docker-compose.yml up -d
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8129/assets/config.yml

回显(实测):

 Container homer-v26.08.3-web Stopping
 Container homer-v26.08.3-sub Stopping
 Container homer-v26.08.3-web Stopped
 Container homer-v26.08.3-web Removing
 Container homer-v26.08.3-sub Stopped
 Container homer-v26.08.3-sub Removing
 Container homer-v26.08.3-web Removed
 Container homer-v26.08.3-sub Removed
 Network homer-v26083-stack_homer-net Removing
 Network homer-v26083-stack_homer-net Removed
 Network homer-v26083-stack_homer-net Creating
 Network homer-v26083-stack_homer-net Creating
 Network homer-v26083-stack_homer-net Created
 Network homer-v26083-stack_homer-net Created
 Container homer-v26.08.3-sub Creating
 Container homer-v26.08.3-web Creating
 Container homer-v26.08.3-web Created
 Container homer-v26.08.3-sub Created
 Container homer-v26.08.3-web Starting
 Container homer-v26.08.3-sub Starting
 Container homer-v26.08.3-web Started
 Container homer-v26.08.3-sub Started
200

重建后 config.yml 仍 200、内容未变(备份/恢复演练见运维篇)。因为状态只有这一个目录,volumes 用 bind 而不是命名卷——配置即文件,直接进宿主目录才能被 git 管理、被 tar 备份。

💡 说明:INIT_ASSETS=1 只在 /www/assets 里没有 config.yml 时落示例文件,已有配置时不覆盖;子路径实例设 INIT_ASSETS=0 跳过这步,目录保持干净由运维投放配置。

六、环境变量说明

官方镜像只认 4 个环境变量(README 原文口径 + 本篇实测):

变量默认值本方案取值说明
INIT_ASSETS1web=1 / sub=0首启空目录时自动写入示例配置与图标素材;要求目录对 1000:1000 可写
SUBFOLDER空sub=/homer子路径托管,页面资源引用加前缀(如 <http://my-domain/homer>)
PORT8080未改镜像内 lighttpd 监听端口;改动后 compose 的 ports 右侧要同步(实测见九章)
IPV6_DISABLE0未改置 1 关闭 IPv6 监听(实测对照见九章)

⚠️ 注意:运行身份不要用环境变量设 GID/UID(官方 troubleshooting 明确禁止,也不要用 0:0 root 运行),统一用 compose 的 user: 字段。

七、配置参数说明(速览)

config.yml 顶层键实测清单(python yaml 解析本方案配置文件的输出):

config.yml OK, top keys: ['title', 'subtitle', 'documentTitle', 'logo', 'header', 'footer', 'columns', 'connectivityCheck', 'defaults', 'theme', 'stylesheet', 'colors', 'message', 'links', 'updateIntervalMs', 'services']
page2.yml OK, top keys: ['subtitle', 'message', 'links', 'services']

各块一句话含义(逐项详解、智能卡 50+ 清单与生产模板见《Homer v26.08.3 配置参数详解》):

键本方案取值一句话含义
title / subtitleHome Lab / G27 面板实测页头大标题与副标题
documentTitleHomeLab Dashboard浏览器标签页文字
logo / iconassets/logo.png页头图标(icon: 可用 Font Awesome 类名二选一)
header / footertrue / HTML 串页头显隐;页脚 HTML(false 隐藏)
columns"4"卡片列数(1/2/3/4/6/12 或 auto)
connectivityChecktrue周期 HEAD 探测面板自身,断连/会话过期提示
defaults.layoutcolumns布局:columns 或 list
defaults.colorThemedark默认配色:auto/light/dark
themedefault主题:default/walkxcode/neon 或社区主题
stylesheetassets/custom.css追加自定义 CSS
colorslight/dark 两组CSS 变量逐色覆盖
messageis-info 横幅顶部消息条(可接 JSON 端点)
linksGitHub + #page2顶部导航;#page2 即多页面
updateIntervalMs30000智能卡全局刷新周期(毫秒,最小 1000)
services2 组分组与卡片本体,type: 启用智能卡

八、配置文件挂载方式

标准形态就是 4.1/4.2 的整目录 bind:./data/assets:/www/assets。改配置不需要重启任何进程——浏览器每次加载页面都重新 fetch assets/config.yml,实测热加载序列:

curl -s http://127.0.0.1:8129/assets/config.yml | grep -E '^title|^subtitle'
sed -i 's/^title: "Home Lab"/title: "Home Lab C1"/' stack/data/assets/config.yml
curl -s http://127.0.0.1:8129/assets/config.yml | grep '^title'
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8129/

回显(实测,全程未重启服务进程):

title: "Home Lab"
subtitle: "G27 面板实测"
title: "Home Lab C1"
200

再改回原值即恢复稳态(title: "Home Lab",实测验证通过)。

替代形态是单文件挂载,适合配置已在宿主 git 仓库里、只想投一个文件的场景:

volumes:
  - ./config.yml:/www/assets/config.yml:ro

⚠️ 注意:单文件 :ro 后 INIT_ASSETS=1 会因目录不可写而报错(见 11.2),需改 INIT_ASSETS=0;且 page2.yml、custom.css、logo.png 等其余 assets 文件还得另行挂载,一般不如整目录方案省事。

九、等价 docker run

compose 的运行时等价命令(web 实例,同挂载同用户;执行前先 docker compose -f stack/docker-compose.yml stop homer 腾出 8129):

docker run -d --name homer-v26.08.3-run -p 8129:8080 --user 1000:1000 \
  -e INIT_ASSETS=0 \
  -v /opt/data/quzuo/tmp/homer/stack/data/assets:/www/assets \
  --restart=unless-stopped b4bz/homer:v26.08.3
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8129/assets/config.yml
docker rm -f homer-v26.08.3-run

回显(实测):

e6b8238fbcde8305862311513dcc62198a3d86209385c0ede07529d9452f3205
200
homer-v26.08.3-run

PORT 改内部端口演示(宿主 8129 → 服务内 9000):

docker run -d --name homer-v26.08.3-port9k -p 8129:9000 -e PORT=9000 \
  --user 1000:1000 \
  -v /opt/data/quzuo/tmp/homer/stack/data/assets:/www/assets \
  b4bz/homer:v26.08.3
curl -s http://127.0.0.1:8129/VERSION
docker rm -f homer-v26.08.3-port9k
docker compose -f stack/docker-compose.yml up -d homer

回显(实测):

26.08.3
26.08.3

IPV6_DISABLE=1 对照实测(无端口发布,直接进服务内探测):

docker run -d --name homer-ipv6test -e IPV6_DISABLE=1 -e INIT_ASSETS=0 \
  --user 1000:1000 b4bz/homer:v26.08.3
docker exec homer-ipv6test wget -q -O /dev/stdout http://127.0.0.1:8080/VERSION
docker exec homer-ipv6test wget -q -O /dev/stdout "http://[::1]:8080/VERSION"
docker exec homer-v26.08.3-web wget -q -O /dev/stdout "http://[::1]:8080/VERSION"
docker rm -f homer-ipv6test

回显(实测):

26.08.3
wget: can't connect to remote host: Connection refused
26.08.3
homer-ipv6test

IPV6_DISABLE=1 实例 IPv6 回环被拒、IPv4 正常;默认实例双栈可达。纯内网 IPv4 环境可置 1 减少一个监听面。

十、常用运维命令

操作命令
状态docker compose -f stack/docker-compose.yml ps
跟踪日志docker compose -f stack/docker-compose.yml logs -f homer
重启实例docker compose -f stack/docker-compose.yml restart homer
进入实例docker compose -f stack/docker-compose.yml exec homer sh
停止并删除栈(配置在宿主目录,天然保留)docker compose -f stack/docker-compose.yml down
升级/回滚版本改 compose 的 image 标签后 up -d(实测见 11.3)
备份配置tar czf homer-assets-backup-$(date +%Y%m%d).tar.gz -C stack/data assets

实测节选——日志尾部(lighttpd 访问日志直通 stdout,健康检查与业务请求都可见):

docker compose -f stack/docker-compose.yml logs --tail 5 homer
homer-v26.08.3-web  | 2026-11-02 17:06:31: (../src/server.c.2384) server stopped by UID = 0 PID = 0
homer-v26.08.3-web  | Starting webserver
homer-v26.08.3-web  | 2026-11-02 17:06:34: (../src/server.c.1973) server started (lighttpd/1.4.85)
homer-v26.08.3-web  | 10.89.56.1 127.0.0.1:8129 - [02/Nov/2026:17:06:35 +0000] "GET /VERSION HTTP/1.1" 200 7 "-" "curl/8.5.0"
homer-v26.08.3-web  | 10.89.56.1 127.0.0.1:8129 - [02/Nov/2026:17:06:54 +0000] "GET /assets/config.yml HTTP/1.1" 404 158 "-" "curl/8.5.0"

实测节选——资源占用(静态站 + lighttpd 单进程,常驻内存约 1 MiB):

docker stats --no-stream homer-v26.08.3-web
CONTAINER ID   NAME                 CPU %     MEM USAGE / LIMIT     MEM %     NET I/O        BLOCK I/O   PIDS
2d88d21dd626   homer-v26.08.3-web   0.00%     1.055MiB / 15.57GiB   0.01%     3.2kB / 716B   0B / 0B     1

PIDS=1、MEM 1.055MiB——树莓派级硬件承载毫无压力,这也是 Homer "Low / No maintenance" 定位的量化注脚。

十一、常见问题

11.1 宿主端口已被占用,容器起不来

现象:把发布端口指向已被监听的 8130 起服务,docker run 直接报错(实测故意撞端口复现):

docker: Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint homer-v26.08.3-porttest (a996e7f527391eef2f50e205b43073e1703200e736c84374db4187fea5f3b263): failed to bind host port 0.0.0.0:8130/tcp: address already in use

定位:ss -ltn | grep ':8130 ' 找到占用进程。解决:换宿主端口(Homer 只在意 ports 左侧,右侧 8080 不动即可);清理失败残留用 docker rm -f homer-v26.08.3-porttest。

11.2 容器反复 restarting / 示例配置没落盘

现象:INIT_ASSETS=1 启动后容器不停重启,日志给出明确原因(官方 troubleshooting 原文场景):

Assets directory not writable. Check assets directory permissions & docker user or skip default assets install by setting the INIT_ASSETS env var to 0

定位:挂载目录属主与容器用户(默认 1000:1000)不一致。解决二选一:

chown -R 1000:1000 /your/assets/folder/

或改 compose 的 user: 匹配目录属主。官方明确警告:不要用环境变量设 GID/UID,不要用 0:0 root 运行(安全风险且不保证可用)。若配置是自己投放的,直接 INIT_ASSETS=0 跳过示例落盘。

11.3 升级与回滚实测(v26.08.3 ↔ v26.08.2)

升级/回滚 Homer 就是换一个静态包——改 compose 标签重建即可,配置目录不动。实测回滚演练:

sed -i "s/v26.08.3/v26.08.2/" stack/docker-compose.yml
docker compose -f stack/docker-compose.yml up -d homer
curl -s http://127.0.0.1:8129/VERSION

回显(实测节选):

 Image b4bz/homer:v26.08.2 Pulled
 Container homer-v26.08.3-web Recreate
 Container homer-v26.08.3-web Recreated
 Container homer-v26.08.3-web Starting
 Container homer-v26.08.3-web Started
26.08.2

再改回 v26.08.3 执行同样的 up -d,/VERSION 回到 26.08.3(实测通过)。注意两点:容器名里的版本号只是命名习惯,不随镜像变;config.yml 用的智能卡 type 若为目标版本没有的组件(如 v26.08.3 新增的 Seerr),回滚后该卡片渲染为普通链接卡,不报错但丢状态展示。

11.4 面板打开空白 / config.yml 404

现象:页面框架出来了但没有任何卡片,curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8129/assets/config.yml 返回 404(实测误删文件后复现)。

定位:assets 目录里没有 config.yml(挂载路径写错、或文件被删)。日志侧同步可见 GET /assets/config.yml HTTP/1.1" 404。

解决:从备份恢复(实测):

tar xzf homer-assets-backup-20261103.tar.gz -C stack/data
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:8129/assets/config.yml
200

刷新浏览器即恢复。备份恢复完整流程与 YAML 语法错误处置见运维篇。

十二、参考链接

Homer Docker Compose 部署指南 - Quzuo