From 008f2f15ca4328f7a54288bff1670b17788c655d Mon Sep 17 00:00:00 2001 From: Alexander Popov Date: Wed, 11 Nov 2026 11:24:02 +0300 Subject: [PATCH] add ram --- README.txt | 24 ++++++++ default.ram.conf | 128 +++++++++++++++++++++++++++++++++++++++++ docker-compose.ram.yml | 25 ++++++++ olapka-ram-start.sh | 11 ++++ 4 files changed, 188 insertions(+) create mode 100644 README.txt create mode 100644 default.ram.conf create mode 100644 docker-compose.ram.yml create mode 100644 olapka-ram-start.sh diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..874ef40 --- /dev/null +++ b/README.txt @@ -0,0 +1,24 @@ +О’ляпка · Nginx с сайтом в оперативной памяти +Распакуйте три файла рядом с существующей папкой html и docker-compose.yml версии v3. Папку html оставьте на диске: это источник для перезапуска. Существующая внешняя сеть pangolin_frontend и имя контейнера olapka-ru сохранены. + +Проверка без запуска: +docker compose -f docker-compose.ram.yml config -q + +Включение (в каталоге действующего проекта): +docker compose -f docker-compose.ram.yml up -d --force-recreate nginx +Команда пересоздаёт сервис; во время копирования возможен краткий перерыв. Используйте то же имя проекта Compose, что и сейчас (в исходном файле — olapka; если вы задавали -p, повторите его). + +Контроль внутри контейнера: +docker compose -f docker-compose.ram.yml exec nginx df -h /srv/olapka-ram +docker compose -f docker-compose.ram.yml exec nginx nginx -t +Для видео запрос Range: bytes=0-1023 должен вернуть 206 Partial Content. + +Обновление контента: полностью обновите html на диске, затем выполните +docker compose -f docker-compose.ram.yml restart nginx +Обычный nginx reload не копирует файлы заново. При изменении лимитов или томов используйте up -d --force-recreate nginx. + +Откат к исходному конфигу: +docker compose -f docker-compose.yml up -d --force-recreate nginx + +Что находится в RAM: полный снимок html (страницы, скрипты, картинки, видео и служебные файлы). Сервер начинает принимать запросы только после успешного копирования и nginx -t. Правила браузерного кеширования, перенаправления, HTTPS через Pangolin и отложенная загрузка видео сохранены. Журналы Docker, исходники и сама ОС не переносятся в RAM. +Размер текущей статики около 265 МиБ. Предел tmpfs — 384 МиБ, лимит всего контейнера — 640 МиБ; равный memswap_limit запрещает контейнеру swap при поддержке Linux cgroups. Лимиты не резервируют физическую память. На сервере нужен достаточный запас оперативной памяти. Если html перерастёт 384 МиБ, увеличьте size, а при необходимости и оба равных лимита; при ошибке копирования сервис не запустится. diff --git a/default.ram.conf b/default.ram.conf new file mode 100644 index 0000000..ab0b0a5 --- /dev/null +++ b/default.ram.conf @@ -0,0 +1,128 @@ +# Loaded by the standard nginx image inside the http context. +# TLS is terminated by the existing external reverse proxy (Pangolin). +map $uri $olapka_canonical_path { + # Re-evaluate after internal error_page redirects. + volatile; + default $uri; + ~^/new-year(?:\.html)?/?$ /; + ~^/index(?:\.html)?/?$ /; + ~^/(business-animation|contacts|legal|personal-animation|portfolio|services|social-animation)(?:\.html/?|/)$ /$1; +} + +server { + listen 80; + server_name www.olapka.ru; + return 301 https://olapka.ru$olapka_canonical_path$is_args$args; +} + +server { + listen 80; + server_name olapka.ru; + root /srv/olapka-ram; + sendfile on; + charset utf-8; + charset_types text/plain text/css text/markdown application/javascript application/json application/xml image/svg+xml; + + gzip on; + gzip_vary on; + gzip_proxied any; + gzip_min_length 512; + gzip_comp_level 5; + gzip_types text/plain text/css text/markdown application/javascript application/json application/xml text/xml image/svg+xml; + + # /404 is an error too, never a successful content page. + location = /404 { + return 404; + } + + error_page 404 =404 /404.html; + + location = /404.html { + internal; + } + + # Only return redirects here; no rewrite loops or HTTPS checks behind proxy. + if ($uri != $olapka_canonical_path) { + return 301 https://olapka.ru$olapka_canonical_path$is_args$args; + } + + # try_files serves an existing file in-place, without a client redirect. + location = / { + try_files /index.html =404; + } + + location = /business-animation { + try_files /business-animation.html =404; + } + + location = /contacts { + try_files /contacts.html =404; + } + + location = /legal { + try_files /legal.html =404; + } + + location = /personal-animation { + try_files /personal-animation.html =404; + } + + location = /portfolio { + try_files /portfolio.html =404; + } + + location = /new-year.md { + return 301 /index.md$is_args$args; + } + + location = /new-year { + return 301 /$is_args$args; + } + + location = /services { + try_files /services.html =404; + } + + location = /social-animation { + try_files /social-animation.html =404; + } + + # Machine-readable site summaries (UTF-8 Markdown in .txt files). + location ~ ^/llms(?:-full)?\.txt$ { + types { } + default_type text/plain; + charset utf-8; + add_header Cache-Control "public, max-age=3600"; + try_files $uri =404; + } + + # Keep the source legal page's noindex policy on its Markdown copy. + location = /legal.md { + types { } + default_type text/markdown; + charset utf-8; + add_header X-Robots-Tag "noindex, follow"; + add_header Link '; rel="describedby"'; + try_files $uri =404; + } + + location ~ ^/(index|services|personal-animation|business-animation|social-animation|portfolio|contacts)\.md$ { + types { } + default_type text/markdown; + charset utf-8; + add_header Cache-Control "public, max-age=3600"; + add_header Link '; rel="describedby"'; + try_files $uri =404; + } + + # Revalidate changed assets after one hour (filenames are not versioned). + location ~ ^/(?:css|js|img|video)/ { + add_header Cache-Control "public, max-age=3600"; + try_files $uri =404; + } + + # Real assets are served normally. Unknown URLs return a real 404. + location / { + try_files $uri =404; + } +} diff --git a/docker-compose.ram.yml b/docker-compose.ram.yml new file mode 100644 index 0000000..918226a --- /dev/null +++ b/docker-compose.ram.yml @@ -0,0 +1,25 @@ +name: olapka +services: + nginx: + container_name: olapka-ru + image: nginx:stable-alpine + restart: unless-stopped + mem_limit: 640m + memswap_limit: 640m + tmpfs: + - /srv/olapka-ram:rw,noexec,nosuid,nodev,size=384m,mode=0755 + entrypoint: ["/bin/sh", "/opt/olapka-ram-start.sh"] + command: ["nginx", "-g", "daemon off;"] + volumes: + - ./olapka-ram-start.sh:/opt/olapka-ram-start.sh:ro + - ./html:/srv/olapka-source:ro + - ./default.ram.conf:/etc/nginx/conf.d/default.conf:ro + networks: + frontend: + aliases: + - olapka-ru + +networks: + frontend: + external: true + name: pangolin_frontend diff --git a/olapka-ram-start.sh b/olapka-ram-start.sh new file mode 100644 index 0000000..4db4d7b --- /dev/null +++ b/olapka-ram-start.sh @@ -0,0 +1,11 @@ +#!/bin/sh +set -eu +src=/srv/olapka-source +dst=/srv/olapka-ram +awk -v p="$dst" '$2==p && $3=="tmpfs" {found=1} END {exit !found}' /proc/mounts || { echo "Missing tmpfs: $dst" >&2; exit 1; } +test -s "$src/index.html" || { echo "Missing source index.html" >&2; exit 1; } +test -z "$(find "$src" -type l -print -quit)" || { echo "Use regular site files instead of symbolic links." >&2; exit 1; } +cp -a "$src/." "$dst/" +chmod 0755 "$dst" +nginx -t +exec /docker-entrypoint.sh "$@"