【问题标题】:can `bootBuildImage` create writeable volumes?`bootBuildImage` 可以创建可写卷吗?
【发布时间】:2021-01-28 21:17:05
【问题描述】:

给定一个将文件写入/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 所有,因此应用程序对该文件夹没有写入权限。

快速解决方法是通过指定user: rootroot 运行图像:

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 不会使用它——对吗?那么我们如何创建可写卷呢?

【问题讨论】:

    标签: spring-boot docker docker-compose


    【解决方案1】:

    通过检查图像,我发现 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:
    

    不过,这不是很好,因为它不是直截了当的(因此我未来的自己需要花时间重新理解它),而且它的可扩展性非常有限。

    更新 30.10.2020 - 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
    

    另请参阅此问题:ERROR: failed to launch: determine start command: when there is no default process a command is required

    【讨论】:

    • 我对 docker 很陌生,遇到了你描述的同样的问题:stackoverflow.com/questions/67280070/… - 你能推荐任何关于如何创建/添加 dockerfile 层的阅读资料吗?我想这不会与 gradle 构建过程集成,对吧?
    猜你喜欢
    • 2014-11-11
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多