สร้างโปรเจ็กต์ gradle ภายใน Docker

ฉันมีโปรเจ็กต์ Gradle ง่ายๆ ที่ฉันต้องการสร้างภายในคอนเทนเนอร์ Docker

ฉันมีการสร้างนักเทียบท่าแบบหลายขั้นตอน ขั้นตอนแรกเพียงโคลนโครงการจาก GitHub ขั้นตอนที่สองจะต้องสร้างโครงการเพื่อที่ฉันจะสามารถดำเนินการได้ในขั้นตอนสุดท้าย แต่มันล้มเหลวใน

FROM gradle:4.2.1-jdk8-alpine
WORKDIR /app
COPY --from=0 /app/myProject /app
RUN ./gradlew build --stacktrace

คำสั่ง ./gradlew build --stacktrace ไม่สามารถดำเนินการได้และล้มเหลวโดยมีข้อผิดพลาด:

FAILURE: Build failed with an exception.

* What went wrong:
Could not update /app/.gradle/3.5-rc-2/file-changes/last-build.bin

และสแต็กเทรซ:

org.gradle.api.UncheckedIOException: Could not update /app/.gradle/3.5-rc-2/file-changes/last-build.bin
    at org.gradle.api.internal.changedetection.state.FileTimeStampInspector.updateOnFinishBuild(FileTimeStampInspector.java:72)
    at org.gradle.api.internal.changedetection.state.BuildScopeFileTimeStampInspector.stop(BuildScopeFileTimeStampInspector.java:38)
    at org.gradle.internal.concurrent.CompositeStoppable.stop(CompositeStoppable.java:98)
.....
Caused by: java.io.FileNotFoundException: /app/.gradle/3.5-rc-2/file-changes/last-build.bin (Permission denied)
    at java.io.FileOutputStream.open0(Native Method)
......

เหตุใดผู้ใช้นักเทียบท่าจึงไม่มีสิทธิ์สร้างไฟล์ในไดเร็กทอรีการทำงานและจะเพิ่มสิทธิ์เหล่านี้ได้อย่างไร แบบธรรมดา RUN chmod 777 /app ใช้งานไม่ได้และบอกฉัน: chmod: /app: Operation not permitted


person Sergii Bishyr    schedule 17.10.2017    source แหล่งที่มา
comment
ดูไฟล์นักเทียบท่าสำหรับ gradle:4.2.1-jdk8-alpine github.com/keeganwitt/docker-gradle/blob/ มันตั้งค่า USER gradle ไฟล์ที่คุณกำลังคัดลอกจากไดเร็กทอรีแอปของคุณไปยังไดเร็กทอรีแอปของอิมเมจนักเทียบท่าอาจไม่มีสิทธิ์ที่ถูกต้องสำหรับผู้ใช้ gradle ตอนนี้ RUN chmod ไม่ทำงานเนื่องจากคำสั่งนั้นถูกเรียกใช้ในฐานะผู้ใช้ gradle อีกครั้งภายในบริบทนักเทียบท่า ดังนั้นคุณต้องรัน chown -R none:nobody /path/to/app/myProject บนเทอร์มินัลในพื้นที่ของคุณ จากนั้นสร้างอิมเมจนักเทียบท่า   -  person Raghwendra Singh    schedule 18.10.2017
comment
@Cyclops ขอบคุณสำหรับความคิดเห็น คุณหมายถึงอะไรโดยสถานีท้องถิ่น? ฉันไม่สามารถทำให้เป็นอัตโนมัติใน Dockerfile ของฉันได้หรือ   -  person Sergii Bishyr    schedule 18.10.2017
comment
คุณสามารถเพิ่ม 3 คำสั่งต่อไปนี้ใน dockerfile ของคุณ: -------- 1. USER root # สิ่งนี้จะเปลี่ยนผู้ใช้เริ่มต้นเป็น root 2. RUN chown -R gradle /app # สิ่งนี้จะเปลี่ยนความเป็นเจ้าของโฟลเดอร์ 3. USER gradle # สิ่งนี้ เปลี่ยนผู้ใช้กลับไปเป็นการไล่ระดับผู้ใช้เริ่มต้น   -  person Raghwendra Singh    schedule 18.10.2017
comment
ลืมเพิ่มอีกสิ่งหนึ่ง 3 บรรทัดนี้จะอยู่ใต้คำสั่ง COPY ในไฟล์นักเทียบท่าของคุณ แจ้งให้เราทราบหากวิธีนี้ใช้ได้ผลสำหรับคุณ ฉันเคยประสบปัญหาที่คล้ายกันในอดีตเกี่ยวกับปัญหาการเป็นเจ้าของไฟล์และโฟลเดอร์ ฉันได้แก้ไขพวกเขาในลักษณะเดียวกัน   -  person Raghwendra Singh    schedule 18.10.2017
comment
@Cyclops มันใช้งานได้ โพสไว้เป็นคำตอบก็ยอม!   -  person Sergii Bishyr    schedule 19.10.2017


คำตอบ (2)


ตาม Dockerfile สำหรับ gradle:4.2.1- jdk8-alpine ที่ มี "gradle " เป็นผู้ใช้เริ่มต้น ไฟล์ที่คุณกำลังคัดลอกจากไดเร็กทอรีแอปของคุณไปยังไดเร็กทอรีแอปของอิมเมจนักเทียบท่าอาจไม่มีสิทธิ์ที่ถูกต้องสำหรับผู้ใช้ "gradle"

คุณควรเพิ่มคำสั่งเพิ่มเติมสามคำสั่งใน Dockerfile ของคุณเพื่อตั้งค่าการอนุญาตที่ถูกต้อง:

FROM gradle:4.2.1-jdk8-alpine
WORKDIR /app
COPY --from=0 /app/myProject /app

USER root                # This changes default user to root
RUN chown -R gradle /app # This changes ownership of folder
USER gradle              # This changes the user back to the default user "gradle"

RUN ./gradlew build --stacktrace
person Raghwendra Singh    schedule 21.10.2017

อีกทางเลือกหนึ่งคือใช้คำสั่ง ADD แทน COPY จากนั้นใช้ตัวเลือก --chown เพื่อเปลี่ยนเจ้าของไฟล์หลังการคัดลอก ดังนั้น Dockerfile สุดท้ายจะง่ายกว่านี้อีก

FROM gradle:4.2.1-jdk8-alpine
WORKDIR /app
ADD --chown=gradle:gradle /app/myProject /app

RUN ./gradlew build --stacktrace
person zaerymoghaddam    schedule 22.03.2019
comment
COPY ยังรองรับตัวเลือก --chown โปรดดูที่ docs.docker.com/engine/reference/builder /#คัดลอก - person Peter Dotchev; 25.09.2019