diff --git a/api/test/nginx-config.test.js b/api/test/nginx-config.test.js index 361cfa13..4ea8f1c8 100644 --- a/api/test/nginx-config.test.js +++ b/api/test/nginx-config.test.js @@ -290,3 +290,36 @@ test('the proxied Host keeps its port, or every write is refused', () => { assert.doesNotMatch(line, /\$host\b(?!_)/, '$host strips the port'); } }); + +/* Where request logs go. + + Alpine's packaged nginx.conf sends the access log and the error log to files + under /var/log/nginx. Nothing in the container reads them, and nothing trims + them: no logrotate binary is installed and no cron runs. So request failures + an operator needs (413, upstream refused, permission problems) were invisible + in `docker logs`, while the files grew unbounded in the writable layer. + + Both directives are valid in the server context, so this stays in a file the + repo owns rather than shipping our own nginx.conf. That also bounds it: + master and startup errors still follow the main context. */ + +test('request errors reach the container log', () => { + const serverLevel = dashboard.slice(0, dashboard.indexOf('location')); + assert.match( + serverLevel, + /^\s*error_log stderr\b/m, + 'without this, request failures are written to a file nobody reads', + ); +}); + +test('the access log is off rather than written to an unrotated file', () => { + const serverLevel = dashboard.slice(0, dashboard.indexOf('location')); + assert.match(serverLevel, /^\s*access_log off;$/m); +}); + +/* The health check runs every few seconds forever, so it was given its own + access_log off long before the server-level one existed. */ +test('the health check is still excluded', () => { + const health = dashboard.slice(dashboard.indexOf('location = /health')); + assert.match(health.slice(0, health.indexOf('}')), /access_log off;/); +}); diff --git a/nginx/dashboard.conf b/nginx/dashboard.conf index 3c9f41bf..0517a146 100644 --- a/nginx/dashboard.conf +++ b/nginx/dashboard.conf @@ -2,6 +2,15 @@ server { listen 80; server_name _; + # Alpine's packaged nginx.conf sends both logs to files under /var/log/nginx, + # where nothing reads them and nothing rotates them: the container ships no + # logrotate and no cron. Request errors go to stderr so `docker logs` shows + # them; the access log is dropped rather than written to a file that only + # grows. This covers request handling only, master and startup errors still + # follow the main context. + error_log stderr warn; + access_log off; + # Don't advertise the nginx version in the Server header or on error pages. server_tokens off;