给出一个将文件写入/var/lib/app/files
的spring boot应用程序。
我用gradle任务创建了一个docker镜像:
./gradlew bootBuildImage --imageName=app:latest
然后,我想在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
和该应用拥有,因此对该文件夹无写权限。
快速解决方案是通过指定root
以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
不会使用它-对吗?那么我们如何创建可写卷?
答案 0 :(得分:0)
通过检查映像,我发现buildpack使用/cnb/lifecycle/launcher
启动应用程序。因此,我能够自定义docker命令并在启动前修复特定文件夹的所有者:
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:
仍然,这不是很好,因为它不是直接的(因此我未来的自我将需要花费时间来重新理解它),并且它的可扩展性非常有限。
更新2020年10月30日-Spring Boot 2.3
我们最终创建了另一个Dockerfile / layer,因此我们无需在docker-compose文件中为此烦恼:
# 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将导致此错误:
ERROR: failed to launch: determine start command: when there is no default process a command is required
原因是paketo构建器的默认入口点已更改。将入口点从/cnb/lifecycle/launcher
更改为新的入口点即可解决:
ENTRYPOINT /cnb/process/web