Skip to content

Instantly share code, notes, and snippets.

Last active August 26, 2020 12:53
Show Gist options
  • Save twistedpair/4b8d0f78095dd9d491370447ee531461 to your computer and use it in GitHub Desktop.
Save twistedpair/4b8d0f78095dd9d491370447ee531461 to your computer and use it in GitHub Desktop.
Preview Environment Nginx Config
FROM nginx
# Copy custom error pages
COPY html /usr/share/nginx/html
# nginx defaults like logging
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
# nginx mapping file for URL routing
COPY nginx/nginx.conf /etc/nginx/nginx.conf
<body><h1>404 😭</h1></body>
<body>There is nothing here. Be sure to enter the correct preview environment path.</body>
server {
listen 8080;
server_name localhost;
# TLS is terminated upstream, so use forwarded proto to determine redirect need
if ($http_x_forwarded_proto ~* ^http$ ) {
return 301 https://$host$request_uri;
# Extract wildcard commit hash from hostname -> app_hash
# Use this matcher for <app-hash>-<app-name>-<env-name> style wildcard DNS routing
# server_name "~^(?<app_hash>[a-f0-9]{7})-(?<app_name>[a-z]{3,10})-(?<env_name>dev|prod})\$";
# Use this matcher for<app-name>/<app-hash>/ style routing (env-name optional)
server_name "";
# enable rewrite debugging logs - uncomment for debugging
#rewrite_log on;
#error_log /var/log/nginx/debug.log debug;
# Map to our custom erorr page - use this for a custom error page (include in your HTML dir)
error_page 404 /404.html;
# Support health checking
location ~ /health.html {
return 204;
# NOTE: this is a little tricky, we need to add the app path TWICE, since the location matcher will STRIP IT
location / {
# Rewrite / -> /index.html on upstream
# (1) / -> index.html
rewrite ^/$ /cdn/$env_name/$app_name/$app_hash/index.html last;
# (2) Anything without a file extension /foo, /foo/bar -> index.html
rewrite ^/(.*/)?[^\.]+$ /cdn/$env_name/$app_name/$app_hash/index.html last;
# (3) Add GCS path to all other requests
rewrite ^/(.*)$ /cdn/$env_name/$app_name/$app_hash/$1 last;
# The app name will be blank if someone is just fuzzing this proxy - don't proxy to GCS
# A blank app name (or otherwise invalid URL) will give us a double slash `//`
location ~ // {
return 404; # set 404 code
# Path parts matched here will be stripped by Nginx when resolving in the proxy, so just add the 'cdn/' prefix above
# proxy resolvers like this can have NO DYNAMIC MATCHERS/PARTS
location /cdn {
# Extra header info to help with debugging
set $upstream_url<YOUR-BUCKET-NAME-HERE>/$app_name/$app_hash/$1;
add_header X-app-hash "$app_hash";
add_header X-app-name "$app_name";
add_header X-upstream-url "$upstream_url";
# Note: no trailing slash, as the rewrite rules above/stripping will leave us with an appended slash
# Map error status codes
location = /404.html {
root /usr/share/nginx/html;
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log notice;
pid /var/run/;
events {
worker_connections 1024;
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_tokens off;
log_format main '[$time_local] "$host" "$remote_addr" "$http_x_forwarded_for" '
'"$http_x_forwarded_proto" "$http_referer" "$remote_user" "$request" $status $body_bytes_sent '
'$request_time $upstream_connect_time $upstream_header_time $upstream_response_time '
# Turn on for detailed debugging
#rewrite_log on;
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment