Docker Community Forums

Share and learn in the Docker community.

Log files not created in container or host with Winston logger

I have a container based on nodejs:14 that uses winston for logging where, the destination is set as console for development and file for production. The container is itself launched with docker-compose up where, the YAML file has a volumes entry as ${HOST}/logs:${APP}/logs for logs. The idea is to ship the logs from the host to archives, log visualization, log rotation, etc. I did read about Configure logging drivers - but, I am avoiding this because of this line.

These files are designed to be exclusively accessed by the Docker daemon. Interacting with these files with external tools may interfere with Docker’s logging system and result in unexpected behavior, and should be avoided.

With winston, using File for transport, I could only see the log file on the host but it is empty. This behavior is actually discussed at Winston not creating any output when running in a Docker container. The work around mentioned (towards the end) is to use Console as the output and add a Dockerfile entry for redirecting STDOUT and STDERR to appropriate files through symbolic links.

The symbolic links will probably depend on the base image. For example, in the issue above, the STDOUT is referred to as /proc/1/fd/1 whereas, the documentation on View logs for a container or service refers the httpd example where, the STDOUT is referred to as /proc/self/fd/1.

Therefore, the approach with symbolic links does not sound like a straight forward approach.

In fact, the last comment in that thread suggests that CMD itself be set-up to direct STDOUT and STDERR to appropriate files through standard Linux commands. This sounds a better approach.

I have tried the second approach where winston uses Console approach but can’t get the files to be written even within the container. This is my Dockerfile.

FROM node:14 as build

ARG APP_ROOT=/app
ARG APP_PORT=4000

WORKDIR /
RUN mkdir -p ${APP_ROOT}/logs && \
    touch ${APP_ROOT}/logs/app.log && \
    touch ${APP_ROOT}/logs/app.err

WORKDIR /app
COPY app .
COPY package.json .
COPY package-lock.json .

RUN npm i

EXPOSE ${APP_PORT}
CMD ["node", "index.js"]

FROM gcr.io/distroless/nodejs:14

ARG APP_ROOT=/app
ENV LOG_FILE=${APP_ROOT}/logs/app.log
ENV ERR_FILE=${APP_ROOT}/logs/app.err

COPY --from=build /app /app
COPY --from=build ${APP_ROOT} ${APP_ROOT}

WORKDIR /app

CMD ["index.js", "1>${LOG_FILE}", "2>${ERR_FILE}"]

How do I get log files generated on console, by winston, to be written to files and read on host? Better yet, how do I get winston to write to files directly?