337 lines
9.3 KiB
Text
337 lines
9.3 KiB
Text
|
# vim: ft=nginx
|
||
|
|
||
|
keepalive_timeout 5;
|
||
|
|
||
|
if ($host = "www.quay.io") {
|
||
|
return 301 $proper_scheme://quay.io$request_uri;
|
||
|
}
|
||
|
|
||
|
# Disable the ability to be embedded into iframes
|
||
|
add_header X-Frame-Options DENY;
|
||
|
|
||
|
|
||
|
# Proxy Headers
|
||
|
proxy_set_header X-Forwarded-For $proper_forwarded_for;
|
||
|
proxy_set_header X-Forwarded-Proto $proper_scheme;
|
||
|
proxy_set_header Host $host;
|
||
|
proxy_redirect off;
|
||
|
|
||
|
proxy_set_header Transfer-Encoding $http_transfer_encoding;
|
||
|
|
||
|
location / {
|
||
|
proxy_pass http://web_app_server;
|
||
|
}
|
||
|
|
||
|
location /push {
|
||
|
proxy_pass http://web_app_server;
|
||
|
client_max_body_size 5M;
|
||
|
}
|
||
|
|
||
|
location /realtime {
|
||
|
proxy_pass http://web_app_server;
|
||
|
proxy_buffering off;
|
||
|
proxy_request_buffering off;
|
||
|
}
|
||
|
|
||
|
location ~ ^/_storage_proxy/([^/]+)/([^/]+)/([^/]+)/(.+) {
|
||
|
include resolver.conf;
|
||
|
|
||
|
auth_request /_storage_proxy_auth;
|
||
|
|
||
|
proxy_pass $2://$3/$4$is_args$args;
|
||
|
|
||
|
proxy_set_header X-Real-IP $remote_addr;
|
||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
|
proxy_set_header Host $3;
|
||
|
|
||
|
add_header Host $3;
|
||
|
|
||
|
proxy_buffering off;
|
||
|
proxy_request_buffering off;
|
||
|
|
||
|
proxy_read_timeout 60s;
|
||
|
}
|
||
|
|
||
|
location = /_storage_proxy_auth {
|
||
|
proxy_pass http://web_app_server;
|
||
|
proxy_pass_request_body off;
|
||
|
proxy_set_header Content-Length "";
|
||
|
|
||
|
proxy_set_header X-Original-URI $request_uri;
|
||
|
|
||
|
proxy_read_timeout 10;
|
||
|
}
|
||
|
|
||
|
location ~ ^/v2/_catalog(.*)$ {
|
||
|
proxy_pass http://registry_app_server;
|
||
|
proxy_read_timeout 10;
|
||
|
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
|
||
|
|
||
|
{% if enable_rate_limits %}
|
||
|
limit_req zone=dynamicauth_heavy_http1 burst=1 nodelay;
|
||
|
limit_req zone=dynamicauth_heavy_http2 burst=5 nodelay;
|
||
|
{% endif %}
|
||
|
}
|
||
|
|
||
|
location /secscan/ {
|
||
|
proxy_pass http://jwtproxy_secscan;
|
||
|
}
|
||
|
|
||
|
location /secscan/_internal_ping {
|
||
|
proxy_pass http://secscan_app_server;
|
||
|
}
|
||
|
|
||
|
{% if signing_enabled %}
|
||
|
location ~ ^/v2/(.+)/_trust/tuf/(.*)$ {
|
||
|
set $upstream_tuf {{ tuf_server }};
|
||
|
proxy_pass $upstream_tuf$uri;
|
||
|
proxy_set_header Host "{{ tuf_host }}";
|
||
|
}
|
||
|
{% endif %}
|
||
|
|
||
|
location /cnr {
|
||
|
proxy_buffering off;
|
||
|
|
||
|
proxy_request_buffering off;
|
||
|
|
||
|
proxy_pass http://registry_app_server;
|
||
|
proxy_read_timeout 120;
|
||
|
proxy_temp_path /tmp 1 2;
|
||
|
|
||
|
{% if enable_rate_limits %}
|
||
|
limit_req zone=staticauth burst=5 nodelay;
|
||
|
{% endif %}
|
||
|
}
|
||
|
|
||
|
location /api/ {
|
||
|
proxy_pass http://web_app_server;
|
||
|
|
||
|
{% if enable_rate_limits %}
|
||
|
limit_req zone=dynamicauth_heavy_http1 burst=25 nodelay;
|
||
|
limit_req zone=dynamicauth_heavy_http2 burst=100 nodelay;
|
||
|
{% endif %}
|
||
|
|
||
|
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
|
||
|
}
|
||
|
|
||
|
location /api/suconfig {
|
||
|
proxy_pass http://web_app_server;
|
||
|
|
||
|
# For suconfig, set our read timeout as super large for both DB migrations
|
||
|
# and awaiting for secrets to be updated.
|
||
|
proxy_read_timeout 2000;
|
||
|
}
|
||
|
|
||
|
# This block handles blob requests, and will receive a high volume of traffic, so we set the burst
|
||
|
# much higher.
|
||
|
location ~ /v2/([^/]+)\/[^/]+/blobs/ {
|
||
|
# If we're being accessed via v1.quay.io, pretend we don't support v2.
|
||
|
if ($host = "v1.quay.io") {
|
||
|
return 404;
|
||
|
}
|
||
|
|
||
|
# NOTE: We disable gzip for HEAD requests because Docker issues them to determine the Content
|
||
|
# Length of a blob. Unfortunately, nginx, seeing an empty body, overwrites the header with
|
||
|
# a length of 0, which breaks this functionality.
|
||
|
if ($request_method = HEAD) {
|
||
|
gzip off;
|
||
|
}
|
||
|
|
||
|
proxy_buffering off;
|
||
|
proxy_request_buffering off;
|
||
|
proxy_read_timeout 2000;
|
||
|
proxy_temp_path /tmp 1 2;
|
||
|
|
||
|
client_max_body_size {{ maximum_layer_size }};
|
||
|
|
||
|
# Setting ANY header clears all inherited proxy_set_header directives
|
||
|
proxy_set_header X-Forwarded-For $proper_forwarded_for;
|
||
|
proxy_set_header X-Forwarded-Proto $proper_scheme;
|
||
|
proxy_set_header Host $host;
|
||
|
|
||
|
proxy_http_version 1.1;
|
||
|
|
||
|
proxy_pass http://registry_app_server;
|
||
|
|
||
|
set $namespace $1;
|
||
|
|
||
|
{% if enable_rate_limits %}
|
||
|
limit_req zone=namespaced_dynamicauth_light_http1 burst=50 nodelay;
|
||
|
limit_req zone=namespaced_dynamicauth_light_http2 burst=100 nodelay;
|
||
|
{% endif %}
|
||
|
|
||
|
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
|
||
|
}
|
||
|
|
||
|
# This block handles tags endpoint requests, for which we want to restrict traffic due to how
|
||
|
# heavy an operation it can be
|
||
|
location ~ /v2/([^/]+)\/[^/]+/tags/ {
|
||
|
# If we're being accessed via v1.quay.io, pretend we don't support v2.
|
||
|
if ($host = "v1.quay.io") {
|
||
|
return 404;
|
||
|
}
|
||
|
|
||
|
# Setting ANY header clears all inherited proxy_set_header directives
|
||
|
proxy_set_header X-Forwarded-For $proper_forwarded_for;
|
||
|
proxy_set_header X-Forwarded-Proto $proper_scheme;
|
||
|
proxy_set_header Host $host;
|
||
|
|
||
|
proxy_http_version 1.1;
|
||
|
|
||
|
proxy_pass http://registry_app_server;
|
||
|
|
||
|
set $namespace $1;
|
||
|
|
||
|
{% if enable_rate_limits %}
|
||
|
limit_req zone=namespaced_dynamicauth_heavy_http1 burst=2 nodelay;
|
||
|
limit_req zone=namespaced_dynamicauth_heavy_http2 burst=2 nodelay;
|
||
|
{% endif %}
|
||
|
|
||
|
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
|
||
|
}
|
||
|
|
||
|
# This block handles manifests endpoint requests, for which we want to restrict traffic heavier than
|
||
|
# the generic V2 operations, as it handles pushes and pulls.
|
||
|
location ~ /v2/([^/]+)\/[^/]+/manifests/ {
|
||
|
# If we're being accessed via v1.quay.io, pretend we don't support v2.
|
||
|
if ($host = "v1.quay.io") {
|
||
|
return 404;
|
||
|
}
|
||
|
|
||
|
# Setting ANY header clears all inherited proxy_set_header directives
|
||
|
proxy_set_header X-Forwarded-For $proper_forwarded_for;
|
||
|
proxy_set_header X-Forwarded-Proto $proper_scheme;
|
||
|
proxy_set_header Host $host;
|
||
|
|
||
|
proxy_http_version 1.1;
|
||
|
|
||
|
proxy_pass http://registry_app_server;
|
||
|
|
||
|
set $namespace $1;
|
||
|
|
||
|
{% if enable_rate_limits %}
|
||
|
limit_req zone=namespaced_dynamicauth_light_http1 burst=10 nodelay;
|
||
|
limit_req zone=namespaced_dynamicauth_light_http2 burst=50 nodelay;
|
||
|
{% endif %}
|
||
|
|
||
|
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
|
||
|
}
|
||
|
|
||
|
# This block applies to the beginning of a push or pull
|
||
|
location = /v2/auth {
|
||
|
# If we're being accessed via v1.quay.io, pretend we don't support v2.
|
||
|
if ($host = "v1.quay.io") {
|
||
|
return 404;
|
||
|
}
|
||
|
|
||
|
# Setting ANY header clears all inherited proxy_set_header directives
|
||
|
proxy_set_header X-Forwarded-For $proper_forwarded_for;
|
||
|
proxy_set_header X-Forwarded-Proto $proper_scheme;
|
||
|
proxy_set_header Host $host;
|
||
|
|
||
|
proxy_http_version 1.1;
|
||
|
|
||
|
proxy_pass http://registry_app_server;
|
||
|
|
||
|
{% if enable_rate_limits %}
|
||
|
limit_req zone=staticauth burst=2 nodelay;
|
||
|
{% endif %}
|
||
|
|
||
|
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
|
||
|
}
|
||
|
|
||
|
# This block handles all other V2 requests, for which we can use a higher rate limit.
|
||
|
location ~ ^/v2 {
|
||
|
# If we're being accessed via v1.quay.io, pretend we don't support v2.
|
||
|
if ($host = "v1.quay.io") {
|
||
|
return 404;
|
||
|
}
|
||
|
|
||
|
# NOTE: We disable gzip for HEAD requests because Docker issues them to determine the Content
|
||
|
# Length of a blob. Unfortunately, nginx, seeing an empty body, overwrites the header with
|
||
|
# a length of 0, which breaks this functionality. Included here for completeness.
|
||
|
if ($request_method = HEAD) {
|
||
|
gzip off;
|
||
|
}
|
||
|
|
||
|
# Setting ANY header clears all inherited proxy_set_header directives
|
||
|
proxy_set_header X-Forwarded-For $proper_forwarded_for;
|
||
|
proxy_set_header X-Forwarded-Proto $proper_scheme;
|
||
|
proxy_set_header Host $host;
|
||
|
|
||
|
proxy_http_version 1.1;
|
||
|
|
||
|
proxy_pass http://registry_app_server;
|
||
|
|
||
|
{% if enable_rate_limits %}
|
||
|
limit_req zone=dynamicauth_very_light_http1 burst=20 nodelay;
|
||
|
limit_req zone=dynamicauth_very_light_http2 burst=80 nodelay;
|
||
|
{% endif %}
|
||
|
|
||
|
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
|
||
|
}
|
||
|
|
||
|
location /v1/ {
|
||
|
# Setting ANY header clears all inherited proxy_set_header directives
|
||
|
proxy_set_header X-Forwarded-For $proper_forwarded_for;
|
||
|
proxy_set_header X-Forwarded-Proto $proper_scheme;
|
||
|
proxy_set_header Host $host;
|
||
|
|
||
|
proxy_buffering off;
|
||
|
|
||
|
proxy_request_buffering off;
|
||
|
|
||
|
proxy_http_version 1.1;
|
||
|
|
||
|
proxy_pass http://registry_app_server;
|
||
|
proxy_temp_path /tmp 1 2;
|
||
|
|
||
|
client_max_body_size {{ maximum_layer_size }};
|
||
|
|
||
|
{% if enable_rate_limits %}
|
||
|
limit_req zone=dynamicauth_heavy_http1 burst=5 nodelay;
|
||
|
limit_req zone=dynamicauth_heavy_http2 burst=25 nodelay;
|
||
|
{% endif %}
|
||
|
|
||
|
keepalive_timeout 0; # Disables HTTP 1.1 keep-alive and forces round-robin.
|
||
|
}
|
||
|
|
||
|
location = /v1/_ping {
|
||
|
add_header Content-Type text/plain;
|
||
|
add_header X-Docker-Registry-Version 0.6.0;
|
||
|
add_header X-Docker-Registry-Standalone 0;
|
||
|
return 200 'true';
|
||
|
}
|
||
|
|
||
|
location /c1/ {
|
||
|
proxy_buffering off;
|
||
|
|
||
|
proxy_request_buffering off;
|
||
|
|
||
|
proxy_pass http://verbs_app_server;
|
||
|
proxy_temp_path /tmp 1 2;
|
||
|
|
||
|
{% if enable_rate_limits %}
|
||
|
limit_req zone=staticauth burst=5 nodelay;
|
||
|
{% endif %}
|
||
|
}
|
||
|
|
||
|
location /static/ {
|
||
|
# checks for static file, if not found proxy to app
|
||
|
alias {{static_dir}}/;
|
||
|
error_page 404 /404;
|
||
|
}
|
||
|
|
||
|
error_page 502 {{static_dir}}/502.html;
|
||
|
|
||
|
location ~ ^/b1/controller(/?)(.*) {
|
||
|
proxy_pass http://build_manager_controller_server/$2;
|
||
|
}
|
||
|
|
||
|
location ~ ^/b1/socket(/?)(.*) {
|
||
|
proxy_pass http://build_manager_websocket_server/$2;
|
||
|
proxy_http_version 1.1;
|
||
|
proxy_set_header Upgrade $http_upgrade;
|
||
|
proxy_set_header Connection "upgrade";
|
||
|
proxy_read_timeout 300;
|
||
|
}
|