CRMEB容器部署java项目图片问题
1. 目的
移动端Crmeb-front.jar上传的图片,需要和管理端Crmeb-admin.jar使用同一个宿主机目录保存和访问:
宿主机:/JAVA_PROJECT/MER/dev/admin/crmebimage上传后的典型文件位置为:
/JAVA_PROJECT/MER/dev/admin/crmebimage/image/年/月/日/文件名2. 路径关系
当前部署使用 Docker。front 容器中的/app是宿主机 front 目录的挂载点(以实际${CODE_DIR}为准):
宿主机 /JAVA_PROJECT/MER/dev/front -> 容器 /app因此,下面这个参数:
--crmeb.image-path=/JAVA_PROJECT/MER/dev/admin/指向的是容器内部路径,并不会自动指向宿主机的 admin 目录。若没有 Docker volume 挂载,文件会写入容器自身的可写层,宿主机的 front 和 admin 目录都看不到。
--crmeb.image-path的值必须是容器内路径;宿主机路径需要通过volumes映射进去。
3. 推荐的目录挂载
在 front 应用的 1Panel Compose 配置中,将 admin 的图片目录挂载到 front 容器的/shared/crmebimage:
volumes:-${CODE_DIR}:/app-/JAVA_PROJECT/MER/dev/admin/p12:/app/p12-/JAVA_PROJECT/MER/dev/admin/crmebimage:/shared/crmebimage其中:
${CODE_DIR}对 front 应为/JAVA_PROJECT/MER/dev/front,可通过容器挂载列表核对。/JAVA_PROJECT/MER/dev/admin/p12:/app/p12用于挂载微信支付证书;如果证书位置不同,以实际部署为准。/JAVA_PROJECT/MER/dev/admin/crmebimage:/shared/crmebimage是本次图片共享的关键配置。- 宿主机目录不存在时先创建:
mkdir-p/JAVA_PROJECT/MER/dev/admin/crmebimageadmin 容器如果已经使用:
/JAVA_PROJECT/MER/dev/admin -> /app则 admin 继续使用/app/作为图片根目录即可。front 和 admin 实际上会访问同一个宿主机目录。
4. 启动参数
4.1 front
front 使用共享挂载点/shared/:
java-jarCrmeb-front.jar\--spring.profiles.active=beta\--wx.pay.ma.key-path=/app/p12/apiclient_cert.p12\--wx.pay.ma.private-cert-path=/app/p12/apiclient_cert.pem\--wx.pay.ma.private-key-path=/app/p12/apiclient_key.pem\--wx.pay.ma.public-key-path=/app/p12/pub_key.pem\--crmeb.image-path=/shared/证书路径仍然使用容器内的/app/p12/...,图片路径使用容器内的/shared/。不要在 front 参数中直接填写宿主机路径/JAVA_PROJECT/MER/dev/admin/,除非该路径也被挂载到容器内。
4.2 admin
先确认 admin 容器确实把宿主机/JAVA_PROJECT/MER/dev/admin挂载到/app。若是这样,admin 可以继续使用:
java-jarCrmeb-admin.jar\--spring.profiles.active=beta\--crmeb.image-path=/app/已有 admin 图片上传和访问正常时,保持其现有挂载和启动参数即可;本次只需修改 front。
5. 修改后重建 front 容器
修改 Compose 后必须重新创建容器。仅执行restart不会应用新的 volume 挂载。
先进入 front 的 Compose 目录:
cd/opt/1panel/runtime/java/java-mer-dev-front确认当前 Compose 配置中包含共享目录,并检查/run.sh实际传给 Java 的参数:
dockercompose config|grep-n"crmebimage\|shared"grep-n'crmeb.image-path'run.sh然后重新创建服务。当前 Compose 服务名通常是java:
dockercompose up-d--force-recreate --no-depsjava如果服务器使用旧版命令,则执行:
docker-composeup-d--force-recreate --no-depsjava在 1Panel 中也可以在应用的 Compose 编辑页面保存配置后点击“重新部署”或“重建容器”。
6. 验证挂载是否生效
6.1 查看容器挂载
dockerinspect java-mer-dev-front--format\'{{range .Mounts}}{{println .Source "->" .Destination}}{{end}}'必须看到:
/JAVA_PROJECT/MER/dev/admin/crmebimage -> /shared/crmebimage如果没有这一行,说明使用的 Compose 文件不是刚修改的文件,或者容器尚未重新创建。ls能看到/shared/crmebimage并不足以证明它是挂载点。
6.2 查看容器内目录
dockerexecjava-mer-dev-frontsh-c'ls -ld /shared/crmebimage'6.3 上传后检查宿主机
完成一次移动端图片上传后,在宿主机执行:
find/JAVA_PROJECT/MER/dev/admin/crmebimage-typef-mmin-10能看到新文件即表示 front 已经写入 admin 的共享目录。
7. 常见问题
7.1/shared/crmebimage存在,但宿主机没有文件
只执行ls -ld /shared/crmebimage只能证明容器内目录存在,不能证明它是宿主机挂载目录。必须用docker inspect确认是否存在:
宿主机 admin/crmebimage -> 容器 /shared/crmebimage7.2 inspect 中只有/app,没有/shared
说明共享 volume 没有写入实际生效的 Compose 文件。可以查看容器记录的 Compose 配置文件:
dockerinspect java-mer-dev-front--format\'{{index .Config.Labels "com.docker.compose.project.config_files"}}'编辑该文件,在services.java.volumes下增加共享挂载,然后重新部署。
7.3 上传时报权限错误
检查宿主机目录权限:
ls-ld/JAVA_PROJECT/MER/dev/admin/crmebimage同时查看容器进程 UID/GID 与目录属主,确认运行用户对目录有写权限:
dockerexecjava-mer-dev-frontidls-ldn/JAVA_PROJECT/MER/dev/admin/crmebimage如不匹配,再按实际 UID/GID 对目标目录调整属主或权限。不要对整个 admin 站点递归修改权限。
7.4 图片已保存但访问 404
物理存储路径和图片访问 URL 是两个配置。确认数据库中的localUploadUrl指向能够提供/crmebimage/**静态文件的域名,通常应指向 admin 服务或其反向代理地址。代码中 admin 配置了本地crmebimage静态映射,而 front 没有配置对应映射。
7.5 旧图片不会自动迁移
修改挂载和启动参数只影响后续上传。原来保存在 front 目录的图片不会自动移动,需要在确认备份后手动复制到:
/JAVA_PROJECT/MER/dev/admin/crmebimage8. 最终检查清单
- front Compose 已增加
/JAVA_PROJECT/MER/dev/admin/crmebimage:/shared/crmebimage。 - front 启动参数使用
--crmeb.image-path=/shared/。 - 容器已重新创建,而不是只重启。
docker inspect能看到共享挂载。- 移动端上传后,宿主机 admin 目录出现新文件。
- 图片访问域名能够提供
/crmebimage/**。