grocy 4.7.1 Docker Compose 部署指南

grocy 4.7.1 Docker Compose 部署(官方 README 指定镜像 lscr.io/linuxserver/grocy):持久化卷、环境变量、部署验证、数据备份与恢复闭环、升级与回滚,全程实测。

grocy自托管2026/10/23

grocy 4.7.1 Docker Compose 部署指南

目标:使用官方 README 指定的 LinuxServer.io 镜像 lscr.io/linuxserver/grocy:4.7.1,以 Docker Compose 从零部署 grocy 家庭库存管理系统,覆盖镜像选型、持久化卷、环境变量、部署验证、数据备份与恢复闭环、升级与回滚。全部命令与回显在 Ubuntu 22.04(x86_64,内核 6.8.0-138-generic)实测通过,实测时点 2026-10-23。

一、环境信息

  • 操作系统:Ubuntu 22.04(x86_64)
  • grocy 版本:4.7.1(ReleaseDate 2026-09-04)
  • 镜像:lscr.io/linuxserver/grocy:4.7.1(镜像 ID d63bffe9afb2,压缩体积约 87MB,解压后 421MB,docker compose images 实查)
  • 镜像内运行时:PHP 8.5.12 + SQLite 3.53.4(部署后经 /api/system/info 实查,满足 grocy ≥ PHP 8.5 / SQLite ≥ 3.40 的硬校验)
  • Docker Engine + Docker Compose v2(docker compose 子命令形态)
  • 服务端口:宿主机 8150 → 容器 80(HTTP;容器同时监听 443 自签名 HTTPS)
  • 数据目录:/opt/grocy/config(bind mount 到容器 /config,全部持久化数据在内)

二、镜像选型说明

2.1 为什么是 lscr.io/linuxserver/grocy

grocy 官方仓库 README(v4.7.1 tag,2026-10-23 查询)的「How to run using Docker」一节直接指向 https://hub.docker.com/r/linuxserver/grocy,即 LinuxServer.io 维护的镜像。项目自身在 GitHub Packages 发布的 ghcr.io/grocy/grocy 镜像包页已不存在(2026-10-23 实查返回 404),因此官方推荐且实际可用的形态就是 LinuxServer.io 版本。

LinuxServer.io 镜像的特点(2026-10-23 Docker Hub API 实查):

  • 跟随上游发版:4.7.1、version-v4.7.1、v4.7.1-ls346、latest 等标签均构建于 2026-10-21
  • 多架构:amd64 与 arm64v8 双架构标签(NAS 友好)
  • 内置满足要求的运行时:镜像内 PHP 8.5.12 + SQLite 3.53.4(部署后 /api/system/info 实测),无需宿主机安装任何 PHP 组件

2.2 标签选择建议

标签含义建议
4.7.1固定版本号生产推荐:升级时机自己控制
latest跟随上游最新稳定版追新可用,升级不可控
v4.7.1-ls346上游版本 + LSIO 构建号需要精确复现构建时使用

关键差异解读:latest 会在上游发新版后随构建自动前移,docker compose pull 即升级,但数据库 schema 迁移是单向的(无法自动回退);家庭使用建议固定版本号标签,升级改为「改 tag → pull → up -d」的手动动作。

三、前置条件

确认 Docker 与 Compose 可用:

docker --version
docker compose version

实测回显:

Docker version 27.5.1, build 9f9e854
Docker Compose version v2.38.2

确认 8150 端口未被占用(被占用则换一个空闲端口,同步修改 compose 文件):

ss -ltn | grep 8150 || echo "8150 free"

实测回显:

8150 free

创建数据目录:

sudo mkdir -p /opt/grocy/config

四、部署步骤

4.1 编写 docker-compose.yml

在 /opt/grocy 下创建 docker-compose.yml(compose 项目名显式声明为 grocy-4.7.1-stack,避免与其他 compose 项目同名冲突):

sudo tee /opt/grocy/docker-compose.yml > /dev/null <<'EOF'
name: grocy-4.7.1-stack

services:
  grocy:
    image: lscr.io/linuxserver/grocy:4.7.1
    container_name: grocy-4.7.1
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Shanghai
    volumes:
      - /opt/grocy/config:/config
    ports:
      - "8150:80"
    restart: unless-stopped
EOF

配置逐项说明:

  • image:固定版本号标签,见 2.2 节选型
  • container_name:固定容器名,便于 docker logs grocy-4.7.1 等命令直接引用
  • PUID/PGID:容器内进程以此身份运行,设为数据目录属主(id -u/id -g 查询),避免 bind mount 读写权限问题
  • TZ:容器时区,影响入库时间戳显示
  • volumes:/config 是全部持久化数据的挂载点(数据库、配置、证书),宿主机路径可按需调整
  • ports:宿主机 8150 映射容器 80;如需 HTTPS,再加一行 "8151:443"
  • restart: unless-stopped:开机自启、异常退出自动拉起(手动 stop 的除外)

4.2 启动

cd /opt/grocy && docker compose up -d

实测回显(首次会自动拉取镜像):

[+] Running 10/10
 ✔ Network grocy-4.7.1-stack_default  Created
 ✔ Container grocy-4.7.1              Started

查看初始化日志:

docker compose logs --tail 8 grocy

实测回显(节选):

grocy-4.7.1  | Setting resolver to  127.0.0.11
grocy-4.7.1  | Setting worker_processes to 12
grocy-4.7.1  | generating self-signed keys in /config/keys, you can replace these with your own keys if required
grocy-4.7.1  | [custom-init] No custom files found, skipping...
grocy-4.7.1  | [ls.io-init] done.

确认运行状态:

docker compose ps

实测回显:

NAME          IMAGE                             COMMAND   SERVICE   CREATED          STATUS          PORTS
grocy-4.7.1   lscr.io/linuxserver/grocy:4.7.1   "/init"   grocy     15 minutes ago   Up 15 minutes   443/tcp, 0.0.0.0:8150->80/tcp, [::]:8150->80/tcp

验证点解读:STATUS 为 Up 且端口映射 0.0.0.0:8150->80/tcp 生效即启动成功;初始化日志出现 [ls.io-init] done. 表示服务就绪。

4.3 首次访问、初始化与改密

浏览器访问 http://<服务器IP>:8150/。首次访问自动执行数据库迁移(迁移至 257,/api/system/info 的 db_version 可证),跳转登录页。

默认账号:admin / admin(grocy 迁移脚本 0027.php 创建)。登录后立即改密:用户菜单 → 用户设置 → 设置新密码。本文以 q1w2e3r4 为演示口令,用 API 修改的等价操作(q1w2e3r4 base64 为 cTF3MjNyNA==):

curl -s -c /tmp/grocy-b2-session.txt -o /dev/null -d "username=admin&password_base64=YWRtaW4=" http://localhost:8150/login
curl -s -o /dev/null -w "put=%{http_code}\n" -X PUT -b /tmp/grocy-b2-session.txt \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","first_name":"","last_name":"","password_base64":"cTF3MjNyNA=="}' \
  http://localhost:8150/api/users/1

实测回显:

put=204

验证登录页可达且新密码生效:

curl -s -o /dev/null -w "login_page=%{http_code}\n" http://localhost:8150/login
curl -s -o /dev/null -w "new_pwd => %{http_code} %{redirect_url}\n" -d "username=admin&password_base64=cTF3MjNyNA==" http://localhost:8150/login

实测回显:

login_page=200
new_pwd => 302 http://localhost:8150/

4.4 部署结果验证

经系统信息 API 核验版本链:

curl -s -b /tmp/grocy-b2-session.txt http://localhost:8150/api/system/info

实测回显:

{"grocy_version":{"Version":"4.7.1","ReleaseDate":"2026-09-04"},"php_version":"8.5.12","sqlite_version":"3.53.4","db_version":257,"os":"Linux 6.8.0-138-generic #138~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug  7 13:43:15 UTC  x86_64","client":"curl\/7.81.0"}

验证点解读:grocy_version 4.7.1、php_version 8.5.12、sqlite_version 3.53.4(≥ 3.40 达标)、db_version 257(迁移完整)即部署成功。API Key 的创建方式见《grocy 4.7.1 API 使用详解》。

五、数据持久化说明

5.1 持久化布局

/opt/grocy/config(容器内 /config)承载全部状态,关键子目录与文件:

路径(宿主机侧)内容
config/data/grocy.dbSQLite 数据库——商品、库存、用户、API Key 等全部业务数据
config/data/config.php实例配置文件(改货币、语言、首页等,见第七节)
config/data/plugins/条码查询等插件目录
config/keys/首次启动自动生成的自签名 HTTPS 密钥(日志原文:generating self-signed keys in /config/keys)

5.2 持久化实测(down/up 循环)

完整执行一次「删除运行实例 → 重新拉起」,验证数据不丢:

cd /opt/grocy && docker compose down

实测回显:

 Container grocy-4.7.1 Removed
 Network grocy-4.7.1-stack_default Removing
 Network grocy-4.7.1-stack_default Removed

确认数据库文件仍在宿主机:

ls -la /opt/grocy/config/data/grocy.db

实测回显:

-rw-r--r-- 1 1000 1000 561152 Oct 23 16:11 /opt/grocy/config/data/grocy.db

重新拉起并验证业务数据完好:

docker compose up -d

实测回显:

 Container grocy-4.7.1 Starting
 Container grocy-4.7.1 Started
curl -s -H "GROCY-API-KEY: <你的APIKey>" http://localhost:8150/api/stock | head -c 200

实测回显(此前录入的库存完整保留):

[{"amount":2,"amount_aggregated":2,"value":11,"best_before_date":"2026-10-30","amount_opened":0,"amount_opened_aggregated":0,"is_aggregated_amount":0,"due_type":1,"product_id":1,"product":{"id":1,"nam

⚠️ 注意:down 会删除容器与 compose 网络,但 bind mount 的宿主机目录不受影响——这正是持久化设计的目的。切勿把数据放在容器内部路径而不同步挂载,否则 down 即数据全失。

六、环境变量表

LinuxServer.io 镜像层环境变量(容器初始化使用):

变量默认值说明
PUID1000容器内进程运行用户 UID,应与 /opt/grocy/config 属主一致
PGID1000同上,组 ID
TZEtc/UTC时区,建议显式设为 Asia/Shanghai
DOCKER_MODS空LSIO 通用扩展机制,grocy 无需

grocy 应用层配置透传变量(GROCY_ 前缀 + 配置键全大写):镜像会把所有 GROCY_* 环境变量作为配置覆盖传给应用,优先级高于 data/config.php。实测:在 compose 的 environment 中加入:

    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Shanghai
      - GROCY_CURRENCY=CNY
      - GROCY_ENTRY_PAGE=shoppinglist

重新生效并回读(环境变量属于容器定义,必须 up -d 重建而非 restart):

docker compose up -d
curl -s -H "GROCY-API-KEY: <你的APIKey>" http://localhost:8150/api/system/config | grep -oE '"(CURRENCY|ENTRY_PAGE)":"[^"]*"'

实测回显:

"CURRENCY":"CNY"
"ENTRY_PAGE":"shoppinglist"

配置三级覆盖链(settingoverrides > GROCY_* 环境变量 > config.php)的完整实测见《grocy 4.7.1 配置参数详解》。

七、配置参数说明与配置文件挂载

部署后的实例配置文件在宿主机 /opt/grocy/config/data/config.php(容器内 /config/data/config.php),直接编辑保存即生效(无需重启,下一次请求即生效)。常用项:

sudo grep -E "Setting\('CURRENCY'|Setting\('DEFAULT_LOCALE'|Setting\('ENTRY_PAGE'" /opt/grocy/config/data/config.php

实测回显(出厂默认):

Setting('CURRENCY', 'USD');
Setting('DEFAULT_LOCALE', 'en');
Setting('ENTRY_PAGE', 'stock');
配置键默认建议
CURRENCYUSD中国使用环境改 CNY(实测改后 /api/system/config 立即回读为 CNY)
DEFAULT_LOCALEen简体中文改 zh_CN(官方本地化包内置)
ENTRY_PAGEstock登录后默认落地页,可改 shoppinglist 等
DISABLE_URL_REWRITINGfalse镜像内置 nginx 已带重写规则,保持默认

HTTPS:容器 443 端口使用 /config/keys/ 下自签名证书(首次启动自动生成),需 HTTPS 时在 compose 中追加 "8151:443" 映射并信任/替换该证书;公网部署建议前置 nginx 反代 + Let's Encrypt,grocy 侧无需改动。

💡 说明:全部 55 个配置键的逐项含义、默认值与实测效果,见《grocy 4.7.1 配置参数详解》。

八、等价 docker run 命令

与上述 compose 完全等价的单命令形态(一次性评估或无 compose 环境时使用):

docker run -d \
  --name grocy-4.7.1 \
  -p 8150:80 \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Asia/Shanghai \
  -v /opt/grocy/config:/config \
  --restart unless-stopped \
  lscr.io/linuxserver/grocy:4.7.1

两者差异:compose 提供项目化管理(name: grocy-4.7.1-stack,一条 docker compose down 即可整体下线网络+实例),单 run 形态删除时需 docker rm -f grocy-4.7.1 并自行清理网络;生产建议 compose。

九、常用运维命令

cd /opt/grocy
docker compose ps                     # 运行状态与端口映射
docker compose logs --tail 50 grocy   # 最近日志
docker compose restart grocy          # 重启进程(不重建,环境变量改动不生效)
docker compose up -d                  # 配置改动后重建生效
docker compose stop grocy             # 停止(保留实例定义)
docker compose start grocy            # 启动
docker compose down                   # 下线实例与网络(数据在宿主机不受影响)
docker compose images                 # 当前镜像与体积

docker compose images 实测回显:

CONTAINER           REPOSITORY                  TAG                 PLATFORM            IMAGE ID            SIZE                CREATED
grocy-4.7.1         lscr.io/linuxserver/grocy   4.7.1               linux/amd64         d63bffe9afb2        421MB               36 hours ago

升级流程(以未来版本 4.8.0 发布后为例):

# 1. 备份数据(见第十节)
# 2. 修改 docker-compose.yml 中镜像 tag:4.7.1 -> 4.8.0(或 latest)
# 3. 拉取并重建
docker compose pull
docker compose up -d

docker compose pull 实测回显(当前已是最新 tag 时的输出):

 Image lscr.io/linuxserver/grocy:4.7.1 Pulling
 Image lscr.io/linuxserver/grocy:4.7.1 Pulled

⚠️ 注意:升级会触发数据库 schema 迁移,迁移单向不可自动回退;grocy 4.7.0 升级说明中明确「本次更新使全部 Web 前端会话失效,需重新登录」(v4.7.0 Release Notes 实查)。回滚 = 把镜像 tag 改回旧版本并用第十节备份还原数据目录。

十、数据备份与恢复

10.1 备份

全部状态都在 /opt/grocy/config 一个目录,停机一致性备份两步:

cd /opt/grocy
docker compose stop grocy
tar czf /root/grocy-config-2026-10-23.tgz -C . config
docker compose start grocy

备份包与内容核对:

ls -la /root/grocy-config-2026-10-23.tgz
tar tzf /root/grocy-config-2026-10-23.tgz | head -5

实测回显:

-rw-r--r-- 1 root root 55756 Oct 23 16:38 /root/grocy-config-2026-10-23.tgz
config/
config/data/
config/data/plugins/
config/data/plugins/.placeholder
config/data/grocy.db

(数据量小可直接打包;如需免停机热备,可对 config/data/grocy.db 使用 SQLite 的 .backup 命令,避免拷贝到写入中间态。)

10.2 恢复(实测演练)

模拟数据目录丢失后从备份完整恢复:

cd /opt/grocy
docker compose stop grocy
mv config config.bak                # 移走当前目录模拟丢失
tar xzf /root/grocy-config-2026-10-23.tgz   # 解出 config/
docker compose start grocy

验证恢复结果(此前录入的商品仍在):

curl -s -H "GROCY-API-KEY: <你的APIKey>" http://localhost:8150/api/objects/products | head -c 150

实测回显:

[{"id":1,"name":"\u725b\u5976","description":null,"product_group_id":null,"active":1,"location_id":2,"shopping_location_id":null,"qu_id_purchase":2,"q

确认无误后清理:rm -rf /opt/grocy/config.bak。整个恢复演练实测耗时约 10 秒,恢复后用户、API Key、库存数据全部如初。

十一、常见问题(FAQ)

Q1:docker compose up -d 后浏览器打不开页面? 依次排查:docker compose ps 看状态是否 Up;docker compose logs grocy 是否有 [ls.io-init] done.;宿主机 ss -ltn | grep 8150 确认映射存在;云服务器还需放行安全组 8150 端口。

Q2:改了 compose 里的 environment(如 GROCY_CURRENCY)但配置没生效? docker compose restart 只重启进程、不会重建实例,环境变量不生效;必须 docker compose up -d 让 compose 重建容器(本文第六节实测即用此方式生效)。

Q3:页面报无权限写入 / 数据目录属主混乱? PUID/PGID 与 /opt/grocy/config 属主不一致所致。以 id -u、id -g 的输出修改 compose 中 PUID/PGID,并 chown -R 数据目录后 docker compose up -d 重建。

Q4:想用 80 端口直接访问? 把 ports 改为 "80:80";若宿主机 80 已被占用(如已有 nginx),保持高位端口 + 反向代理转发更稳。

Q5:HTTPS 提示证书不受信任? 443 用的是首次启动自动生成的自签名证书(/config/keys/)。内网可信任该证书或换自有证书;公网建议前置 nginx + Let's Encrypt 反代,grocy 保持 80 端口内部监听。

Q6:升级后要求重新登录? 正常现象。grocy 4.7.0 起认证中间件重构,升级说明明确会使全部 Web 会话失效(Release Notes 实查),重新登录即可。

Q7:如何完全卸载?

cd /opt/grocy && docker compose down
docker rmi lscr.io/linuxserver/grocy:4.7.1
sudo rm -rf /opt/grocy        # 含全部数据,确认备份后再删

十二、参考链接