diff --git a/backend/Dockerfile b/backend/Dockerfile index 2262bce..d399f65 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -21,4 +21,4 @@ USER django EXPOSE 8000 ENTRYPOINT ["./entrypoint.sh"] -CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "2", "--access-logfile", "-"] +CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "2", "--log-level", "warning"] diff --git a/backend/entrypoint.sh b/backend/entrypoint.sh index 55ba000..61923eb 100644 --- a/backend/entrypoint.sh +++ b/backend/entrypoint.sh @@ -2,7 +2,7 @@ set -eu attempt=1 -until python manage.py migrate --noinput; do +until python manage.py migrate --noinput --verbosity 0; do if [ "$attempt" -ge 10 ]; then echo "Database migrations failed after $attempt attempts." >&2 exit 1 @@ -11,5 +11,5 @@ until python manage.py migrate --noinput; do sleep 2 done -python manage.py collectstatic --noinput +python manage.py collectstatic --noinput --verbosity 0 exec "$@" diff --git a/docker-compose.yml b/docker-compose.yml index be038ab..f93d8aa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -67,7 +67,7 @@ services: "CMD", "node", "-e", - "fetch('http://localhost:4321/').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))", + "fetch('http://localhost:4321/favicon.svg').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))", ] interval: 10s timeout: 5s diff --git a/docs/operations.md b/docs/operations.md index d6ff2a0..a703799 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -13,6 +13,11 @@ Compose health checks all services. Through the virtual host, the public health is `http://azionelab.org:8080/health/`; the aggregate content endpoint is `http://azionelab.org:8080/api/site/home/`. +Frontend and backend container logs suppress successful request and informational +entries by default, while warnings and errors remain visible. NGINX retains its access +log for request-level diagnostics. The frontend health check requests a static asset so +it does not render the home page or query the CMS. + Test routing without changing the hosts file: ```bash diff --git a/docs/security.md b/docs/security.md index 1e7e511..912c5a3 100644 --- a/docs/security.md +++ b/docs/security.md @@ -17,6 +17,9 @@ retain, and delete them according to the operator's privacy policy. - Avoid placing personal phone numbers or private contact details in logs. The API legitimately exposes only contact details approved for publication. +- Frontend and backend informational/access logs are suppressed by default, reducing + routine client metadata in application logs without hiding warnings or errors. NGINX + remains the request-level access log and must receive the same retention controls. - Dependency and image versions are explicit. Operators remain responsible for patch upgrades, vulnerability scans, and production digest pinning. - NGINX forwards the original host and standard client/protocol headers. Django trusts diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 0d04e05..aab82b5 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,5 +1,8 @@ FROM node:22.20-alpine +ENV ASTRO_TELEMETRY_DISABLED=1 \ + ASTRO_DISABLE_UPDATE_CHECK=true + WORKDIR /app RUN chown node:node /app @@ -12,4 +15,4 @@ COPY --chown=node:node . . EXPOSE 4321 -CMD ["npm", "run", "dev"] +CMD ["./node_modules/.bin/astro", "dev"] diff --git a/frontend/astro.config.mjs b/frontend/astro.config.mjs index 4b18864..ea4bda8 100644 --- a/frontend/astro.config.mjs +++ b/frontend/astro.config.mjs @@ -1,14 +1,26 @@ import { defineConfig } from "astro/config"; -export default defineConfig({ +export default defineConfig(({ command }) => ({ output: "static", + experimental: + command === "dev" + ? { + logger: { + entrypoint: "astro/logger/node", + config: { + level: "warn", + }, + }, + } + : undefined, server: { host: true, port: 4321, }, vite: { + logLevel: command === "dev" ? "warn" : undefined, server: { allowedHosts: ["azionelab.org"], }, }, -}); +}));