Log to stdout and stderr, and let the platform collect and route the stream. The twelve factor guidance says an app should not manage log files or routing, and Docker captures those two streams by default. Add structure, redaction and a central destination so logs outlive the container.
What the guidance says
The twelve factor methodology treats logs as the stream of time ordered events from running processes and backing services. A twelve factor app never concerns itself with routing or storage of its output stream. It writes its events, unbuffered, to stdout. In staging and production, the execution environment captures each stream, combines them and routes them to their destinations, which the app cannot see or configure.
Docker's documentation matches this from the other side: by default, docker logs shows the command's STDOUT and STDERR. It also warns that processes which write to log files instead can leave docker logs nearly empty. The official nginx image symlinks its log files to the standard streams, and the official httpd image points its output at the process file descriptors for the same reason.
Stdout versus files
| Question | Stdout and stderr | Log files in the container |
|---|---|---|
| Visible to platform tooling | Yes, by default | Only if you add a collector |
| Survives container restart | If shipped off host | No, unless on a volume |
| Rotation handled by | The platform or driver | You, inside the image |
| Disk fill risk inside container | Lower | Higher |
| Tamper exposure | Stream leaves the process | Anyone in the container can edit |
| Local debugging | Easy, in the terminal | Need to exec in |
The security angle is the last two rows. A file inside a container writable by the app is also writable by an attacker who compromises the app, and it disappears when the container is replaced. A stream shipped off the host is harder to quietly rewrite.
Steps
- Configure the application and any web server in the image to write to stdout and stderr. Check third party images the way Docker describes, using symlinks or file descriptors where needed.
- Emit one structured event per line, so the collector does not need to guess boundaries. See structured log fields.
- Send errors to stderr and normal events to stdout, or put the level in the record.
- Ship the stream from the node to central storage with a collector. Local only storage is one of the conditions OWASP Top 10 A09 lists as a logging failure.
- Set limits on the container log driver so a chatty process cannot fill the host disk. See log pipeline flooding and disk fill.
- Run containers with a read only root file system where you can. If logs go to stdout, nothing needs to write them to disk.
Common mistakes
Multi line stack traces split into separate records break parsing. Use a format that keeps the trace inside one event, or a logger that emits JSON.
Another is logging secrets from environment dumps at startup. Do not print the full environment.
Last, remember that stdout is not private. Anyone with access to the platform logs can read it, so apply the same redaction rules as for any other log store.
Try it yourself
Click through it at your own pace, or open it full screen.
Quick check
Is it ever right to write files in a container?
Sometimes, for example an audit stream mounted to a separate volume with its own access rules. Even then, ship a copy off the host.
Does stdout logging mean I lose logs when a pod dies?
Only if you keep them on the node alone. Ship them to central storage as they are produced.
Safeguard scans container images and their dependencies for known issues. Try a free scan at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.