2017-01-01 2 views
7

При попытке отладки операторов RUN в моем файле Docker я попытался перенаправить вывод в файл в связанном томе (./mongo/log).Docker: RUN touch не создает файл

К моему удивлению, мне не удалось создать файлы с помощью команды RUN или передать результат другой команды в файл с помощью операторов перенаправления/добавления (,). Однако я смог выполнить указанную задачу, выполнив вход в рабочий контейнер через docker exec -ti mycontainer /bin/sh и выдав команду оттуда.

Почему такое поведение происходит? Как я могу дотронуться до файла в файле Dockerfile/redirect в файл или на консоль, из которой запускается Dockerfile?

Вот мой Dockerfile:

FROM mongo:3.4 

#Installing NodeJS 
    RUN apt-get update && \ 
    apt-get install -y curl && \ 
    curl -sL https://deb.nodesource.com/setup_6.x | bash - && \ 
    apt-get install -y nodejs 


#Setting Up Mongo 
    WORKDIR /var/www/smq 
    COPY ./mongo-setup.js mongo-setup.js 

    ##for testing 
    RUN touch /var/log/node.log &&/
     node --help 2>&1 > /var/log/node.log 

    ##this was the command to debug 
    #RUN node mongo-setup.js > /var/log/mongo-setup.log 2> /var/log/mongo-setup.error.log 

Вот отрывок из моего Докер-compose.yml:

mongodb: 
    build: 
     context: ./ 
     dockerfile: ./mongodb-dockerfile 
    container_name: smqmongodb 
    volumes: 
    - /var/lib/mongodb/data 
    - ./mongo/log/:/var/log/ 
    - ../.config:/var/www/.config 
+0

Вы должны прочитать о промежуточных этапах кэширования: https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/. Он работает именно так, как он предназначен для работы - вы, похоже, хотите, чтобы он работал по-другому. Хотя можно сказать, что сборка docker не использует кеширование (с '--no-cache = true', как вы можете узнать в ссылке выше), я бы предложил вам рассмотреть способ создания файла Docker для охвата и использования возможности кэширования. –

+0

Прохладный читать! Позвольте мне обновить файл Dockerfile. Из моего быстрого чтения это, похоже, не решает мою проблему, нет? –

+0

@Phillipe - параметр, о котором я говорил *, должен * решить проблему - он отключит кеширование, поэтому «touch» будет выполняться на каждой отдельной сборке. Но могли бы быть и другие способы достижения ваших целей без необходимости отключать кеш ... –

ответ

4

Вместо RUN node mongo-setup.js > /var/log/mongo-setup.log 2> /var/log/mongo-setup.error.log, в контейнере, что, если вы просто сказать `RUN узел монго-setup.js?

Docker рекомендует использовать docker logs. Как так:

docker logs container-name 

Чтобы сделать то, что вы после этого (см журналов установки Монго?), Вы можете разделить стандартный вывод & STDERR контейнера по конвейеру отдельных потоков: и отправить их в файлы:

[email protected]~$ docker logs foo > stdout.log 2>stderr.log 

[email protected]~$ cat stdout.log 
[email protected]~$ cat stderr.log 

Кроме того, обратитесь к docker logs documentation

+1

Интересно, я сделаю немного исследований о том, как это может быть достигнуто с помощью docker-compose (и как ведут себя журналы докеров), и я опубликую здесь свои результаты. –

+0

После некоторого исследования я нашел эту хорошую статью, описывающую в обзоре, как ведение журнала происходит в докере: https://medium.com/@yoanis_gil/logging-with-docker-part-1-b23ef1443aac#.q7macfaym Теперь я вижу докер стратегии с точки зрения стыковки. Замечательно! –

+0

Пока я настраивал параметр ведения журнала syslog, по какой-то причине я начал получать некоторые отпечатки от неисправной команды (узел mongo-setup.js). Итак, теперь у меня есть syslog, готовый идти, когда я хочу использовать такую ​​систему ведения журнала, и моя команда печатает на консоль в противном случае. Еще раз спасибо за ваш ответ :) –

7

Вы делаете это во время сборки:

RUN touch /var/log/node.log &&/
    node --help 2>&1 > /var/log/node.log 

Файл /var/log/node.log создается и фиксируется неизменно в полученном изображении.

Затем запустите контейнер с этим монтировании:

volumes: 
    - ./mongo/log/:/var/log/ 

Что бы ни было в ./mongo/log/ монтируется как /var/log в контейнере, который скрывает все, что было раньше (с изображением). Это то, что делает его похожим на то, что ваш touch не работал (хотя он, вероятно, работал нормально).

Вы думаете об этом назад - ваше монтируемое количество не отображает версию контейнера /var/log снаружи - она ​​заменяет все, что там было.

Ничего, что вы делаете в Dockerfile (build), никогда не появится во внешнем крепеже.

+0

Ваш ответ - ах-ха! момент. Отличное объяснение. Ясно, кратким и точным. Теперь я понимаю, что @Bruno Reis имел в виду в своем комментарии под OP. В конечном счете, поскольку ответ Сократеса является решением моей проблемы с регистрацией, я возьму его как принятое решение. Однако ваш ответ столь же информативен и ценен. Ура! –