bootBuildImage可以创建可写卷吗? [英] can `bootBuildImage` create writeable volumes?

查看:62
本文介绍了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.

更新2020年10月30日-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构建器的默认入口点已更改.将入口点从/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

另请参阅以下问题: 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆