-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: set last-modified header with build time
As the source files in the reulting buildpack always have the same timestamp, we work around this by setting the last-modified header in the nginx.conf to the current time at build time. This makes caching work at least somewhat.
- Loading branch information
Showing
3 changed files
with
328 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
# Number of worker processes running in container | ||
worker_processes 1; | ||
|
||
# Run NGINX in foreground (necessary for containerized NGINX) | ||
daemon off; | ||
|
||
# Set the location of the server's error log | ||
error_log stderr; | ||
|
||
events { | ||
# Set number of simultaneous connections each worker process can serve | ||
worker_connections 1024; | ||
} | ||
|
||
http { | ||
client_body_temp_path {{ tempDir }}/client_body_temp; | ||
proxy_temp_path {{ tempDir }}/proxy_temp; | ||
fastcgi_temp_path {{ tempDir }}/fastcgi_temp; | ||
|
||
charset utf-8; | ||
|
||
# Map media types to file extensions | ||
types { | ||
text/html html htm shtml; | ||
text/css css; | ||
text/xml xml; | ||
image/gif gif; | ||
image/jpeg jpeg jpg; | ||
application/javascript js; | ||
application/atom+xml atom; | ||
application/rss+xml rss; | ||
font/ttf ttf; | ||
font/woff woff; | ||
font/woff2 woff2; | ||
text/mathml mml; | ||
text/plain txt; | ||
text/vnd.sun.j2me.app-descriptor jad; | ||
text/vnd.wap.wml wml; | ||
text/x-component htc; | ||
text/cache-manifest manifest; | ||
image/png png; | ||
image/tiff tif tiff; | ||
image/vnd.wap.wbmp wbmp; | ||
image/x-icon ico; | ||
image/x-jng jng; | ||
image/x-ms-bmp bmp; | ||
image/svg+xml svg svgz; | ||
image/webp webp; | ||
application/java-archive jar war ear; | ||
application/mac-binhex40 hqx; | ||
application/msword doc; | ||
application/pdf pdf; | ||
application/postscript ps eps ai; | ||
application/rtf rtf; | ||
application/vnd.ms-excel xls; | ||
application/vnd.ms-powerpoint ppt; | ||
application/vnd.wap.wmlc wmlc; | ||
application/vnd.google-earth.kml+xml kml; | ||
application/vnd.google-earth.kmz kmz; | ||
application/x-7z-compressed 7z; | ||
application/x-cocoa cco; | ||
application/x-java-archive-diff jardiff; | ||
application/x-java-jnlp-file jnlp; | ||
application/x-makeself run; | ||
application/x-perl pl pm; | ||
application/x-pilot prc pdb; | ||
application/x-rar-compressed rar; | ||
application/x-redhat-package-manager rpm; | ||
application/x-sea sea; | ||
application/x-shockwave-flash swf; | ||
application/x-stuffit sit; | ||
application/x-tcl tcl tk; | ||
application/x-x509-ca-cert der pem crt; | ||
application/x-xpinstall xpi; | ||
application/xhtml+xml xhtml; | ||
application/zip zip; | ||
application/octet-stream bin exe dll; | ||
application/octet-stream deb; | ||
application/octet-stream dmg; | ||
application/octet-stream eot; | ||
application/octet-stream iso img; | ||
application/octet-stream msi msp msm; | ||
application/json json; | ||
audio/midi mid midi kar; | ||
audio/mpeg mp3; | ||
audio/ogg ogg; | ||
audio/x-m4a m4a; | ||
audio/x-realaudio ra; | ||
video/3gpp 3gpp 3gp; | ||
video/mp4 mp4; | ||
video/mpeg mpeg mpg; | ||
video/quicktime mov; | ||
video/webm webm; | ||
video/x-flv flv; | ||
video/x-m4v m4v; | ||
video/x-mng mng; | ||
video/x-ms-asf asx asf; | ||
video/x-ms-wmv wmv; | ||
video/x-msvideo avi; | ||
} | ||
|
||
access_log /dev/stdout; | ||
|
||
# Set the default MIME type of responses; 'application/octet-stream' | ||
# represents an arbitrary byte stream | ||
default_type application/octet-stream; | ||
|
||
# (Performance) When sending files, skip copying into buffer before sending. | ||
sendfile on; | ||
# (Only active with sendfile on) wait for packets to reach max size before | ||
# sending. | ||
tcp_nopush on; | ||
|
||
# (Performance) Enable compressing responses | ||
gzip on; | ||
# For all clients | ||
gzip_static always; | ||
# Including responses to proxied requests | ||
gzip_proxied any; | ||
# For responses above a certain length | ||
gzip_min_length 1100; | ||
# That are one of the following MIME types | ||
gzip_types | ||
text/plain | ||
text/css | ||
text/js | ||
text/xml | ||
text/javascript | ||
application/javascript | ||
application/x-javascript | ||
application/json | ||
application/xml | ||
application/xml+rss | ||
font/eot | ||
font/otf | ||
font/ttf | ||
image/svg+xml; | ||
# Compress responses to a medium degree | ||
gzip_comp_level 6; | ||
# Using 16 buffers of 8k bytes each | ||
gzip_buffers 16 8k; | ||
|
||
# Add "Vary: Accept-Encoding” response header to compressed responses | ||
gzip_vary on; | ||
|
||
# Decompress responses if client doesn't support compressed | ||
gunzip on; | ||
|
||
# Don't compress responses if client is Internet Explorer 6 | ||
gzip_disable "msie6"; | ||
|
||
# Set a timeout during which a keep-alive client connection will stay open on | ||
# the server side | ||
keepalive_timeout 30; | ||
|
||
# Ensure that redirects don't include the internal container PORT - <%= | ||
# ENV["PORT"] %> | ||
port_in_redirect off; | ||
|
||
# (Security) Disable emitting nginx version on error pages and in the | ||
# “Server” response header field | ||
server_tokens off; | ||
|
||
server { | ||
listen {{port}} default_server; | ||
server_name _; | ||
|
||
# Directory where static files are located | ||
root $(( .WebServerRoot -)); | ||
$(( if .WebServerForceHTTPS )) | ||
# If HTTP request is made, redirect to HTTPS requests | ||
set $updated_host $host; | ||
if ($http_x_forwarded_host != "") { | ||
set $updated_host $http_x_forwarded_host; | ||
} | ||
|
||
if ($http_x_forwarded_proto != "https") { | ||
return 301 https://$updated_host$request_uri; | ||
} | ||
$(( end )) | ||
$((- if (ne .BasicAuthFile "") )) | ||
# Require username + password authentication for access | ||
auth_basic "Password Protected"; | ||
auth_basic_user_file $(( .BasicAuthFile )); | ||
$(( end )) | ||
location $(( .WebServerLocationPath )) { | ||
$((- if .WebServerEnablePushState )) | ||
# Send the content at / in response to *any* requested endpoint | ||
if (!-e $request_filename) { | ||
rewrite ^(.*)$ / break; | ||
} | ||
$(( end )) | ||
# Specify files sent to client if specific file not requested (e.g. | ||
# GET www.example.com/). NGINX sends first existing file in the list. | ||
index index.html index.htm Default.htm; | ||
} | ||
|
||
$((- if .LastModifiedValue )) | ||
add_header last-modified '$(( .LastModifiedValue ))'; | ||
$(( end )) | ||
|
||
$((- if .ETag )) | ||
etag 'on'; | ||
$(( else )) | ||
etag 'off'; | ||
$(( end )) | ||
|
||
# (Security) Don't serve dotfiles, except .well-known/, which is needed by | ||
# LetsEncrypt | ||
location ~ /\.(?!well-known) { | ||
deny all; | ||
return 404; | ||
} | ||
} | ||
|
||
$(( if .NGINXStubStatusPort )) | ||
# stub_status | ||
server { | ||
listen $(( .NGINXStubStatusPort -)); | ||
listen [::]:$(( .NGINXStubStatusPort -)); | ||
|
||
location /stub_status { | ||
stub_status; | ||
} | ||
} | ||
$(( end )) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package static | ||
|
||
import ( | ||
"bytes" | ||
_ "embed" | ||
"fmt" | ||
"html/template" | ||
"io" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/paketo-buildpacks/nginx" | ||
"github.com/paketo-buildpacks/packit/v2/scribe" | ||
) | ||
|
||
//go:embed assets/default.conf | ||
var DefaultConfigTemplate string | ||
|
||
// this has been adapted from https://github.com/paketo-buildpacks/nginx/blob/main/default_config_generator.go | ||
// to add our own customizations to the config | ||
type DefaultConfigGenerator struct { | ||
logs scribe.Emitter | ||
} | ||
|
||
type Configuration struct { | ||
LastModifiedValue string | ||
ETag bool | ||
nginx.Configuration | ||
} | ||
|
||
func NewDefaultConfigGenerator(logs scribe.Emitter) DefaultConfigGenerator { | ||
return DefaultConfigGenerator{logs: logs} | ||
} | ||
|
||
func (g DefaultConfigGenerator) Generate(config Configuration) error { | ||
g.logs.Process("Generating %s", config.NGINXConfLocation) | ||
t := template.Must(template.New("template.conf").Delims("$((", "))").Parse(DefaultConfigTemplate)) | ||
|
||
if !filepath.IsAbs(config.WebServerRoot) { | ||
config.WebServerRoot = filepath.Join(`{{ env "APP_ROOT" }}`, config.WebServerRoot) | ||
} | ||
|
||
g.logs.Subprocess("Setting server root directory to '%s'", config.WebServerRoot) | ||
|
||
if config.WebServerLocationPath == "" { | ||
config.WebServerLocationPath = "/" | ||
} | ||
|
||
g.logs.Subprocess("Setting server location path to '%s'", config.WebServerLocationPath) | ||
|
||
if config.WebServerEnablePushState { | ||
g.logs.Subprocess("Enabling push state routing") | ||
} | ||
|
||
if config.WebServerForceHTTPS { | ||
g.logs.Subprocess("Setting server to redirect HTTP requests to HTTPS") | ||
} | ||
|
||
if config.BasicAuthFile != "" { | ||
g.logs.Subprocess("Enabling basic authentication with .htpasswd credentials") | ||
} | ||
|
||
if config.NGINXStubStatusPort != "" { | ||
g.logs.Subprocess("Enabling basic status information with stub_status module") | ||
} | ||
|
||
g.logs.Break() | ||
|
||
var b bytes.Buffer | ||
err := t.Execute(&b, config) | ||
if err != nil { | ||
// not tested | ||
return err | ||
} | ||
|
||
f, err := os.OpenFile(config.NGINXConfLocation, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm) | ||
if err != nil { | ||
return fmt.Errorf("failed to create %s: %w", config.NGINXConfLocation, err) | ||
} | ||
defer f.Close() | ||
|
||
_, err = io.Copy(f, &b) | ||
if err != nil { | ||
// not tested | ||
return err | ||
} | ||
return nil | ||
} |