LittleLink Docker Compose 部署指南
LittleLink v3.11.0 Docker Compose 部署指南:官方源码构建镜像(无预构建镜像)、site 目录挂载免重启改配置、多实例复用镜像、等价 docker run 与升级回滚,含空挂载 403、端口冲突、图标 404 三条排障实录,Ubuntu 24.04.5 全量实测回显。
LittleLink Docker Compose 部署指南
目标:在 Ubuntu 24.04.5 LTS 服务器上用 Docker Compose 从零部署 LittleLink v3.11.0 个人链接导航页,覆盖源码获取、镜像构建、站点目录挂载、多实例复用、日常运维与三条排障实录。全部命令与回显均已在 Ubuntu 24.04.5 LTS(x86_64)、Docker 29.9.2 / Docker Compose v5.6.1 环境实测通过,站点监听
8141端口。
一、环境信息
本文部署环境为单台真实服务器,关键版本与规划如下:
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 24.04.5 LTS(7.0.0-38-generic,x86_64) |
| Docker | 29.9.2(build a82e528) |
| Docker Compose | v5.6.1 |
| LittleLink | v3.11.0(2026-07-28 发布,MIT 许可) |
| 基础镜像 | nginx:alpine(nginx/1.31.8) |
| 自建镜像 | littlelink:v3.11.0(95.1MB) |
| 站点目录 | /opt/littlelink/site(bind mount 进容器) |
| 对外端口 | 主实例 8141、第二实例 8144、docker run 演示 8145 |
| 自定义网络 | 10.89.68.0/24(主)、10.89.69.0/24(第二实例) |
宿主机版本实测回显:
docker --version
docker compose version
head -2 /etc/os-release
uname -mr
Docker version 29.9.2, build a82e528
Docker Compose version v5.6.1
PRETTY_NAME="Ubuntu 24.04.5 LTS"
NAME="Ubuntu"
7.0.0-38-generic x86_64
💡 技术拓展:LittleLink 的部署形态不止 Docker Compose 一种,常见渠道全量对比——
形态 原理 适用场景 静态托管(Cloudflare Pages/GitHub Pages) 直接把 index.html等静态文件推到托管平台,官方仓库自带wrangler.toml无服务器、要免费公网域名 任意 Web 服务器直放 把站点目录拷到 Nginx/Apache 根目录 已有 Web 服务器,顺手多挂一个站 Docker Compose(本文) 官方 docker/Dockerfile(nginx:alpine + 站点文件)构建镜像,site目录 bind mount服务器已容器化、要版本隔离与一键启停 纯静态镜像挂载 不构建 LittleLink 镜像,直接用 nginx:alpine挂site不想自建镜像(见「九、等价 docker run」的变体讨论) 本文采用 Docker Compose 形态,理由:与本机其他自托管组件统一管理,且官方仓库自带 Docker 支持(v3.6.0 起,PR #151),compose 文件即官方形态。
二、镜像选型说明
本节确定「用什么镜像跑 LittleLink」。关键事实:LittleLink 官方没有在 Docker Hub/ghcr 发布预构建镜像,官方仓库 docker/ 目录提供的是 Dockerfile + compose.yaml,官方推荐的容器化方式就是从源码构建——把整个项目(含站点静态文件)COPY 进 nginx:alpine,再把站点目录挂载出去供修改。
三种可选路线:
| 路线 | 做法 | 优点 | 缺点 |
|---|---|---|---|
| A. 官方源码构建(本文) | build: ./littlelink-3.11.0 + docker/Dockerfile | 与官方一致、版本可锁定、镜像自带兜底站点 | 需保留源码目录做构建上下文 |
| B. 复用已构建镜像 | 多实例共用 littlelink:v3.11.0,各自挂不同 site | 只构建一次,秒级起新实例 | 首次仍需路线 A 构建 |
| C. 裸 nginx:alpine 挂载 | image: nginx:alpine + 挂 site + 自备 nginx 配置 | 零构建 | 丢失官方内联 nginx 配置(gzip/缓存/日志到 stdout),需自己维护 |
镜像体积实测(构建完成后):
docker images littlelink:v3.11.0
docker images nginx:alpine
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
littlelink:v3.11.0 67a220909046 95.1MB 26.8MB U
nginx:alpine 785835ea65db 94.5MB 27.3MB
LittleLink 镜像比裸 nginx:alpine 仅重约 0.6MB(站点静态文件压缩后增量),因为镜像内容就是「nginx:alpine + 一份站点文件 + 一段内联 nginx 配置」。解读:选路线 A 构建一次、多实例走路线 B;路线 C 仅在无法执行构建的环境(如只允许预置镜像的运行时)考虑,且需自行补齐「七、配置参数说明」中的 nginx 配置。
三、前置条件
3.1 Docker 与 Compose 就绪
Docker 29.9.2 与 Compose v5.6.1 已安装(回显见「一、环境信息」),无需额外组件——LittleLink 无数据库、无运行时依赖,nginx:alpine 基础镜像本机已存在:
docker images nginx:alpine
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
nginx:alpine 785835ea65db 94.5MB 27.3MB
nginx 具体版本号(1.31.8)在部署完成后由响应头 Server: nginx/1.31.8 验证(见 4.3),无需单独探测。
3.2 端口空闲检查
主实例计划使用 8141 端口,先确认未被占用:
ss -ltn | grep ':8141' || echo "8141 空闲"
8141 空闲
⚠️ 注意:8142 端口在本机被 IDE 组件占用,规划端口时请避开;端口冲突的实际报错与处理见「十二、常见问题」Q2。
3.3 获取官方源码(含网络降级实录)
官方仓库为 sethcottle/littlelink(官网 littlelink.io 指向的同一仓库)。首选 git clone 拉取 v3.11.0 标签:
mkdir -p /opt/littlelink && cd /opt/littlelink
git clone --branch v3.11.0 --depth 1 https://github.com/sethcottle/littlelink.git littlelink-3.11.0
当时实测该命令在本机无输出挂起直至超时(复测 git ls-remote https://github.com/sethcottle/littlelink.git HEAD 限时 30 秒同样无任何输出、退出码 124),代理通道亦不可达;改用 curl 直连 GitHub 官方 tarball 成功——这是当前实测唯一可用渠道:
cd /opt/littlelink
curl -LO https://github.com/sethcottle/littlelink/archive/refs/tags/v3.11.0.tar.gz
输出节选(实测末行进度):
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 432k 0 432k 0 0 205k 0 --:--:-- 0:00:02 --:--:-- 423k
ls -l v3.11.0.tar.gz
tar -xzf v3.11.0.tar.gz
ls littlelink-3.11.0
-rw-r--r-- 1 root root 442372 Nov 3 02:11 v3.11.0.tar.gz
css
docker
fonts
images
index.html
LICENSE.md
privacy.html
README.md
VERSION.md
wrangler.toml
⚠️ 网络情况(2026-11-02/03 实测):
git clone/git ls-remote直连 GitHub 超时不可用、代理192.168.1.62:7897不可达;curl直连https://github.com/sethcottle/littlelink/archive/refs/tags/v3.11.0.tar.gz稳定可用(442372 字节)。复现本文时若 git 已恢复则优先 git,否则按上述 tarball 渠道下载,并校验版本(head -4 VERSION.md首行应为# LittleLink Version History、## Current Version: v3.11.0)。
3.4 准备站点目录
部署采用「镜像内置站点 + bind mount 覆盖」模式,需要先把站点文件从源码目录复制成独立的可写目录(后续所有编辑都发生在 site/,与源码目录解耦):
cd /opt/littlelink
mkdir -p site
cp -r littlelink-3.11.0/{css,fonts,images,index.html,privacy.html} site/
du -sh site
984K site
站点目录共 984K:index.html(460 行、121 个示例按钮)、css/ 3 个样式表、images/icons/ 123 个品牌 SVG 图标、fonts/ 4 个 woff2 字体、privacy.html 隐私页。解读:这就是 LittleLink 的全部「数据」——纯静态文件,没有编译产物、没有数据库。
四、部署步骤
4.1 编写 compose.yaml
在 /opt/littlelink/ 下创建 compose.yaml:
name: littlelink
services:
web:
build:
context: ./littlelink-3.11.0
dockerfile: docker/Dockerfile
image: littlelink:v3.11.0
ports:
- "8141:80"
volumes:
- ./site:/usr/share/nginx/html
networks:
- littlelink-net
restart: unless-stopped
networks:
littlelink-net:
driver: bridge
ipam:
config:
- subnet: 10.89.68.0/24
逐项说明:
name: littlelink:compose 项目名,决定容器/网络前缀(容器littlelink-web-1、网络littlelink_littlelink-net);build.context/build.dockerfile:以源码目录为构建上下文、使用官方docker/Dockerfile(内容见「七、配置参数说明」);image: littlelink:v3.11.0:给构建产物显式命名打标签,供多实例复用(见「十、多实例部署」);ports: "8141:80":容器内 nginx 监听 80,映射到宿主 8141;volumes: ./site:/usr/share/nginx/html:站点目录覆盖镜像内置副本,改文件即生效、无需重建镜像;restart: unless-stopped:宿主机重启后自动拉起,手动 stop 则不复活;networks+ 固定subnet:显式网段便于与本机其他组件网段隔离排查(不写也能跑,Docker 自动分配)。
💡 技术拓展:
restart策略共四档——
策略 行为 适用 no(默认)退出即终止 一次性任务 on-failure[:N]非 0 退出码才重启,可限次数 批处理 always无条件重启,宿主重启后也拉起 必须常驻的服务 unless-stopped同 always,但尊重手动stop本文这类常驻但需人工停用的服务 本文用
unless-stopped:既保证宿主机重启自动恢复,又允许排障时docker compose stop后不被自动拉起干扰。
4.2 构建并启动
cd /opt/littlelink
docker compose up -d --build
输出节选(实测首尾):
#10 naming to docker.io/library/littlelink:v3.11.0 done
#10 unpacking to docker.io/library/littlelink:v3.11.0 0.0s done
#10 DONE 0.1s
#11 resolving provenance for metadata file
#11 DONE 0.0s
Image littlelink:v3.11.0 Built
Network littlelink_littlelink-net Created
Container littlelink-web-1 Created
Container littlelink-web-1 Starting
Container littlelink-web-1 Started
4.3 验证运行状态
docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
littlelink-web-1 littlelink:v3.11.0 "/docker-entrypoint.…" web 12 seconds ago Up 11 seconds 0.0.0.0:8141->80/tcp, [::8141->80/tcp]
curl -sI http://localhost:8141/
HTTP/1.1 200 OK
Server: nginx/1.31.8
Date: Mon, 02 Nov 2026 17:52:09 GMT
Content-Type: text/html
Content-Length: 31818
Last-Modified: Mon, 02 Nov 2026 17:52:09 GMT
Connection: keep-alive
Vary: Accept-Encoding
ETag: "6ae8cdc9-7c4a"
Accept-Ranges: bytes
解读:200 OK + Server: nginx/1.31.8 说明镜像内 nginx 正常服务默认 index.html(31818 字节即官方默认页大小);Content-Length 可在改动站点后用于快速判断生效与否。
curl -s http://localhost:8141/ | grep -nE 'class="theme|<title>' | head -3
10:<html class="theme-auto" lang="en"> <!-- Update `class="theme-auto"` with your preference -->
17: <title>LittleLink</title>
首屏确认为官方默认状态:theme-auto(跟随系统深浅色)+ 默认标题。主题与按钮的定制方法见本专栏配置详解篇(发布后互链)。
docker compose logs --tail 5
web-1 | 2026/11/02 17:52:47 [notice] 1#1: start worker process 30
web-1 | 2026/11/02 17:52:47 [notice] 1#1: start worker process 31
web-1 | 2026/11/02 17:52:47 [notice] 1#1: start worker process 32
web-1 | 2026/11/02 17:52:47 [notice] 1#1: start worker process 33
web-1 | 2026/11/02 17:52:47 [notice] 1#1: start worker process 34
解读:nginx worker 进程正常拉起;官方 Dockerfile 把 access/error 日志软链到 stdout/stderr,因此 docker compose logs 可直接看到访问记录(见 4.4)。
4.4 验证网络与访问日志
docker network inspect littlelink_littlelink-net --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
10.89.68.0/24
curl -s -o /dev/null http://localhost:8141/ && docker compose logs --tail 2
web-1 | 10.89.68.1 - - [02/Nov/2026:17:52:09 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/8.5.0"
web-1 | 10.89.68.1 - - [02/Nov/2026:17:52:09 +0000] "GET / HTTP/1.1" 200 31818 "-" "curl/8.5.0"
解读:10.89.68.1 是宿主在自定义网络中的网关地址,说明请求确实经 8141→80 转发进入站点;访问日志实时进入容器 stdout。
五、数据持久化说明
LittleLink 是纯静态站点,没有数据库、没有应用级状态,「数据」就是 /opt/littlelink/site/ 目录本身:
| 数据 | 位置 | 持久化方式 |
|---|---|---|
| 页面与配置(index.html 即配置) | /opt/littlelink/site/ | bind mount,宿主目录即事实源 |
| 品牌图标/字体/样式 | /opt/littlelink/site/images、fonts、css | 同上 |
| 镜像 | Docker 存储 | 可随时由源码重建(up -d --build),无需备份 |
| 日志 | 容器 stdout | 由 Docker 日志驱动管理(默认 json-file) |
备份即打包站点目录:
tar -czf site-$(date +%F).tar.gz -C . site
ls -lh site-*.tar.gz
-rw-r--r-- 1 root root 415K Nov 3 02:15 site-2026-11-03.tar.gz
解读:415K 的 tar 包即全部可恢复状态;docker compose down 不会删除 site/(bind mount 宿主目录不受影响),重建实例只需恢复该目录。
六、环境变量表
LittleLink v3.11.0 官方 Dockerfile 不消费任何环境变量——它不是应用运行时,而是「静态文件 + nginx」。不存在 LISTEN_PORT、BASE_URL 之类参数;页面里的一切可配置项都在 site/index.html 内(数据模型详解见本专栏配置篇)。因此「环境变量表」在本文的对应物是 compose 服务级配置项表:
| compose 键 | 本文取值 | 默认值 | 说明 |
|---|---|---|---|
build.context | ./littlelink-3.11.0 | — | 镜像构建上下文(官方源码目录) |
build.dockerfile | docker/Dockerfile | Dockerfile | 官方 Dockerfile 路径 |
image | littlelink:v3.11.0 | <项目>-web | 显式命名供多实例复用 |
ports | "8141:80" | — | 容器内固定 80(Dockerfile 写死 listen 80),改端口只动宿主侧 |
volumes | ./site:/usr/share/nginx/html | — | 站点目录挂载,核心配置通道 |
restart | unless-stopped | no | 见 4.1 技术拓展 |
networks | 自定义 bridge + 固定 subnet | default | 隔离与可排查性 |
⚠️ 注意:想改容器内监听端口不能靠环境变量——
listen 80内联在镜像的/etc/nginx/conf.d/default.conf里,正确做法是改 compose 的宿主侧端口映射,或自建 Dockerfile 覆盖该配置(见「七、7.1」)。
七、配置参数说明(镜像内 nginx 配置)
7.1 官方 Dockerfile 逐段解读
镜像由官方 docker/Dockerfile 构建,全文如下(v3.11.0 源码 cat docker/Dockerfile 实测内容):
FROM nginx:alpine
# Copy static website files
COPY . /usr/share/nginx/html/
# Configure nginx with basic optimization and logging to stdout/stderr
RUN echo 'server { \
listen 80; \
server_name localhost; \
root /usr/share/nginx/html; \
index index.html index.htm; \
\
# Enable access logging to stdout \
access_log /dev/stdout; \
error_log /dev/stderr; \
\
# Enable gzip compression \
gzip on; \
gzip_vary on; \
gzip_types text/plain text/css application/json application/javascript; \
\
# Basic cache settings \
location ~* \\.(?:css|js|jpg|jpeg|gif|png|ico|svg)$ { \
expires 7d; \
add_header Cache-Control "public"; \
} \
}' > /etc/nginx/conf.d/default.conf
# Forward nginx logs to Docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log && \
ln -sf /dev/stderr /var/log/nginx/error.log
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
关键配置逐项说明:
| nginx 指令 | 取值 | 含义与影响 |
|---|---|---|
listen / server_name | 80 / localhost | 容器内固定 80 端口,server 名仅兜底 |
root / index | /usr/share/nginx/html / index.html index.htm | 站点根即挂载点;默认页优先 index.html |
access_log / error_log | /dev/stdout / /dev/stderr | 日志进容器标准流,docker compose logs 可见 |
gzip on + gzip_types | text/css、js、json 等 | 文本资源压缩传输 |
静态资源 location | expires 7d + Cache-Control: public | css/js/图片/SVG 缓存 7 天 |
7.2 配置生效验证(实测)
gzip 与缓存头实测:
curl -sI -H 'Accept-Encoding: gzip' http://localhost:8141/css/brands.css | grep -iE 'HTTP|content-encoding|vary'
curl -sI http://localhost:8141/css/brands.css | grep -iE 'HTTP|expires|cache-control'
curl -sI http://localhost:8141/ | grep -iE 'HTTP|cache-control|expires'
HTTP/1.1 200 OK
Vary: Accept-Encoding
Content-Encoding: gzip
HTTP/1.1 200 OK
Expires: Mon, 09 Nov 2026 18:02:36 GMT
Cache-Control: max-age=604800
Cache-Control: public
HTTP/1.1 200 OK
解读:brands.css(11597 字节)走 gzip 压缩、带 7 天缓存头(max-age=604800 = 7×86400);而 index.html 不匹配静态资源 location、无缓存头——这正是期望行为:入口页永远回源验证,静态资源长期缓存。改完 index.html 浏览器立即能拿到新内容,改 css/图标则最多滞后 7 天(强制刷新即可,见 Q4)。
八、配置文件挂载
本方案唯一需要「挂载」的配置文件就是站点目录:./site:/usr/share/nginx/html。工作机制:
- 构建时
COPY .已把源码目录整体打入镜像/usr/share/nginx/html(兜底副本); - 运行时 bind mount 用宿主
site/覆盖该目录——镜像内副本被遮蔽,nginx 读到的全部是宿主文件; - 因此修改站点文件不需要重启容器,nginx 对静态文件按请求读盘。
实测验证「免重启生效」——修改标题与主题后直接抓取:
cd /opt/littlelink/site
sed -i 's|<html class="theme-auto"|<html class="theme-dark"|' index.html
sed -i 's|<title>LittleLink</title>|<title>Quzuo Labs - 链接导航</title>|' index.html
curl -s http://localhost:8141/ | grep -nE 'class="theme|<title>' | head -3
10:<html class="theme-dark" lang="en"> <!-- Update `class="theme-auto"` with your preference -->
17: <title>Quzuo Labs - 链接导航</title>
全程无 restart、无 --build,改动即时可见。解读:这就是把「配置」放在挂载目录而非镜像内的价值——配置变更与镜像解耦。若挂载路径写错(如目录不存在),compose 会自动创建空目录挂进去,nginx 因找不到 index.html 且未开目录列表而返回 403——完整排障实录见 Q1。
九、等价 docker run
compose 主服务等价的一次性 docker run(用于无 compose 环境或临时验证):
cd /opt/littlelink
docker run -d --name littlelink-standalone -p 8145:80 -v "$PWD/site:/usr/share/nginx/html" littlelink:v3.11.0
c7b472a6a4addd6b2f2cbae42db7ea64082be5ba506b3fd27983691434f2ae55
curl -sI http://localhost:8145/ | head -6
HTTP/1.1 200 OK
Server: nginx/1.31.8
Date: Mon, 02 Nov 2026 17:52:47 GMT
Content-Type: text/html
Content-Length: 32405
Last-Modified: Mon, 02 Nov 2026 17:52:10 GMT
解读:同一镜像、同一挂载,docker run 与 compose 行为一致(Content-Length: 32405 是「八、配置文件挂载」改过标题的定制页大小,与 compose 实例相互印证)。差异仅在:--restart unless-stopped 需显式加 --restart,自定义网络需 --network,且无 compose ps/logs 的编排便利。验证完清理演示实例:
docker rm -f littlelink-standalone
十、多实例部署(复用镜像)
LittleLink 单实例即一个导航页;为不同用户/场景开多个页面时,复用 littlelink:v3.11.0 镜像、每个实例独立项目目录与站点目录即可,不必重复构建。以第二实例(Jane 的个人页)为例,目录 /opt/littlelink-jane/:
name: littlelink-jane
services:
web:
image: littlelink:v3.11.0
ports:
- "8144:80"
volumes:
- ./site:/usr/share/nginx/html
networks:
- littlelink-net
restart: unless-stopped
networks:
littlelink-net:
driver: bridge
ipam:
config:
- subnet: 10.89.69.0/24
与主实例 compose 的差异只有三处:name(项目隔离)、ports(8144)、subnet(10.89.69.0/24,避开主实例网段);image 直接引用已构建镜像、无 build 段。
启动与验证(实测):
cd /opt/littlelink-jane
mkdir -p site && cp -r /opt/littlelink/site/. site/
docker compose up -d
docker compose ps
Container littlelink-jane-web-1 Created
Container littlelink-jane-web-1 Starting
Container littlelink-jane-web-1 Started
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
littlelink-jane-web-1 littlelink:v3.11.0 "/docker-entrypoint.…" web Less than a second ago Up Less than a second 0.0.0.0:8144->80/tcp, [::8144->80/tcp]
curl -s http://localhost:8144/ | grep -nE 'class="theme|<title>' | head -3
docker network inspect littlelink-jane_littlelink-net --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
10:<html class="theme-light" lang="en"> <!-- Update `class="theme-auto"` with your preference -->
17: <title>Jane Doe - 个人链接页</title>
10.89.69.0/24
解读:第二实例的 site/ 独立编辑(示例中已改为 theme-light + 个人标题),与主实例互不影响;两实例各自独立网络与端口,docker compose ps 互不串扰。新增 N 个页面即复制该模式 N 份(端口、网段逐个错开)。
十一、常用运维命令
以下命令均在 /opt/littlelink/ 项目目录内执行,回显为实测。
11.1 状态与日志
docker compose ps
docker compose logs --tail 5
回显见 4.3/4.4 节。日志即 nginx access/error 流,排查 404/403 首选此处(见 Q1、Q3)。
11.2 停止、启动与重建
docker compose stop
docker compose ps -a
Container littlelink-web-1 Stopping
Container littlelink-web-1 Stopped
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
littlelink-web-1 littlelink:v3.11.0 "/docker-entrypoint.…" web 10 minutes ago Exited (0) Less than a second ago
docker compose up -d
Container littlelink-web-1 Starting
Container littlelink-web-1 Started
解读:stop 保留容器(Exited (0),配置不变),up -d 原地拉起;unless-stopped 策略下手动 stop 不会被自动重启干扰。
进入站点目录核对文件(不依赖宿主副本视角):
docker compose exec web sh -c 'ls /usr/share/nginx/html | head'
css
fonts
images
index.html
privacy.html
11.3 升级与回滚
升级 = 确认新版本号 → 下载新源码 → 重建镜像 → 按需同步站点新增文件。版本号不硬编码,用官方发布订阅源实查(实测回显,最新 release 更新时间 2026-07-29 即 v3.11.0):
curl -s https://github.com/sethcottle/littlelink/releases.atom | grep -m3 -E '<title>|<updated>'
<title>Release notes from littlelink</title>
<updated>2026-07-29T04:31:15Z</updated>
<updated>2026-07-29T04:49:45Z</updated>
拿到新版本号 vX.Y.Z 后,按 3.3 节同款命令下载对应 tarball(https://github.com/sethcottle/littlelink/archive/refs/tags/vX.Y.Z.tar.gz,URL 中的 vX.Y.Z 替换为上一步实查到的版本号)并解压为新源码目录,然后重建镜像并原地滚动更新:
docker compose up -d --build
回显与 4.2 节一致(Image littlelink:v3.11.0 Built → Container littlelink-web-1 Started,镜像名/版本号随 image: 键同步调整)。
⚠️ 注意:
site/目录不会被升级自动覆盖——若新版新增了 css/图标文件(如 v3.11.0 新增的.button-yt-music类与重制的 Google 系列图标),需手工把新版源码中的css/brands.css、images/icons/增量同步进site/,否则新按钮类无样式、新图标 404(现象与定位见 Q3)。回滚则把build.context指回旧版源码目录重新up -d --build,站点目录用「五、」的 tar 备份恢复。
11.4 彻底卸载
docker compose down
Container littlelink-web-1 Stopping
Container littlelink-web-1 Stopped
Container littlelink-web-1 Removing
Container littlelink-web-1 Removed
Network littlelink_littlelink-net Removing
Network littlelink_littlelink-net Removed
docker rmi littlelink:v3.11.0
rm -rf /opt/littlelink
解读:down 只删容器与网络,不动 site/ 数据;确认不再需要后再删镜像与目录。
十二、常见问题
Q1:站点目录挂成了空目录,页面返回 403 Forbidden。
现象(实测复现:故意把一个空目录挂进站点根):
mkdir -p /opt/littlelink/empty-site
docker run -d --name littlelink-empty -v /opt/littlelink/empty-site:/usr/share/nginx/html littlelink:v3.11.0
docker exec littlelink-empty sh -c 'ls -A /usr/share/nginx/html | wc -l'
IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' littlelink-empty)
curl -sI http://$IP:80/ | head -2
0
HTTP/1.1 403 Forbidden
Server: nginx/1.31.8
定位:挂载点内文件数为 0——nginx 找不到 index.html,而目录列表(autoindex)默认关闭,对目录本身返回 403 而非 404。根因通常是 compose 里 volumes 路径写错,Docker 自动创建了不存在的宿主目录。解决:清理演示实例,核对 volumes 指向真实站点目录(./site)并把文件复制进去,再复验:
docker rm -f littlelink-empty
curl -sI http://localhost:8141/ | head -1
littlelink-empty
HTTP/1.1 200 OK
Q2:端口被占用,容器起不来。
现象(实测:对已占用端口再起一个实例):
docker run -d --name littlelink-dup -p 8141:80 littlelink:v3.11.0
docker: Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint littlelink-dup (9a5f1c9ee8e93c5ff7cea666a51213a9380ff4f87b8dfaefb0df14894dc7380a): Bind for 0.0.0.0:8141 failed: port is already allocated
Run 'docker run --help' for more information
定位与解决:报错明确指出 8141 已分配。用 ss -ltnp | grep 8141 找到占用者;若是遗留实验实例,docker rm -f 后重试;若端口规划冲突,改 compose ports 宿主侧端口(如 8144,见「十、」)并同步防火墙/反代配置。
Q3:按钮图标不显示,日志里一片 404。
现象(实测:引用了不存在的图标文件):
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8141/images/icons/nonexistent.svg
docker compose logs --tail 2
404
web-1 | 2026/11/02 17:52:10 [error] 29#29: *10 open() "/usr/share/nginx/html/images/icons/nonexistent.svg" failed (2: No such file or directory), client: 10.89.68.1, server: localhost, request: "GET /images/icons/nonexistent.svg HTTP/1.1", host: "localhost:8141"
web-1 | 10.89.68.1 - - [02/Nov/2026:17:52:10 +0000] "GET /images/icons/nonexistent.svg HTTP/1.1" 404 153 "-" "curl/8.5.0"
定位:error 日志精确给出缺失文件在站点根下的路径。根因两类:手写按钮时 src 拼错,或升级后新增按钮引用了尚未同步的图标。解决:对照 site/images/icons/ 下 123 个官方 SVG 文件名修正 src,或从新版源码补齐图标文件;无需重启。
Q4:改了 CSS/图标,浏览器还是旧样式。
定位:镜像内 nginx 对 css/js/图片/SVG 设置了 expires 7d(实测响应头 Cache-Control: max-age=604800,见 7.2),而 index.html 无缓存头。所以「页面结构变了但样式没变」通常是静态资源缓存所致。解决:强制刷新(Ctrl+Shift+R);长期方案是在反代层对静态资源加版本查询串或缩短缓存期(需自建 Dockerfile 覆盖 default.conf,见「六、」注意事项)。
十三、参考链接
- LittleLink 官网:https://littlelink.io
- 官方仓库(源码/Dockerfile/compose 示例):https://github.com/sethcottle/littlelink
- 官方 Docker 支持背景(v3.6.0,PR #151):https://github.com/sethcottle/littlelink/pull/151
- 扩展品牌库 LittleLink Extended:https://github.com/sethcottle/littlelink-extended
- nginx 官方镜像:https://hub.docker.com/_/nginx
- 同类面板部署参考:《Homarr 介绍与选型指南》、《Dashy 4.9.0 Docker Compose 部署指南》、《homepage v2.7.0 Docker Compose 部署指南》、《LinkStack 4.8.8 Docker Compose 部署指南》