Reputation: 997
I am trying to log the output of an application to both a file and stdout. Only logging the output to stdout and only logging the output to a file works, however the combination of the two does not work as expected.
Here are simplified versions of docker-compose.yml and a startup script.
docker-compose.yml:
version: "3.8"
services:
web:
image: node:14
command: sh "/app/scripts/init-app.sh"
init: true
volumes:
- ./:/app
init-app.sh:
#!/usr/bin/env sh
# Exit script immediately if a command exits with a non-zero status.
set -e
# Install and configure app
[...]
# Start app
exec ./app
The above configuration works, but outputs only to stdout.
Modification #1 (last line of init script):
# Start app and log output to file
exec ./app >> "/app/log.txt" 2>&1
This configuration works also, logging the output to a file, but not to stdout.
Modification #2 (last line of init script):
# Start app and log output to both a file and stdout
exec ./app 2>&1 | tee -a "/app/log.txt"
This correctly outputs to both a file and stdout, but it breaks the container's start/stop functionality.
Details:
Despite being called with exec
, ./app
doesn't run as PID 1 when called with tee
.
This is a problem, because when the container is stopped (via CLI or GUI), docker sends a stop signal to the process with PID 1. The ./app
process doesn't receive the signal and therefore ./app
doesn't stop.
How is it possible to log the output to both a file and stdout without breaking the start/stop functionality?
// Edit: Fixed modification #1
// Edit2: Added "init: true" to docker-compose.yml
Upvotes: 4
Views: 16841
Reputation: 2175
I've heard a best practice :
If i apply this, docker should be the only one in charge for managing this stream.
If you accept this principle you can leave you start script with only
exec ./app
you can start your app by running
docker-compose up web
control-c is available if needed.
You can access the logs in another terminal and redirect them to a file
docker-compose logs -f web > web.log
I dont see the use case, but if you want to do both starting and logging to stdout and loging to a file all the time then
# run and detach
docker-compose up -d web
# save logs to a file in the background
docker-compose logs -f web > web.log 2>&1 &
# reattach to the container to be able to do control-c
# it will not rerun the container, just reattach
docker-compose up web
Upvotes: 6
Reputation: 461
could you utilize the logging
capabilties of docker-compose to have both, printed stdout and a log file?
Only the json-file and journald drivers make the logs available directly from docker-compose up and docker-compose logs. Using any other driver does not print any logs
Upvotes: 2