Приложение Node не может прочитать файловую систему в образе Docker

Итак, у меня есть приложение узла, которое обращается к каталогу в своей файловой структуре и что-то с ним делает. Для этого я использую модуль «fs». Когда я запускаю контейнер из его образа, я получаю следующую ошибку:

Error: ENOENT, readdir './classes/cs395'

Я сразу же подумал о целой куче вещей, которые могут быть неправильными, ПОКА я не подключился к работающему контейнеру (после его перезапуска, потому что контейнер умрет при ошибке... конечно). Когда я запустил приложение узла из контейнера... оно сработало... без ошибок.

Я полагаю, что это может быть как-то связано с тем, как обрабатываются файловые системы, когда образы докеров многоуровневые, но когда это работало нормально, когда я прикреплялся к контейнеру, я действительно запутался.

РЕДАКТИРОВАТЬ:

Файл ДЕЙСТВИТЕЛЬНО существует... вот доказательство: введите здесь описание изображения Опять же, если (поскольку я подключен к контейнеру, как показано на картинке) я запускаю node server.js и пингую ip:port все работает отлично! каталог распознается! Но НЕ, если выполняется отдельно от образа.

Чтобы показать, что файл все еще там, давайте запустим наш остановленный контейнер и присоединимся к нему... как вы видите, файл все еще там. (Обратите внимание, что запуск контейнера не приведет к воссозданию файла, которого не было, когда он остановился... он просто продолжит работу с того места, где остановился) введите здесь описание изображения

Если это поможет, вот как я использую модуль «fs»:

var p = "./classes/cs395";

//READ ALL FILES FROM A DIRECTORY AND EMIT THE NAME OF THE FILE
fs.readdir(p, function(err, files){
    if (err) throw err;

    files.forEach(function (file) {
        if (files.length == 1 && file == '.DS_Store'){
            io.emit('receive_file', null);
        } else {
            fs.stat(p + '/' + file, function(err, stats){
                if (err) throw err;

                if (stats.isFile() && file != '.DS_Store'){
                    var ext = path.extname(file);
                    var name = path.basename(p + '/' + file, ext);
                    io.emit('receive_file', name);
                }
            });

        }
    });  

    if (files.length == 0) {
        io.emit('receive_file', null);
    }    

    console.log(files);
}); 

person frankgreco    schedule 20.02.2016    source источник


Ответы (2)


Задача состоит в том, чтобы определить ожидаемое место выполнения сценария узла и фактический рабочий каталог в докере. Эта разница будет учитывать расхождения между тем, что вы ожидаете от пути к файлу "." быть и что есть на самом деле.

Самый простой способ определить, выполняете ли вы в том контексте, в котором, как вы думаете, вы находитесь, — это утешить Fs.realpathSync("."). Я ожидаю, что местоположение не там, где вы думали, что выполняете (но оно должно совпадать с тем, что ваш WORKDIR установлен в ваш образ Docker). (Вы также можете доказать, что это ваша проблема, временно изменив пути «.» на абсолютные.)

Измените свой рабочий каталог, чтобы он указывал на то место, где вы ожидаете увидеть "." быть (в вашем случае WORKDIR /src), и вы должны иметь возможность использовать "." так, как вы ожидаете.

person purgatory101    schedule 11.04.2017

ENOENT означает, что такой записи в каталоге нет; файл ./classes/cs395 не существует и поэтому fs не может его прочитать. Проверьте, есть ли он там до и после.

См. Почему ENOENT означает "Нет такого файла или каталога"? для получения дополнительной информации.

Поскольку он работает после перезапуска приложения, одна из возможностей заключается в том, что файл создается после первого запуска приложения, и вы пытаетесь прочитать его до того, как он был создан.

person max_    schedule 20.02.2016
comment
Если бы только это было проблемой. Файл ДЕЙСТВИТЕЛЬНО существует.... см. мое редактирование вопроса. - person frankgreco; 20.02.2016
comment
ПОКА я не присоединился к работающему контейнеру (после перезапуска — существует ли файл до перезапуска при новой установке? - person max_; 20.02.2016
comment
добавил это к вопросу - person frankgreco; 20.02.2016