diff --git a/api/src/core/db.py b/api/src/core/db.py index da9c415..61aca8a 100644 --- a/api/src/core/db.py +++ b/api/src/core/db.py @@ -2,7 +2,11 @@ from src.core.settings import settings import src.models -engine = create_engine(str(settings.PGSQL_DATABASE_URI)) +engine = create_engine( + str(settings.PGSQL_DATABASE_URI), + pool_size=settings.POSTGRES_POOL_SIZE, + max_overflow=settings.POSTGRES_MAX_OVERFLOW, +) async def init_db(): diff --git a/api/src/core/settings.py b/api/src/core/settings.py index 5b7942a..07c1820 100644 --- a/api/src/core/settings.py +++ b/api/src/core/settings.py @@ -18,6 +18,8 @@ class Settings(BaseSettings): POSTGRES_USER: str POSTGRES_PASSWORD: str = "" POSTGRES_DB: str = "" + POSTGRES_POOL_SIZE: int = 15 + POSTGRES_MAX_OVERFLOW: int = 20 # Keycloak KEYCLOAK_URL: str = "" diff --git a/deployment/.env.prod.example b/deployment/.env.prod.example index 3c19a7b..b432f2d 100644 --- a/deployment/.env.prod.example +++ b/deployment/.env.prod.example @@ -15,7 +15,7 @@ MONGO_PASSWORD=template_pass # Garage object storage (S3-compatible API) FILE_STORAGE_BACKEND=garage GARAGE_S3_ENDPOINT=http://garage:3900 -GARAGE_S3_PUBLIC_ENDPOINT=http://localhost:3900 +GARAGE_S3_PUBLIC_ENDPOINT=https://mednat.ieeta.pt:9071/garage GARAGE_S3_REGION=garage GARAGE_ACCESS_KEY_ID=garage-access-key GARAGE_SECRET_ACCESS_KEY=garage-secret-key diff --git a/deployment/nginx.mednat.conf b/deployment/nginx.mednat.conf index b748efc..f7c27dc 100644 --- a/deployment/nginx.mednat.conf +++ b/deployment/nginx.mednat.conf @@ -37,6 +37,11 @@ http { server keycloak:8080 resolve max_fails=3 fail_timeout=30s; } + upstream garages { + zone garages 64k; + server garage:3900 resolve max_fails=3 fail_timeout=30s; + } + upstream grafanas { zone grafanas 64k; server grafana:3000 resolve max_fails=3 fail_timeout=30s; @@ -97,6 +102,23 @@ http { proxy_set_header X-Forwarded-Port $forwarded_port; } + # Garage S3 API on same host via /garage for presigned object URLs. + location = /garage { + return 301 /garage/; + } + location /garage/ { + rewrite ^/garage/(.*)$ /$1 break; + proxy_pass http://garages; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $http_host; + proxy_set_header X-Forwarded-Port $forwarded_port; + } + # Frontend entrypoint is /app. location = / { diff --git a/deployment/nginx.securelearning.conf b/deployment/nginx.securelearning.conf index dc8fedc..1bb85c7 100644 --- a/deployment/nginx.securelearning.conf +++ b/deployment/nginx.securelearning.conf @@ -31,6 +31,11 @@ http { server keycloak:8080 resolve max_fails=3 fail_timeout=30s; } + upstream garages { + zone garages 64k; + server garage:3900 resolve max_fails=3 fail_timeout=30s; + } + upstream grafanas { zone grafanas 64k; server grafana:3000 resolve max_fails=3 fail_timeout=30s; @@ -102,6 +107,36 @@ http { } } + # Garage S3 - s3.localhost / s3.securelearning.pt + server { + listen 8081 ssl; + listen [::]:8081 ssl; + server_name s3.localhost s3.securelearning.pt s3.mednat.ieeta.pt; + + ssl_certificate /etc/nginx/certs/tls.crt; + ssl_certificate_key /etc/nginx/certs/tls.key; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + + proxy_buffer_size 128k; + proxy_buffers 4 256k; + proxy_busy_buffers_size 256k; + large_client_header_buffers 4 32k; + + location / { + proxy_pass http://garages/; + proxy_redirect off; + proxy_http_version 1.1; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $http_host; + } + } + # Keycloak - kc.localhost / kc.securelearning.pt server { listen 8081 ssl; diff --git a/performance/k6/base-user.js b/performance/k6/base-user.js index aff0b27..a968b27 100644 --- a/performance/k6/base-user.js +++ b/performance/k6/base-user.js @@ -28,7 +28,7 @@ export const options = { const scenarios = { current_user: { executor: "constant-arrival-rate", - rate: Number(__ENV.K6_PROFILE_RATE || 5), + rate: Number(__ENV.K6_PROFILE_RATE || 15), timeUnit: "1s", duration: __ENV.K6_DURATION || "1m", preAllocatedVUs: Number(__ENV.K6_PREALLOCATED_VUS || 5), @@ -38,7 +38,7 @@ export const options = { }, enrolled_courses: { executor: "constant-arrival-rate", - rate: Number(__ENV.K6_ENROLLED_RATE || 5), + rate: Number(__ENV.K6_ENROLLED_RATE || 15), timeUnit: "1s", duration: __ENV.K6_DURATION || "1m", preAllocatedVUs: Number(__ENV.K6_PREALLOCATED_VUS || 5), @@ -48,7 +48,7 @@ export const options = { }, progress_list: { executor: "constant-arrival-rate", - rate: Number(__ENV.K6_PROGRESS_RATE || 5), + rate: Number(__ENV.K6_PROGRESS_RATE || 15), timeUnit: "1s", duration: __ENV.K6_DURATION || "1m", preAllocatedVUs: Number(__ENV.K6_PREALLOCATED_VUS || 5), @@ -58,7 +58,7 @@ export const options = { }, certificates: { executor: "constant-arrival-rate", - rate: Number(__ENV.K6_CERTIFICATES_RATE || 3), + rate: Number(__ENV.K6_CERTIFICATES_RATE || 15), timeUnit: "1s", duration: __ENV.K6_DURATION || "1m", preAllocatedVUs: Number(__ENV.K6_PREALLOCATED_VUS || 5), @@ -68,7 +68,7 @@ export const options = { }, my_stats: { executor: "constant-arrival-rate", - rate: Number(__ENV.K6_ME_STATS_RATE || 3), + rate: Number(__ENV.K6_ME_STATS_RATE || 15), timeUnit: "1s", duration: __ENV.K6_DURATION || "1m", preAllocatedVUs: Number(__ENV.K6_PREALLOCATED_VUS || 5), @@ -78,7 +78,7 @@ export const options = { }, compliance_status: { executor: "constant-arrival-rate", - rate: Number(__ENV.K6_COMPLIANCE_RATE || 3), + rate: Number(__ENV.K6_COMPLIANCE_RATE || 15), timeUnit: "1s", duration: __ENV.K6_DURATION || "1m", preAllocatedVUs: Number(__ENV.K6_PREALLOCATED_VUS || 5), @@ -88,7 +88,7 @@ export const options = { }, compliance_doc: { executor: "constant-arrival-rate", - rate: Number(__ENV.K6_COMPLIANCE_DOC_RATE || 2), + rate: Number(__ENV.K6_COMPLIANCE_DOC_RATE || 15), timeUnit: "1s", duration: __ENV.K6_DURATION || "1m", preAllocatedVUs: Number(__ENV.K6_PREALLOCATED_VUS || 5), @@ -98,7 +98,7 @@ export const options = { }, compliance_quiz: { executor: "constant-arrival-rate", - rate: Number(__ENV.K6_COMPLIANCE_QUIZ_RATE || 2), + rate: Number(__ENV.K6_COMPLIANCE_QUIZ_RATE || 15), timeUnit: "1s", duration: __ENV.K6_DURATION || "1m", preAllocatedVUs: Number(__ENV.K6_PREALLOCATED_VUS || 5), @@ -111,7 +111,7 @@ export const options = { if (courseId) { scenarios.course_progress = { executor: "constant-arrival-rate", - rate: Number(__ENV.K6_COURSE_PROGRESS_RATE || 3), + rate: Number(__ENV.K6_COURSE_PROGRESS_RATE || 15), timeUnit: "1s", duration: __ENV.K6_DURATION || "1m", preAllocatedVUs: Number(__ENV.K6_PREALLOCATED_VUS || 5),