Docker не создает файлы в указанном объеме - PullRequest
1 голос
/ 21 июня 2020

Я создал эту небольшую демонстрационную программу, чтобы показать свою проблему.

public class DemoApplication {

public static void main(String[] args) {
    create(".", "1");
    create("", "2");
    create("app/usr", "3");
    create("/usr/app", "4");
    create("usr/app", "5");
}

public static void create(String location, String name) {
    try {
        File myObj = new File(location+ "/" + name + ".txt");
        if (myObj.createNewFile()) {
            System.out.println("File created: " + myObj.getName());
        } else {
            System.out.println("File already exists.");
        }
    } catch (IOException e) {
        System.out.println("An error occurred.");
        e.printStackTrace();
    }
}

}

Я использую этот Dockerfile

FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} /usr/app/demo.jar
WORKDIR /usr/app/
VOLUME /usr/app/
ENTRYPOINT ["java","-jar","demo.jar"]

эти команды для создания контейнера

mvn clean package
docker build -t please/work .

и, наконец, что не менее важно, эта команда для запуска контейнера

docker run please/work -v /root/hayasaka:/usr/app/

Я также пробовал использовать это

docker run please/work -v /root/hayasaka:/

, но в обоих случаях файлы не получаются создается в / root / hayasaka

Это консольный вывод, который я получаю при запуске контейнера

File created: 1.txt
File created: 2.txt
An error occurred.
java.io.IOException: No such file or directory
        at java.io.UnixFileSystem.createFileExclusively(Native Method)
        at java.io.File.createNewFile(File.java:1012)
        at com.example.demo.DemoApplication.create(DemoApplication.java:23)
        at com.example.demo.DemoApplication.main(DemoApplication.java:15)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:109)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)
File created: 4.txt
An error occurred.
java.io.IOException: No such file or directory
        at java.io.UnixFileSystem.createFileExclusively(Native Method)
        at java.io.File.createNewFile(File.java:1012)
        at com.example.demo.DemoApplication.create(DemoApplication.java:23)
        at com.example.demo.DemoApplication.main(DemoApplication.java:17)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:109)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)

Теоретически 1.txt или 2.txt должны быть созданы в указанном томе. О, также я создал проект с помощью инициализатора Spring, так как настоящий проект также был создан с помощью этого инструмента. В качестве дополнительных зависимостей я выбрал только инструменты разработчика и ничего не изменил в файле pom. xml.

1 Ответ

1 голос
/ 21 июня 2020

РЕДАКТИРОВАТЬ : Чтобы сделать этот ответ полным, я добавляю то, что уже упоминалось в комментарии к вопросу. Тот факт, что переключатель -v в команде docker run расположен неправильно.

Основная причина того, что ваше выполнение здесь не работает так, как ожидалось, заключается просто в том, что переключатель -v /some/path добавляется в конец команды docker run после имени изображения.

docker run --help дает следующее описание синтаксиса ввода:

Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Здесь указано, что [OPTIONS] должно быть предоставлено перед названием изображения. Перед всеми переключателями опций стоит одинарный или двойной -, и в большинстве случаев после него следует параметр переключателя. И поэтому двоичный файл docker будет идентифицировать первый аргумент команды docker run, то есть , а не , которому предшествует - в качестве имени изображения.

Аргументы, следующие за именем изображения, будет интерпретироваться как переопределяющая команда ([COMMAND] [ARG...]) и добавляться к ENTRYPOINT, определенному в Dockerfile, из которого было создано изображение.

Вы определили ENTRYPOINT:

ENTRYPOINT ["java","-jar","demo.jar"]

И, учитывая, что вы предоставляете первый пример выполнения, это:

docker run please/work -v /root/hayasaka:/usr/app/

В результате команда, выполненная в контейнере, будет такой:

java -jar demo.jar -v /root/hayasaka:/usr/app/

Это конечно не ваше намерение. И если программа, вероятно, не ожидает никаких аргументов, она просто проигнорирует их.

Вот обзор вашего ввода и результатов.

Файл 1.txt

    create(".", "1");

Это будет ./1.txt, или в абсолютном выражении /usr/app/1.txt, что является прекрасным и допустимым путем. Файл 1.txt будет создан в рабочем каталоге процесса java, который, в свою очередь, является рабочим каталогом пользователя, запускающего программу java, которую вы установили в Dockerfile как * 1053. *.

Файл 2.txt

    create("", "2");

Это создаст файл /2.txt, файл в root файловой системы в контейнере. учитывая, что сопоставлен том только каталог /usr/app, этот файл не будет виден извне контейнера.

Файл 3.txt

    create("app/usr", "3");

Это создаст файл app/usr/3.txt , который является местоположением относительно рабочего каталога процесса java. Абсолютный путь - /usr/app/app/usr/3.txt. Это не удается, скорее всего, из-за отсутствия промежуточной структуры каталогов app/usr. Используйте этот подход для решения проблемы:

    if (!myObj.getParentFile().exists()) {
        myObj.getParentFile().mkdirs();

Это создаст недостающие промежуточные каталоги.

Файл 4.txt

    create("/usr/app", "4");

Будет создан файл /usr/app/4.txt, существующий абсолютный путь, поскольку сборка docker создаст его с заданным определением Dockerfile. Здесь нет проблем.

Файл 5.txt

    create("usr/app", "5")

Это пытается создать файл usr/app/5.txt, который, как и файл 3.txt, является местоположением относительно рабочего каталога java процесс. Абсолютный путь - /usr/app/usr/app/5.txt. Он завершится неудачей по тем же причинам, что и 3.txt.

Надеюсь, это дает хороший обзор!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...