Video Lesson: Pipe Docker log output to STDOUT

Pipe Docker log output to STDOUT

Learn how to route application log files to standard output for centralized container logging.


Lesson Content

Anything written to append-only files within containers should be piped to standard output (STDOUT). This makes application logs easy to diagnose and prevents append-only files from consuming disk space.

Some widely used Docker images, such as Nginx, already pipe their logs to STDOUT. You may still have an application-specific log file that you want to apply the same approach to. For example, this Node application overrides console.log() and writes every call to a file named debug.log:

var fs = require('fs');
var util = require('util');
var logFile = fs.createWriteStream(__dirname + '/debug.log', {flags : 'w'});

console.log = (d) => {
  logFile.write(util.format(d) + '\n');
};

var i = 0;
var log = () => {
  console.log(`foo bar ${i}`);
  i++;
};

setInterval(log, 2000);

Node’s original console.log() already writes to STDOUT, so this is a deliberately nonsensical example, but it shows how to redirect writes from a log file to STDOUT.

Run the script for a few moments:

node index.js

Then check the contents of debug.log:

cat debug.log

The output shows that the script is running and correctly writing to debug.log.

The Dockerfile starts with a Node base image, copies the application into the image, and runs it with the node command:

FROM mhart/alpine-node
COPY index.js .
CMD node index.js

To redirect those writes to STDOUT, add a RUN instruction before the CMD instruction. Use ln -sf to create a symbolic link from /debug.log to /dev/stdout:

FROM mhart/alpine-node
COPY index.js .
RUN ln -sf /dev/stdout /debug.log
CMD node index.js

Whatever would normally be written to debug.log is now piped straight to the container’s standard output.

Build the image and run a container in daemon mode:

docker build -t foo .
docker run -d --name=foo foo

Use docker logs with -f to follow the container output:

docker logs -f foo

The messages that would normally be written to debug.log now appear in the container logs:

foo bar 0
foo bar 1
foo bar 2
foo bar 3
foo bar 4

You can also confirm that nothing is written to debug.log inside the container:

docker exec -it foo cat /debug.log

The application keeps its existing file path while sending its output to STDOUT, where Docker can collect and display it without the container accumulating disk space over time.

Maggie

Hey, I'm Maggie! 👋

Ask me anything.

Want to chat with Maggie?

Log in for AI tutor access.

Comments

Join the discussion!

Notes

Keep track of what you learn!