`bootBuildImage` 可以创建可写卷吗?
问题说明
给定一个将文件写入 /var/lib/app/files
的 Spring Boot 应用程序.
Given a spring boot app that writes files to /var/lib/app/files
.
我使用 gradle 任务创建了一个 docker 镜像:
I create an docker image with the gradle task:
./gradlew bootBuildImage --imageName=app:latest
然后,我想在docker-compose
中使用它:
Then, I want to use it in docker-compose
:
version: '3.5'
services:
app:
image: app:latest
volumes:
- app-storage:/var/lib/app/files
// ...ports etc
volumes:
app-storage:
这将失败,因为该文件夹是在 docker-compose up
期间创建的并且归 root
所有,因此应用程序没有对该文件夹的写访问权限.
This will fail, because the folder is created during docker-compose up
and is owned by root
and the app, hence, has no write access to the folder.
快速修复是通过指定 user: root
:
The quick fix is to run the image as root
by specifying user: root
:
version: '3.5'
services:
app:
image: app:latest
user: root # <------------ required
volumes:
- app-storage:/var/lib/app/files
// ...ports etc
volumes:
app-storage:
这很好用,但我不想以 root
的身份运行它.我想知道如何实现它?我通常可以创建一个 Dockerfile
来创建具有正确所有权和写入权限的所需文件夹.但据我所知,构建包不使用自定义 Dockerfile
,因此 bootBuildImage
不会使用它 - 对吗?那么我们如何创建可写卷?
This works fine, but I do not want to run it as root
. I wonder how to achieve it? I normally could create a Dockerfile
that creates the desired folder with correct ownership and write permissions. But as far as I know build packs do not use a custom Dockerfile
and hence bootBuildImage
would not use it - correct? How can we create writable volumes then?
正确答案
通过检查图片我发现 buildpack 使用 /cnb/lifecycle/launcher
来启动应用程序.因此,我能够在启动前自定义 docker 命令并修复特定文件夹的所有者:
By inspecting the image I found that the buildpack uses /cnb/lifecycle/launcher
to launch the application. Hence I was able to customize the docker command and fix the owner of the specific folder before launch:
version: '3.5'
services:
app:
image: app:latest
# enable the app to write to the storage folder (docker will create it as root by default)
user: root
command: "/bin/sh -c 'chown 1000:1000 /var/lib/app/files && /cnb/lifecycle/launcher'"
volumes:
- app-storage:/var/lib/app/files
// ...ports etc
volumes:
app-storage:
不过,这不是很好,因为它不是直截了当的(因此我未来的自己需要花时间再次理解它)而且它的可扩展性也非常有限.
Still, this is not very nice, because it is not straight forward (and hence my future self will need to spent time on understand it again) and also it is very limited in its extensibility.
更新 30.10.2020 - Spring Boot 2.3
我们最终创建了另一个 Dockerfile/层,这样我们就不需要在 docker-compose 文件中处理这个:
We ended up creating another Dockerfile/layer so that we do not need to hassle with this in the docker-compose file:
# The base_image should hold a reference to the image created by ./gradlew bootBuildImage
ARG base_image
FROM ${base_image}
ENV APP_STORAGE_LOCAL_FOLDER_PATH /var/lib/app/files
USER root
RUN mkdir -p ${APP_STORAGE_LOCAL_FOLDER_PATH}
RUN chown ${CNB_USER_ID}:${CNB_GROUP_ID} ${APP_STORAGE_LOCAL_FOLDER_PATH}
USER ${CNB_USER_ID}:${CNB_GROUP_ID}
ENTRYPOINT /cnb/lifecycle/launcher
25.11.2020 更新 - Spring Boot 2.4
注意上面的Dockerfile会导致这个错误:
Note that the above Dockerfile will result in this error:
ERROR: failed to launch: determine start command: when there is no default process a command is required
原因是 paketo builder 的默认入口点改变了.将入口点从 /cnb/lifecycle/launcher
更改为新的入口点即可修复:
The reason is that the default entrypoint by the paketo builder changed. Changing the entrypoint from /cnb/lifecycle/launcher
to the new one fixes it:
ENTRYPOINT /cnb/process/web
另见这个问题:错误:无法启动:确定启动命令:当没有默认进程时需要命令
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /reply/detail/tanhcajifk
-
YouTube API 不能在 iOS (iPhone/iPad) 工作,但在桌面浏览器工作正常?
it1352 07-30 -
iPhone,一张图像叠加到另一张图像上以创建要保存的新图像?(水印)
it1352 07-17 -
保持在后台运行的 iPhone 应用程序完全可操作
it1352 07-25 -
在android同时打开手电筒和前置摄像头
it1352 09-28 -
使用c++17更新时出现G++编译器警告
it1352 06-18 -
使用 iPhone 进行移动设备管理
it1352 07-23 -
扫描 NFC 标签时是否可以启动应用程序?
it1352 08-02 -
复制文件夹/文件而不修改属性?
it1352 07-15 -
Android微调工具-删除当前选择
it1352 06-20 -
Android App 和三星 Galaxy S4 不兼容
it1352 07-20