Skip to content

Commit

Permalink
OLMIS-2957, provide better nginx.conf
Browse files Browse the repository at this point in the history
Override the nginx.conf that comes in the base image with one more suitable to our deployment topology (AWS single host on linux) and document how an implementation should override our configuration in case they're on a different topology.
  • Loading branch information
joshzamor committed Aug 7, 2017
1 parent b81ab8b commit a216063
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 117 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ RUN wget -O /home/consul-template.zip \
rm /home/consul-template.zip && \
mkdir /var/log/consul-template

COPY nginx.conf /etc/consul-template/nginx.conf
COPY nginx.conf /etc/nginx/nginx.conf
COPY openlmis.conf /etc/consul-template/openlmis.conf
COPY run.sh /home/run.sh

VOLUME [ "/var/log/nginx", "/var/log/consul-template" ]

ENTRYPOINT [ "/home/run.sh" ]

14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ And importantly:
/users/staff - referencedata service (as placeholder matches it, and it is not explicitly defined elsewhere).
/users/staff/validate - auth service.

## Configuration

This customized Nginx image comes with two configuration files:

1. `nginx.conf` is the standard Nginx config file. For customizing this to
your deployment topology, simply overwrite this file by mounting your own
as a Docker volume. e.g.

`docker run -v /your/local/nginx.conf:/etc/nginx/nginx.conf`
1. `openlmis.conf` is the Consul-Template generated Nginx configuration which
needs to be included in the `nginx.conf` above. This configuration should not
be overridden, though it does have a number of environment variables by which
to customize Nginx behavior.

## Logging
By default, Nginx logs are stored under `/var/log/nginx` directory, and Consul Template logs can be found in `/var/log/consul-template` folder. Each of those directories is marked as VOLUME and can be mounted to, in order to retrieve logging data. Additionally, user can specify different directories for logging, using `NGINX_LOG_DIR` and `CONSUL_TEMPLATE_LOG_DIR` environment variables.

Expand Down
136 changes: 22 additions & 114 deletions nginx.conf
Original file line number Diff line number Diff line change
@@ -1,125 +1,33 @@
{{ $loaded_services := services }}
{{ $resources := tree (env "RESOURCES_PATH") }}
user nginx;
worker_processes 1;

{{ range $loaded_services }}
{{- if in .Tags (env "SERVICE_TAG") -}}
{{- $current_service := service .Name "any" -}}
{{- if not (eq (len $current_service) 0) }}
upstream {{ .Name }} {
least_conn;
{{ range $current_service }}server {{ .Address }}:{{ .Port }};
{{ end }}
}
{{ end -}}
{{- end -}}
{{ end }}
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

log_format upstream_time '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_connect_time '
'$upstream_header_time $upstream_response_time '
'$pipe';

server {
listen 80;
gzip on;
gzip_types application/json text/plain;
access_log {{ env "NGINX_LOG_DIR" }}/access.log upstream_time;
error_log {{ env "NGINX_LOG_DIR" }}/error.log;
server_name {{ env "VIRTUAL_HOST" }};
client_max_body_size {{ env "CLIENT_MAX_BODY_SIZE" }};
proxy_connect_timeout {{ env "PROXY_CONNECT_TIMEOUT" }};
proxy_send_timeout {{ env "PROXY_SEND_TIMEOUT" }};
proxy_read_timeout {{ env "PROXY_READ_TIMEOUT" }};
send_timeout {{ env "SEND_TIMEOUT" }};

{{ $paramRegex := "{[\\w-]+}" }}
{{ $allRegex := "<[\\w-]+>" }}
{{ $globalAllRegex := "^<[\\w-]+>$" }}

{{ $paramReplace := "[\\w-]+" }}
{{ $allReplace := ".+" }}

# First retrieve paths without parameters
{{ range $resources }} {{ $location := .Key }} {{ $upstream := .Value }}
{{- if not (or (regexMatch $paramRegex $location) (regexMatch $allRegex $location)) }}
location ~ /{{ $location }}/?$ {
{{- if eq (env "REQUIRE_SSL") "true" }}
if ($http_x_forwarded_proto != "https") {
return 307 https://$host$request_uri;
}
{{ end }}

proxy_pass http://{{ $upstream }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}
{{ end -}}
{{ end }}

# Retrieve paths with {param} wildcard
{{ range $resources }} {{ $location := .Key }} {{ $upstream := .Value }}
{{- if regexMatch $paramRegex $location }}
{{ $location := ($location | regexReplaceAll $paramRegex $paramReplace) }}
location ~ /{{ $location }}/?$ {
{{- if eq (env "REQUIRE_SSL") "true" }}
if ($http_x_forwarded_proto != "https") {
return 307 https://$host$request_uri;
}
{{ end }}
events {
worker_connections 10000;
multi_accept on;
use epoll;
}

proxy_pass http://{{ $upstream }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}
{{ end -}}
{{ end }}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

# Retrieve paths with <all> wildcard, but without global wildcard
{{ range $resources }} {{ $location := .Key }} {{ $upstream := .Value }}
{{- if and (regexMatch $allRegex $location) (not (regexMatch $globalAllRegex $location)) }}
{{ $location := ($location | regexReplaceAll $allRegex $allReplace) }}
location ~ /{{ $location }}/?$ {
{{- if eq (env "REQUIRE_SSL") "true" }}
if ($http_x_forwarded_proto != "https") {
return 307 https://$host$request_uri;
}
{{ end }}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

proxy_pass http://{{ $upstream }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}
{{ end -}}
{{ end }}
access_log /var/log/nginx/access.log main;

# Retrieve global <all> wildcard (if existent)
{{ range $resources }} {{ $location := .Key }} {{ $upstream := .Value }}
{{- if regexMatch $globalAllRegex $location }}
location ~ / {
{{- if eq (env "REQUIRE_SSL") "true" }}
if ($http_x_forwarded_proto != "https") {
return 307 https://$host$request_uri;
}
{{ end }}
sendfile on;
tcp_nopush on;
tcp_nodelay on;

proxy_pass http://{{ $upstream }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}
keepalive_timeout 65;

location ~ /.+$ {
{{- if eq (env "REQUIRE_SSL") "true" }}
if ($http_x_forwarded_proto != "https") {
return 307 https://$host$request_uri;
}
{{ end }}
#gzip on;

proxy_pass http://{{ $upstream }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}
{{ end -}}
{{ end }}
include /etc/nginx/conf.d/*.conf;
}
126 changes: 126 additions & 0 deletions openlmis.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
{{ $loaded_services := services }}
{{ $resources := tree (env "RESOURCES_PATH") }}

{{ range $loaded_services }}
{{- if in .Tags (env "SERVICE_TAG") -}}
{{- $current_service := service .Name "any" -}}
{{- if not (eq (len $current_service) 0) }}
upstream {{ .Name }} {
least_conn;
{{ range $current_service }}server {{ .Address }}:{{ .Port }};
{{ end }}
}
{{ end -}}
{{- end -}}
{{ end }}

log_format upstream_time '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_connect_time '
'$upstream_header_time $upstream_response_time '
'$pipe';

server {
listen 80;
gzip on;
gzip_min_length 1000;
gzip_types application/json text/plain;
access_log {{ env "NGINX_LOG_DIR" }}/access.log upstream_time;
error_log {{ env "NGINX_LOG_DIR" }}/error.log;
server_name {{ env "VIRTUAL_HOST" }};
client_max_body_size {{ env "CLIENT_MAX_BODY_SIZE" }};
proxy_connect_timeout {{ env "PROXY_CONNECT_TIMEOUT" }};
proxy_send_timeout {{ env "PROXY_SEND_TIMEOUT" }};
proxy_read_timeout {{ env "PROXY_READ_TIMEOUT" }};
send_timeout {{ env "SEND_TIMEOUT" }};

{{ $paramRegex := "{[\\w-]+}" }}
{{ $allRegex := "<[\\w-]+>" }}
{{ $globalAllRegex := "^<[\\w-]+>$" }}

{{ $paramReplace := "[\\w-]+" }}
{{ $allReplace := ".+" }}

# First retrieve paths without parameters
{{ range $resources }} {{ $location := .Key }} {{ $upstream := .Value }}
{{- if not (or (regexMatch $paramRegex $location) (regexMatch $allRegex $location)) }}
location ~ /{{ $location }}/?$ {
{{- if eq (env "REQUIRE_SSL") "true" }}
if ($http_x_forwarded_proto != "https") {
return 307 https://$host$request_uri;
}
{{ end }}

proxy_pass http://{{ $upstream }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}
{{ end -}}
{{ end }}

# Retrieve paths with {param} wildcard
{{ range $resources }} {{ $location := .Key }} {{ $upstream := .Value }}
{{- if regexMatch $paramRegex $location }}
{{ $location := ($location | regexReplaceAll $paramRegex $paramReplace) }}
location ~ /{{ $location }}/?$ {
{{- if eq (env "REQUIRE_SSL") "true" }}
if ($http_x_forwarded_proto != "https") {
return 307 https://$host$request_uri;
}
{{ end }}

proxy_pass http://{{ $upstream }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}
{{ end -}}
{{ end }}

# Retrieve paths with <all> wildcard, but without global wildcard
{{ range $resources }} {{ $location := .Key }} {{ $upstream := .Value }}
{{- if and (regexMatch $allRegex $location) (not (regexMatch $globalAllRegex $location)) }}
{{ $location := ($location | regexReplaceAll $allRegex $allReplace) }}
location ~ /{{ $location }}/?$ {
{{- if eq (env "REQUIRE_SSL") "true" }}
if ($http_x_forwarded_proto != "https") {
return 307 https://$host$request_uri;
}
{{ end }}

proxy_pass http://{{ $upstream }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}
{{ end -}}
{{ end }}

# Retrieve global <all> wildcard (if existent)
{{ range $resources }} {{ $location := .Key }} {{ $upstream := .Value }}
{{- if regexMatch $globalAllRegex $location }}
location ~ / {
{{- if eq (env "REQUIRE_SSL") "true" }}
if ($http_x_forwarded_proto != "https") {
return 307 https://$host$request_uri;
}
{{ end }}

proxy_pass http://{{ $upstream }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}

location ~ /.+$ {
{{- if eq (env "REQUIRE_SSL") "true" }}
if ($http_x_forwarded_proto != "https") {
return 307 https://$host$request_uri;
}
{{ end }}

proxy_pass http://{{ $upstream }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}
{{ end -}}
{{ end }}
}
2 changes: 1 addition & 1 deletion run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export SEND_TIMEOUT="${SEND_TIMEOUT:-${NGINX_TIMEOUT:-60s}}"

# Run consul-template in background
CONSUL_PATH="${CONSUL_HOST}:${CONSUL_PORT}"
INPUT_FILE="/etc/consul-template/nginx.conf"
INPUT_FILE="/etc/consul-template/openlmis.conf"
OUTPUT_FILE="/etc/nginx/conf.d/default.conf"
CALLBACK="nginx -s reload"

Expand Down

0 comments on commit a216063

Please sign in to comment.