-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathnginx.conf.template
399 lines (315 loc) · 13.8 KB
/
nginx.conf.template
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
worker_processes auto;
daemon off;
error_log stderr warn;
events {
# For deployment in Kubernetes we should always "use epoll" (most efficient). Optionally you can disable it for local testing.
${USE_EPOLL}
worker_connections ${WORKER_CONNECTIONS};
multi_accept on;
}
http {
charset utf-8;
# EA-2236: Disable access logs
access_log off;
default_type application/octet-stream;
include mime.types;
sendfile on;
tcp_nodelay on;
tcp_nopush on;
# Note that connections will be cut-off after 50 seconds by something in kubernetes
keepalive_timeout 60;
# Note that for upstream servers all IP addresses/services need to be available on start-up!
upstream annotation_api {
keepalive 10;
server ${ANNOTATION_API_HOST};
}
upstream embedding_apis {
keepalive 10;
# We'll not only specify server name using env variables but also settings
# This way we can mark a server as down (for maintenance) in a deployment job
server ${EMBEDDING_SERVER1_SETTINGS};
server ${EMBEDDING_SERVER2_SETTINGS};
}
upstream entity_api {
keepalive 10;
server ${ENTITY_API_HOST};
}
upstream entity_management {
keepalive 10;
server ${ENTITY_MANAGEMENT_HOST};
}
upstream fulltext_api {
keepalive 10;
server ${FULLTEXT_API_HOST};
}
upstream keycloak {
keepalive 10;
server ${KEYCLOAK_HOST};
}
upstream manifest_api {
keepalive 10;
server ${MANIFEST_API_HOST};
}
upstream newspaper_api {
keepalive 10;
server ${NEWSPAPER_API_HOST};
}
upstream oai_record {
keepalive 10;
server ${OAI_RECORD_HOST};
}
upstream recommendation_api {
keepalive 10;
server ${RECOMMENDATION_API_HOST};
}
upstream search_api {
keepalive 10;
server ${SEARCH_API_HOST};
}
upstream set_api {
keepalive 10;
server ${SET_API_HOST};
}
upstream thumbnail_api {
keepalive 10;
server ${THUMBNAIL_API_HOST};
}
upstream translation_api {
keepalive 10;
# Translation API enforces https
server ${TRANSLATION_API_HOST};
}
server {
listen ${PORT} default_server;
root ${PUBLIC_FOLDER};
index index.html;
# HTTPS enforcement should be done within Kubernetes ingress
# "upstream" servers do not use resolver settings by default (paid option), so we proxy directly to the urls
#resolver ${RESOLVER_SETTINGS};
add_header Link "<http://creativecommons.org/publicdomain/zero/1.0/>;rel=license";
include nginx.conf.d/*.conf;
# ----------------------------------------------------------
# CORS config for nginx
# "location /" works as "last resort" and applies to everything that is not matched by other rules
# ----------------------------------------------------------
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
# Custom headers and headers various browsers *should* be OK with but aren't
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,ETag,Cache-Control,Content-Type,Range';
# Tell client that this pre-flight info is valid for 20 days
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
#if ($request_method = 'POST') {
# add_header 'Access-Control-Allow-Origin' '*' always;
# add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
# add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,ETag,Cache-Control,Content-Type,Range' always;
# add_header 'Access-Control-Expose-Headers' 'ETag,Content-Range' always;
#}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,ETag,Cache-Control,Content-Type,Range' always;
# See also https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_response_header
add_header 'Access-Control-Expose-Headers' 'ETag,Content-Range' always;
add_header 'Cache-Control' 'public, max-age=604800, must-revalidate';
}
}
# ----------------------------------------------------------
# Redirect root
location = / {
return 302 ${ROOT_REDIRECT_URL};
}
# Used by Kubernetes health checks
location /nginx-health {
default_type application/json;
return 200 '{"status":"healthy"}';
}
## ----- Search & Record API ----- ##
# Old /api/v2/record and search.json requests
location ~ ^/api/(.*) {
rewrite ^/api/(.*)$ /api/$1 break;
proxy_set_header Host ${SEARCH_API_HOST};
proxy_pass http://search_api;
}
# Recommendation API for records (alternative path, has to be defined before Search & Record)
location ~ ^/record/(v2/)?(.*)/recommend {
proxy_set_header Host ${RECOMMENDATION_API_HOST};
proxy_pass http://recommendation_api/recommend/record/$2$is_args$args;
}
# Search API v3
location ~ ^/record/v3/search(.*)$ {
proxy_set_header Host ${SEARCH_API_HOST};
proxy_pass http://search_api/record/v3/search.json$is_args$args;
}
# Search API
location ~ ^/record/(v2/)?(open)?search(.*)$ {
proxy_set_header Host ${SEARCH_API_HOST};
proxy_pass http://search_api/record/search.json$is_args$args;
}
# Record API
location ~ ^/record/(v2/)?(.*) {
rewrite ^/record/(v2/)?(.*)$ /api/v2/record/$2 break;
proxy_set_header Host ${SEARCH_API_HOST};
proxy_pass http://search_api;
}
# Always enable CORS for Search & Record API Swagger endpoint (as bug fix)
location = /record/api-docs {
proxy_set_header Host ${SEARCH_API_HOST};
proxy_hide_header Access-Control-Allow-Origin;
add_header Access-Control-Allow-Origin "*";
proxy_pass http://search_api/api/api-docs;
}
## ----- Thumbnail API ----- ##
# Thumbnail API v2 (old style)
location = /api/v2/thumbnail-by-url.json {
# Thumbnails are JPEGs; no need to gzip them
gzip off;
proxy_set_header Host ${THUMBNAIL_API_HOST};
proxy_pass http://thumbnail_api;
}
# Thumbnail API v2 (new style)
location = /thumbnail/v2/url.json {
# Thumbnails are JPEGs; no need to gzip them
gzip off;
proxy_set_header Host ${THUMBNAIL_API_HOST};
proxy_pass http://thumbnail_api/api/v2/thumbnail-by-url.json$is_args$args;
}
location ~ /thumbnail/v2/(.*) {
# To make sure incorrect v2 requests are not sent to v3
return 404;
}
# Thumbnail API v3
location ~ /thumbnail/(v3/)?(.*) {
# Thumbnails are JPEGs; no need to gzip them
gzip off;
proxy_set_header Host ${THUMBNAIL_API_HOST};
proxy_pass http://thumbnail_api/thumbnail/v3/$2$is_args$args;
}
## ----- OAI-PMH ----- ##
# OAI-PMH requests
location = /oai/record {
proxy_set_header Host ${OAI_RECORD_HOST};
proxy_pass http://oai_record/oai/$is_args$args;
}
# OAI-PMH index page
location = /oai/record/ {
proxy_set_header Host ${OAI_RECORD_HOST};
proxy_pass http://oai_record/index.html;
}
# Change all OAI-PMH .shtml form pages to .html
location ~ ^/oai/record/(.*)\.shtml {
return 301 https://$host/oai/record/$1.html;
}
# OAI-PMH query forms
location ~ ^/oai/record/(.*)\.html {
proxy_set_header Host ${OAI_RECORD_HOST};
proxy_pass http://oai_record/$1.html;
}
## ----- Annotation API ----- ##
location ~ ^/annotation/(.*) {
proxy_set_header Host ${ANNOTATION_API_HOST};
proxy_pass http://annotation_api/annotation/$1$is_args$args;
}
## ----- Recommendation API for Entities ----- ##
# Recommendation API for entities (alternative path, has to be defined before /entity/* route)
location ~ ^/entity/(.*)/recommend {
proxy_set_header Host ${RECOMMENDATION_API_HOST};
proxy_pass http://recommendation_api/recommend/entity/$1$is_args$args;
}
## ----- Entity API ----- ##
# Entity - search, resolve and suggest are routed to Entity API
location ~ ^/entity/(search|suggest|resolve|enrich|stats)(.*) {
proxy_set_header Host ${ENTITY_API_HOST};
proxy_pass http://entity_api/entity/$1$2$is_args$args;
}
# Entity - all other requests go to Entity Management
location ~ ^/entity/(.*) {
proxy_set_header Host ${ENTITY_MANAGEMENT_HOST};
proxy_pass http://entity_management/entity/$1$is_args$args;
}
## ----- IIIF Manifest API ----- ##
location ~ ^/presentation/(.*)/manifest$ {
proxy_set_header Host ${MANIFEST_API_HOST};
proxy_pass http://manifest_api/presentation/$1/manifest$is_args$args;
}
## ----- Newspaper Search ----- ##
# Newspaper search (has to be defined before fulltext/* route)
location = /fulltext/search.json {
proxy_set_header Host ${NEWSPAPER_API_HOST};
proxy_pass http://newspaper_api/api/v2/search.json$is_args$args;
}
## ----- IIIF Fulltext API ----- ##
location ~ ^/(fulltext|presentation)/(.*) {
proxy_set_header Host ${FULLTEXT_API_HOST};
proxy_pass http://fulltext_api/presentation/$2$is_args$args;
}
## ----- Recommendation API ----- ##
location ~ ^/recommend/(.*) {
proxy_set_header Host ${RECOMMENDATION_API_HOST};
proxy_pass http://recommendation_api/recommend/$1$is_args$args;
}
# Recommendation API for sets (alternative path, has to be defined before /set/* route)
location ~ ^/set/(.*)/recommend {
proxy_set_header Host ${RECOMMENDATION_API_HOST};
proxy_pass http://recommendation_api/recommend/set/$1$is_args$args;
}
# Sets API
location ~ ^/set/(.*) {
proxy_set_header Host ${SET_API_HOST};
proxy_pass http://set_api/set/$1$is_args$args;
}
## ----- Translation API ----- ##
# no rewrite needed for proxying HOST requests - updated for EA-3859
location ~* ^/translation/(.*) {
proxy_set_header Host ${TRANSLATION_API_HOST};
proxy_pass http://translation_api/$1$is_args$args;
}
## ----- Embeddings API (load balanced)----- ##
location ~* ^/embedding/(.*) {
proxy_set_header Host ${EMBEDDING_API_HOST};
# No load balancing algorithm defined, so by default round-robin is used
proxy_pass http://embedding_apis/embedding_api/$1$is_args$args;
# Send to next server in list in case of errors
proxy_next_upstream error timeout http_502 http_503 http_504;
}
## ----- Consoles and attribution ----- ##
location ~* ^/console/(record|iiif|annotation|thumbnail|ld|search|translation|entity|oai|set|recommendation)$ {
return 307 https://$host/console/index.html?url=docs/v3/$1.json;
}
# Old and deprecated (kept for the time being for backward compatibility)
# ----------------------------------------------------------
# Redirect old record url format (to be removed?)
# Nov 2019 - again 0 hits in last 4 months
# March 2020 - 0 hits at API, but I did notice that we have quite a bit of /resolve/record requests coming in via
# Portal, so for now I'm not removing entirely because I'm not sure if this means we want to put it back
# location ~ ^/resolve/record/(.*) {
# return 301 https://$host/api/v2/record/$1$is_args$args;
# }
# EA-3761 Keycloak tests
# location ~ ^/(auth)/?(protocol/openid-connect|account)?(.*)? {
# set $authPath $1/realms/europeana/$2$3;
# proxy_set_header Host ${KEYCLOAK_HOST};
# add_header 'X-Wickie' "$authPath" always;
# proxy_pass http://keycloak/$authPath;
# }
#
# location ~ ^/(auth)(/realms/europeana)(/protocol/openid-connect|/account)?(.*)? {
# set $authPath $1/realms/europeana/$3$4;
# proxy_set_header Host ${KEYCLOAK_HOST};
# add_header 'X-Wickie' "$authPath" always;
# proxy_pass http://keycloak/$authPath;
# }
# Redirect old thumbnail url format
# Feb 2019 - about 1000 requests a month are still done directly to api (and all of them fail with 500 or 404)
# Nov 2019 - still about 1000 requests per month, most return 500 or 404, a few return 301
# Apr 2024 - about 25 requests per month, we can start deprecating this now
# location = /api/image {
# return 301 https://$host/api/v2/thumbnail-by-url.json$is_args$args;
# }
}
}