When serving pre-gzipped log files (e.g., access.log.gz) through Nginx, browsers typically download them as binary files rather than displaying their decompressed content. This occurs because Nginx sends these files with application/x-gzip
as the default Content-Type.
To make browsers automatically decompress and display the content, you need to:
- Set the correct Content-Type header
- Ensure proper Content-Encoding
location ~* \.gz$ {
add_header Content-Encoding gzip;
types { text/plain gz; }
default_type text/plain;
}
For log files specifically, consider this production-tested configuration:
server {
listen 80;
server_name logs.example.com;
location / {
root /var/log/nginx;
location ~* \.(log|txt)\.gz$ {
add_header Content-Encoding gzip;
types { text/plain gz; }
default_type text/plain;
# Optional: Set caching headers
expires 1h;
add_header Cache-Control "public";
}
}
}
For more complex scenarios:
Handling Multiple File Types
location ~* \.(log|txt|csv)\.gz$ {
add_header Content-Encoding gzip;
types {
text/plain gz;
text/csv csv.gz;
application/json json.gz;
}
}
Security Implications
Remember to:
- Restrict access to sensitive log files
- Consider adding authentication
- Set appropriate CORS headers if needed
Verify with curl:
curl -I http://yourserver/access.log.gz
Should return headers including:
Content-Type: text/plain
Content-Encoding: gzip
When dealing with pre-gzipped log files (or any .gz files) that need to be served as plain text, we face an interesting technical challenge. By default, browsers will either:
- Download the .gz file as binary
- Attempt to display raw compressed data if forced to render as text/plain
Here's the proper Nginx configuration to make .gz files display as decompressed text in browsers:
location ~* \.gz$ {
gzip off;
add_header Content-Encoding gzip;
default_type text/plain;
}
Let's break down why this works:
gzip off; # Disables on-the-fly gzipping
add_header Content-Encoding gzip; # Tells browser this is gzipped content
default_type text/plain; # Forces Content-Type header
For more complex scenarios, consider these variations:
# For specific file types
location ~* \.log\.gz$ {
gzip off;
add_header Content-Encoding gzip;
types { } default_type text/plain;
}
# With cache control
location ~* \.gz$ {
gzip off;
add_header Content-Encoding gzip;
default_type text/plain;
expires 1h;
add_header Cache-Control "public";
}
After implementing, verify with curl:
curl -I http://yourserver.com/example.log.gz
Look for these headers in response:
Content-Type: text/plain
Content-Encoding: gzip
When serving many gzipped files:
- Ensure sendfile is enabled in nginx
- Consider adding "gzip_static on" for fallback handling
- Monitor memory usage when serving large .gz files