varnish
This commit is contained in:
88
deploy/varnish/default.vcl.template
Normal file
88
deploy/varnish/default.vcl.template
Normal file
@@ -0,0 +1,88 @@
|
||||
vcl 4.1;
|
||||
|
||||
import vsthrottle;
|
||||
import std;
|
||||
|
||||
backend app {
|
||||
.host = "app";
|
||||
.port = "${APP_PORT}";
|
||||
}
|
||||
|
||||
acl purge { "127.0.0.1"; "::1"; }
|
||||
|
||||
sub vcl_recv {
|
||||
# RATE LIMIT: 100 żądań / 10s, blokada 60s
|
||||
if (vsthrottle.is_denied(client.identity, 100, 10s, 60s)) {
|
||||
return (synth(429, "Too Many Requests"));
|
||||
}
|
||||
|
||||
# PURGE tylko lokalnie
|
||||
if (req.method == "PURGE") {
|
||||
if (!client.ip ~ purge) { return (synth(405, "Not allowed")); }
|
||||
return (purge);
|
||||
}
|
||||
|
||||
# omijamy cache dla healthchecków / wewnętrznych nagłówków
|
||||
if (req.url == "/healthcheck" || req.http.X-Internal-Check) { return (pass); }
|
||||
|
||||
# Specjalna obsługa WebSocket i socket.io
|
||||
if (req.http.Upgrade ~ "(?i)websocket" || req.url ~ "^/socket.io/") {
|
||||
return (pipe);
|
||||
}
|
||||
|
||||
# metody inne niż GET/HEAD bez cache
|
||||
if (req.method != "GET" && req.method != "HEAD") { return (pass); }
|
||||
|
||||
# statyczne – agresywny cache
|
||||
if (req.url ~ "^/static/" || req.url ~ "\.(css|js|png|jpg|svg|ico|woff2?)$") {
|
||||
return (hash);
|
||||
}
|
||||
|
||||
return (hash);
|
||||
}
|
||||
|
||||
sub vcl_pipe {
|
||||
if (req.http.Upgrade) {
|
||||
set bereq.http.Upgrade = req.http.Upgrade;
|
||||
set bereq.http.Connection = req.http.Connection;
|
||||
}
|
||||
}
|
||||
|
||||
sub vcl_backend_response {
|
||||
if (beresp.http.Cache-Control ~ "(?i)no-store|private") {
|
||||
set beresp.uncacheable = true;
|
||||
set beresp.ttl = 0s;
|
||||
return (deliver);
|
||||
}
|
||||
|
||||
if (beresp.http.Cache-Control ~ "(?i)s-maxage=([0-9]+)") {
|
||||
set beresp.ttl = std.duration(regsub(beresp.http.Cache-Control, "(?i).*s-maxage=([0-9]+).*", "\1") + "s", 0s);
|
||||
} else if (beresp.http.Cache-Control ~ "(?i)max-age=([0-9]+)") {
|
||||
set beresp.ttl = std.duration(regsub(beresp.http.Cache-Control, "(?i).*max-age=([0-9]+).*", "\1") + "s", 0s);
|
||||
} else if (beresp.http.Expires) {
|
||||
set beresp.ttl = std.time(beresp.http.Expires, now) - now;
|
||||
if (beresp.ttl < 0s) { set beresp.ttl = 0s; }
|
||||
} else {
|
||||
set beresp.ttl = 60s;
|
||||
}
|
||||
|
||||
if (beresp.http.Cache-Control ~ "(?i)immutable") {
|
||||
set beresp.grace = 1h;
|
||||
set beresp.keep = 24h;
|
||||
}
|
||||
|
||||
if ((bereq.url ~ "^/static/" || bereq.url ~ "\.(css|js|png|jpg|svg|ico|woff2?)$")
|
||||
&& !(beresp.http.Cache-Control ~ "(?i)(s-maxage|max-age)")) {
|
||||
set beresp.ttl = 24h;
|
||||
}
|
||||
}
|
||||
|
||||
sub vcl_deliver {
|
||||
if (obj.hits > 0) {
|
||||
set resp.http.X-Cache = "HIT";
|
||||
}
|
||||
|
||||
unset resp.http.Via;
|
||||
unset resp.http.X-Varnish;
|
||||
unset resp.http.Server;
|
||||
}
|
@@ -1,6 +1,15 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# --- Wczytaj zmienne z .env ---
|
||||
if [[ -f .env ]]; then
|
||||
set -a
|
||||
source .env
|
||||
set +a
|
||||
fi
|
||||
|
||||
APP_PORT="${APP_PORT:-8080}"
|
||||
|
||||
PROFILE=$1
|
||||
|
||||
if [[ -z "$PROFILE" ]]; then
|
||||
@@ -18,6 +27,9 @@ fi
|
||||
echo "Pobieram najnowszy kod z repozytorium..."
|
||||
git pull
|
||||
|
||||
echo "Generowanie default.vcl z APP_PORT=$APP_PORT"
|
||||
envsubst < deploy/varnish/default.vcl.template > deploy/varnish/default.vcl
|
||||
|
||||
echo "Zapisuję hash commita do version.txt..."
|
||||
git rev-parse --short HEAD > version.txt
|
||||
|
||||
|
@@ -1,11 +1,13 @@
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
container_name: live-lista-zakupow
|
||||
ports:
|
||||
- "${APP_PORT:-8000}:8000"
|
||||
container_name: lista-zakupow-app
|
||||
#ports:
|
||||
# - "${APP_PORT:-8000}:8000"
|
||||
expose:
|
||||
- "${APP_PORT}"
|
||||
healthcheck:
|
||||
test: ["CMD", "python", "-c", "import urllib.request; import sys; req = urllib.request.Request('http://localhost:8000/healthcheck', headers={'X-Internal-Check': '${HEALTHCHECK_TOKEN}'}); sys.exit(0) if urllib.request.urlopen(req).read() == b'OK' else sys.exit(1)"]
|
||||
test: ["CMD", "python", "-c", "import urllib.request; import sys; req = urllib.request.Request('http://localhost:${APP_PORT}/healthcheck', headers={'X-Internal-Check': '${HEALTHCHECK_TOKEN}'}); sys.exit(0) if urllib.request.urlopen(req).read() == b'OK' else sys.exit(1)"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@@ -18,6 +20,27 @@ services:
|
||||
- ./instance:/app/instance
|
||||
restart: unless-stopped
|
||||
|
||||
varnish:
|
||||
image: varnish:latest
|
||||
container_name: lista-zakupow-varnish
|
||||
depends_on:
|
||||
app:
|
||||
condition: service_healthy
|
||||
ports:
|
||||
- "${APP_PORT:-8080}:80"
|
||||
volumes:
|
||||
- ./deploy/varnish/default.vcl:/etc/varnish/default.vcl:ro
|
||||
environment:
|
||||
- VARNISH_SIZE=256m
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "curl -fsS -H 'X-Internal-Check=${HEALTHCHECK_TOKEN}' http://localhost/healthcheck | grep -q OK" ]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
env_file:
|
||||
- .env
|
||||
restart: unless-stopped
|
||||
|
||||
pgsql:
|
||||
image: postgres:17
|
||||
container_name: pgsql-db
|
||||
|
Reference in New Issue
Block a user