Как мы обсуждали в прошлый раз, удручающее ожирение сайтов и софта вернуло моду на простые, маленькие проекты. И сейчас происходит своеобразный ренессанс веба 90-х, вплоть до стиля Geocities (такой был бесплатный хостинг) и веб-страниц в виде PDF. Таковы примеры самореализации. У каждого человека — уникальный сайт, который отличается от остальных и отражает его личность.
Статический сайт можно выполнить в одном файле HTML, а динамический — в одном бинарнике (под катом). Тенденция видна везде. Современные фреймворки даже хвалятся «0кБ JavaScript» по дефолту, а браузеры внедрили технические усовершенствования, которые во многом аннулируют преимущества использования SPA.
Сайт в одном бинарнике
Сайт в исполняемом файле — ещё более интересная идея, чем в одном HTML, о котором мы рассказывали в прошлый раз. Если в двух словах, на сервере постоянно запущена программа на Go, которая отслеживает входящие запросы и выдаёт эмбеды изнутри себя.
В каком-то смысле это полная противоположность сайту в одном файле HTML, потому что в данном случае у нас формально не статичные странички, а динамически генерируемый контент. Более того, это полноценная система CI/CD, если так можно сказать, потому что программа постоянно обновляется из репозитория, куда удобно коммитить.
Скрипт для деплоя на сервере:
#!/bin/sh -eu
#
# deploy my website
cd /home/j3s/code/j3s.sh
git fetch origin
if git status | grep -q behind; then
git merge origin/main
go build
mv j3s.sh /usr/local/bin/j3s.sh
service j3s.sh restart
fi
Скрипт на сервере каждую минуту проверяет изменения в репозитории. В этом смысле деплой автоматический. Автор тестирует код локально, а коммиты отражаются на сайте в течение минуты. Минимум зависимостей.
Такую систему внедрил американский разработчик Джес Олсон (Jes Olson) для своего личного сайта-бинарника j3s.sh. Он руководствовался несколькими принципами, которые можно назвать универсальными.
- Простой, понятный код.
- Быстрая разработка (логично вытекает из первого пункта), простая итерабельность.
- Надёжность и долговечность.
- Минимальные усилия в поддержке. При этом максимальная простота в устранении неполадок. Один человек способен тривиально поддерживать все системы без чужой помощи. В идеале вещи должны быть настолько простыми и надёжными, что будут ломаться крайне редко. Если какая-то неприятность всё же случилась, способ исправления проблемы должен быть очевидным.
Автор начал по классике: попробовал генераторы статических сайтов типа Hugo, а также Ghost, Jekyll, SourceHut + tarball и редактирование html вручную, но ни один вариант его не удовлетворил. Даже самая очевидная связка из генератора Hugo и хостинга на Github Pages ему не понравилась из-за множества зависимостей от конкретных программ, компаний, проектов и экосистем.
Он написал странички на старом добром HTML — и захостил на машине, которая находится под его контролем (кстати, Джес работает в известной компании, которая занимается хостингом). Казалось бы, в любой момент можно открыть vim и отредактировать любую страничку, что мгновенно отразится на сайте.
В этот момент пришла идея: если сайт написан на одном языке, то его может генерировать один бинарник. В данном случае на Go, хотя такой же бинарник можно написать на Rust, на C или любом другом языке. Суть одна и та же: это динамически обновляемый генератор статических страничек.
В этом есть свои преимущества. Например, чтобы посмотреть IP-адрес посетителя, достаточно написать функцию в четыре строчки:
func ipHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
fmt.Fprintf(w, r.Header.Get("X-Forwarded-For")+"\n")
}
В случае необходимости можно вызвать эту функцию в любой момент:
http.HandleFunc("/ip", ipHandler)
То есть автор отказался от генератора Hugo, а вместо него написал свою программу Go, которая постоянно работает на сервере, принимает соединения — и выдаёт клиентам контент в нужном формате по их запросам. Все статические файлы переносятся внутрь бинарника, например, с помощью пакета go-bindata или stdlib embed.
Вы можете запустить программу на любом сервере — и вот ваш «сайт» автоматически переехал на новый хостинг. Если пофантазировать, то каждый пользователь может запускать «сайт» на своём компьютере, генерировать и просматривать контент локально, каждый сам у себя (как делает Redbean).
Генератор статических HTML и CSS типа Hugo | Свой бинарник | |
---|---|---|
Зависимости | Обновления Hugo, плагины, Docker (если зафиксировать текущую версию Hugo в контейнере) | Linux, стандартная библиотека Go |
Долговечность стека текущих зависимостей (прогноз) | 10 лет | 20–30 лет |
Конечно, с личными сайтами можно экспериментировать как душе угодно. Кажется, они снова входят в моду, параллельно с возрождением RSS.
Вообще, в начале 2000-х у нас даже проходили национальные конкурсы личных сайтов. А в наши дни даже авторы с тысячами читателей предпочитают публиковаться на чужих платформах, чтобы не потерять читателей. Мало у кого есть личный домен, кроме Экслера и ещё парочки титанов.
Минимализм становится стандартом
Выше был упомянут SourceHut — это набор опенсорсных инструментов для веб-разработки, без использования JavaScript, без трекинга и прочих излишеств. Только самые быстрые и лёгкие инструменты. Набор создан в мае 2022 года специально по запросам общественности (сейчас в публичной альфе).
Современные фреймворки типа Astro, Qwik и Elder.js тоже по умолчанию начали предлагать опцию «0кБ JavaScript». Таким образом, баланс постепенно смещается от тяжеловесных SPA в сторону радикально оптимизированных MPA без JS, с бюджетом 30–50 кБ.
В идеале новый сайт пишут с нуля. Но в реальной жизни приходится иногда разбирать и старые завалы, в том числе решать задачи по оптимизации. Если требуется оптимизировать раздутый сайт, оттуда можно вырезать только полезный контент — текст и графику, и выкинуть всё остальное. Или обойтись мелкими оптимизациями, которые дают быстрый и заметный эффект.
Что касается изображений, мы получаем чистый выигрыш места за счёт простой конвертации старых JPEG и PNG в более современный формат, такой как WebP, AVIF или JPEG XL. Из этих трёх форматов только WebP поддерживается во всех браузерах (кроме IE 11). Его можно использовать смело, в то время как AVIF пока не реализовали в Safari, а самый продвинутый JPEG XL вообще нигде не поддерживается. То есть JPEG XL — это пока формат не для веба, а для личного фотоархива.
Простое преобразование из PNG в WebP одной командой
convert
в ImageMagick иногда даёт результат, особенно если фотографии занимают основную часть места на хостинге, как часто бывает в статических сайтах.По степени сжатия WebP с потерями выигрывает у обычного JPEG примерно 10%:
Cжатие без потерь в WebP тоже вне конкуренции (там используется отдельный кодек):
Апгрейд браузеров убивает SPA
В последние годы в браузерах реализован ряд технических усовершенствований, которые аннулируют главные преимущества использования одностраничных приложений (SPA) вместо нормальных многостраничных сайтов (MPA):
- Chrome реализовал удержание заливки (paint holding) — больше нет «белой вспышки» при переходе между страницами (Safari сделал это в 2019 г).
- Chrome внедрил кэширование «назад-вперёд» (back-forward caching) — теперь эта оптимизация реализована во всех основных браузерах, так что навигация вперёд-назад между страницами MPA стала практически мгновенной.
- Service Workers — когда-то экспериментальная функция теперь стала практически на 100% доступной во всех браузерах. Она позволяет внедрить автономную навигацию по страницам без маршрутизации на стороне клиента (и связанных с этим сложностей).
- Если Shared Element Transitions будут приняты и реализованы в браузерах, появится возможность анимировать переходы между страницами MPA, что ранее было возможно (хотя и сложно) только в SPA.
Если вас это не убедило отказаться от толстых одностраничных приложений, оцените такой аргумент от «защитников SPA».
Возможно, в будущем SPA останутся только в специфических нишах, где без них действительно не обойтись. Например, если хотите сохранить на экране определённый объект (окно плеера или виджет чата) во время навигации по сайту. Это модная концепция transitional apps.
Похоже, что SPA повторяют судьбу библиотеки jQuery. Она предоставляла уникальные и удобные API, которые не поддерживались в браузерах. Но когда браузеры реализовали стандартно querySelector, fetch и другие вызовы, необходимость использования jQuery стала уже не такой очевидной.
Крошечный образ Docker для раздачи статики
Если рассуждать логически, то для обслуживания статического сайта не требуется особая вычислительная мощность. Нужно всего лишь изредка отдавать маленькие файлы в ответ на входящие запросы. Кажется излишеством использовать для этого Docker с тяжеловесным движком типа nginx.
Однако, фанаты-докеры с этим не согласны. Один из них поставил задачу сделать образ минимального размера для раздачи статики. Он протестировал подходящие файл-серверы и остановился на минимальном thttpd:
thttpd -D -h 0.0.0.0 -p 3000 -d /static-website -u static-user -l - -M 60
Затем нашёл маленький дистрибутив Alpine, в состав которого уже входит
thttpd
. Получился докер-образ 7,77 МБ.Затем использовал докеровский инструмент scratch для минификации образа. Эта программа оставляет внутри только ядро и скрипт для загрузки всего необходимого, после запуска скачивает и устанавливает Alpine (130 МБ), берёт снаружи файлы веб-сайта — и начинает работать:
FROM alpine:3.13.2 AS builder
ARG THTTPD_VERSION=2.29
# Install all dependencies required for compiling thttpd
RUN apk add gcc musl-dev make
# Download thttpd sources
RUN wget http://www.acme.com/software/thttpd/thttpd-${THTTPD_VERSION}.tar.gz \
&& tar xzf thttpd-${THTTPD_VERSION}.tar.gz \
&& mv /thttpd-${THTTPD_VERSION} /thttpd
# Compile thttpd to a static binary which we can copy around
RUN cd /thttpd \
&& ./configure \
&& make CCOPT='-O2 -s -static' thttpd
# Create a non-root user to own the files and run our server
RUN adduser -D static
# Switch to the scratch image
FROM scratch
EXPOSE 3000
# Copy over the user
COPY --from=builder /etc/passwd /etc/passwd
# Copy the thttpd static binary
COPY --from=builder /thttpd/thttpd /
# Use our non-root user
USER static
WORKDIR /home/static
# Copy the static website
# Use the .dockerignore file to control what ends up inside the image!
COPY . .
# Run thttpd
CMD ["/thttpd", "-D", "-h", "0.0.0.0", "-p", "3000", "-d", "/home/static", "-u", "static", "-l", "-", "-M", "60"]
В итоге сам образ занимает минимальный размер:
> docker images | grep static
static latest ab0699ed2690 About a minute ago 186kB
Всего 186 КБ. Плюс файлы веб-сайта, вот и всё, что нужно носить с собой.
Код лежит на docker-static-website.
Веб-сервер с нашими файлами внутри бинарника
Не менее элегантный трюк — взять веб-сервер Redbean и внедрить внутрь бинарника свои статические файлы. В результате получится файл
.com
, который нативно запускается под следующими системами: Linux, Mac, Windows, FreeBSD, OpenBSD, NetBSD и BIOS. То есть этот веб-сервер работает на любом компьютере и выдаёт ваш контент в офлайне. Автор программы Redbean и кросс-платформенного формата αcτµαlly pδrταblε εxεcµταblε — известная хакерша Джастин Танни.Минимализм и сжигание лишних слоёв абстракции — похвальная тенденция не только во фронтенде, но вообще в любом софте. Например, в десктопных ОС ожирение вообще приобрело хроническую форму. Разработчики добавляют новые функции, а не убирают лишние. Почти никто не ставит главной целью разработки увеличение производительности за счёт удаления кода.
Для серверов тоже иногда приходится искать облегчённые версии инструментов. Например, TinySSH — отличный SSH-сервер без лишних функций.
Как вариант, для древнего железа можно использовать старые версии программ. Например, веб-сервер mTCP (HTTPServ) для старых IBM PC раздаёт сайт serentty.com (копия) с сервера 386 SX 25 МГц и 4 МБ оперативки по каналу 38400 бод:
HTTP/1.1 200 OK Server: mTCP HTTPServ Mar 7 2020 Date: Sun, 17 Apr 2022 00:30:00 GMT Content-Type: text/html Content-Length: 5355 Expires: Fri, 14 Oct 2022 00:30:00 GMT Last-Modified: Sun, 17 Apr 2022 00:02:00 GMT Connection: keep-alive
Хотя сегодня опять упадёт, наверное…
Основная польза таких экспериментов — они поощряют креативность и возвращают любовь к разработке, немножко приближая его к искусству. Мы вспоминаем о главном: ведь мы не просто точим одинаковые гайки на станке, чтобы купить еду и оплатить ипотеку, а создаём творческие работы для самореализации.
НЛО прилетело и оставило здесь промокод для читателей нашего блога:
— 15% на все тарифы VDS (кроме тарифа Прогрев) — HABRFIRSTVDS.
Комментарии (67)
dimuska139
13.06.2022 11:47-1аннулируют главные преимущества использования одностраничных приложений (SPA) вместо нормальных многостраничных сайтов (MPA):
Т.е., по-вашему, SPA - это не нормально?
vedenin1980
13.06.2022 12:01+24SPA это нормально для своей области (огромные медийные или корпоративные порталы), для обычных сайтов обычных компаний это скорее попытка забивать гвозди микроскопом.
maximw
13.06.2022 13:06+24Если нормальность определять количеством, то да, SPA это не нормально. SPA нишевая штука. Если нет какого-то сложного интерфейса пользователя на странице, то многостраничные сайты удобнее.
DistortNeo
13.06.2022 16:11+29Да, с моей точки зрения, SPA — это ненормально, потому что ломают привычный инструментарий работы с сайтом, а именно возможность для пользователя открыть столько окон, сколько ему нужно. Например, Gmail: как я могу открыть несколько писем, каждое в своём окне? А никак, SPA этого не позволяет. Можно только создать несколько инстансов этого SPA. Или Google Maps: как я могу открыть информацию о нескольких объектах одновременно, чтобы сравнить их?
В итоге пользователь начинает работать с SPA так, как если бы это был MPA, но при этом страдает от тяжеловесности SPA.
daggert
14.06.2022 01:12+3А никак, SPA этого не позволяет.
SPA это позволяет. Точней не запрещает никак. Вопрос в реализации. У меня весьма сложная интерпрайз система в виде SPA-приложения и роутинг обрабатывает такие моменты, схожие с открытием нового письма в новой вкладке/окне или нажатие средней кнопкой мышки на вкладки. Открывается просто новое окно и в нем можно работать полноценно. При этом не загружается все приложение целиком (около 11% кода). Вопрос конечно в синхронизации между вкладками встает остро, но т.к. это локалка - можно спамить кучей xhr.
Конечно открыть в новой вкладке кнопку "сохранить" не выйдет, однако открыть пару окон и вкладок с разными "рабочими пространствами"- можно.
Но за это конечно платишь оооочень дорого, и я тут даже не про деньги. Время разработки растет в десятки раз.
DevAdv
14.06.2022 06:13+1Например, Gmail: как я могу открыть несколько писем, каждое в своём окне? А никак, SPA этого не позволяет.
Хм,
позволяет
Ну или просто
Command + Click
, думаюAlt
в другой системе тоже сработает.DistortNeo
14.06.2022 10:01+5Спасибо, не знал. Я привык открывать ссылки в новых окнах через Middle Click, а этот функционал не работает в Gmail. Через меню открывает в новом окне, а не вкладке. К слову, папки (там, где входящие, отправленные) по среднему клику открываются в новом окне, а через Ctrl — наоборот, нет.
khajiit
14.06.2022 13:00Папки это ссылки, а письма это переход в другую часть SPA. Если включена строка состояния, то видны таргеты при наведении на папки.
maximw
14.06.2022 14:52+1Возможность переопределять стандартное контекстное меню браузера вообще зло само по себе.
ZoomLS
14.06.2022 13:33+4В Gmail можно использовать html версию, тогда никаких проблем с этим. Постоянно её использую, очень удобно, грузится шустро, можно открывать кучу вкладок и ничего не будет тормозить, сжирать память гигабайтами и т.д.
vedenin1980
13.06.2022 11:56+21Сайт в исполняемом файле
Очень старая идея, наверное ей уже лет 30, я помню как такие сайты писали на Perl, потом на C++, потом Java сервлеты и Java аплеты. Там свои проблемы, получается мешанина html и обычного кода и со временем это становится болью.iShrimp
13.06.2022 21:07+5Примечательно, что всё те же этапы развития повторяет сфера IoT. Прошивка - это такой же бинарник с интегрированными кусками HTML-кода в виде констант.
iig
13.06.2022 23:04+5Если железо позволяет - внутри появляется файловая система с html файлами.
randomsimplenumber
14.06.2022 11:07+2Никто не мешает при сборке приложения преобразовать исходники в формате html в любую структуру данных, хоть образ squahsfs, хоть дерево/словарь/массив строк. Вся файловая система, с кластерами/правами/контрольными суммами/кешированием - не всегда нужна.
garbagecollected
13.06.2022 23:19+4И нигде на странице статьи нет упоминания названия этой технологии CGI.
Сразу вспоминается Навальный. Как можно было написать статью про CGI и ни разу не употребить её названия?
F0iL
13.06.2022 23:33+5Потому что в статье речь не про CGI. CGI - это когда у нас есть веб-сервер, который на каждый запрос дёргает какой-то бинарник/интерпретатор чтобы сгенерить страницу. А здесь же идёт речь про случай, когда код, генерирующий страницы, вкомпилен непосредственно в бинарник самого веб-сервера, то есть составляет с ним единое целое (см. про вышеупомянутый RomPager, например).
squonk
15.06.2022 18:54Ну да. В той же Java/Kotlin можно и Spring Boot и Quarkus и Ktor на выходе будет один файл.
Tzimie
13.06.2022 12:01+1У меня статический сайт на Nicepage, там css файл 1 Мег. Я пытался чистить но все время что-то ломается. Как бы это сделать автоматически? Мне их этого css нужно процентов 5...
Alexufo
13.06.2022 12:30+15Скачай расширение для лисы css usage или что то подобное. Походи по сайту и оно накопит только используемые свойства.
Ivnika
13.06.2022 12:46+18Когда-то сохранил себе в копилку идей понравившийся сайт https://oknaludyam.ru :)
MagisterAlexandr
13.06.2022 20:07+2https://web.archive.org/web/20180506234654/http://oknaludyam.ru/ хорош, а теперь дизайн слегка подпортили в угоду повышению конверсии или как оно там называется.
Mingun
13.06.2022 14:27+15Chrome внедрил кэширование «назад-вперёд» (back-forward caching) — теперь эта оптимизация реализована во всех основных браузерах, так что навигация вперёд-назад между страницами MPA стала практически мгновенной.
То есть, в хроме наконец реализовали то, что ещё 10 лет назад умела Opera 12?
F0iL
13.06.2022 23:41+4Opera, насколько я помню, кэшировала только сами элементы страницы и содержимое форм. В наше время так действовать не получится - сегодня сайты (особенно вышеупомянутые SPA) обскриптованы по самое не хочу, и если просто закэшировать состояние DOM-дерева, многие сайты после загрузки из кэша сломаются нафиг - нужно сохранять полностью ещё и состояние скриптов, выполняемых на странице. Opera такое не умела, а вот в новом Хроме, по заверениям разработчиков, оно действительно работает.
VEG
14.06.2022 00:15+1Не любитель старой Оперы, но только что проверил — похоже, что состояние скриптов сохраняется.
F0iL
14.06.2022 00:30А как конкретно проверили? Оно действительно восстанавливает js heap целиком, все таймеры, не успевшие сработать коллбэки, и все остальное из tasks queue?
Когда в свое время, засидевшись, слезал с "классической" Оперы, помню, что уже тогда некоторые сайты начали ломаться при загрузке из кэша...
VEG
14.06.2022 07:51+2Ну как минимум таймеры и значения переменных восстанавливаются, проверил на radar.veg.by. Без восстановления состояния там бы таймер с обратным отсчётом сбрасывался бы до ближайших 30 секунд, как при перезагрузке страницы. Что-то более тяжёлое из современного вы там вряд ли заведёте уже. Возможно, в каких-то случаях оно работало плохо или с ошибками, я не знаю. Оперой как основным браузером никогда не пользовался, только тестировал в ней свои сайты. Иногда сталкивался с неприятными багами в неожиданных местах при этом. Возможно, вы тоже сталкивались с какими-то ошибками в реализации.
Mingun
14.06.2022 18:07+1Не знаю, что и как конкретно она сохраняла, но при использовании кнопки «Назад» ни один сайт никогда не ломался (а пользовался я ей довольно часто, да и сайты были типа google.ru — то есть, объём скриптов там уже тогда был приличный).
baldr
13.06.2022 14:31+31Интересно для хобби-проекта, но я лично бы не стал доверять таким решениям.
Если хочется раздавать только статику с одного публичного сервера - то nginx "и никаких гвоздей"!
Бинарник слушающий сокет? А забыли ли мы атаки с переполнением буфера, инжекцией параметров или просто какой-нибудь printf()?
Как только создаешь публичный сервер с открытыми портами - в течение нескольких часов набегает толпа китайских ботов-сканеров и шлют всякую ересь в надежде использовать какой-то эксплоит.
nginx надежен и протестирован миллионами. Не пускает куда не надо, умеет TLS, пишет логи и прекрасно справляется с тысячами HR, внезапно захотевших открыть вашу страничку с резюме в одно и то же время.
0xd34df00d
13.06.2022 20:25А забыли ли мы атаки с переполнением буфера, инжекцией параметров или просто какой-нибудь printf()?
Если использовать нормальные безопасные языки, то этого не будет.
DirectoriX
13.06.2022 20:49+8«Безопасность» языка помогает защититься только от определённого класса проблем, но против банальных недосмотров они бессильны. Пример — если в веб-сервере не проверять выход выше корневой папки, то любой Петя прочитает с диска всё, до чего дотянутся его ../../
Ну или можно добавить интересные функции, из-за которых вообще бахнет так, что мало не покажется, привет Log4j.0xd34df00d
13.06.2022 20:59-1Пример — если в веб-сервере не проверять выход выше корневой папки, то любой Петя прочитает с диска всё, до чего дотянутся его ../../
Вопрос в том, где вы это будете проверять. Если вы пишете код на C (или на go), то это надо проверять в каждой точке чтения файлов. Если вы пишете на более выразительных языках, то это достаточно проверить ровно в одном месте.
Ну или можно добавить интересные функции, из-за которых вообще бахнет так, что мало не покажется, привет Log4j.
Опять же, если язык достаточно выразительный, то нельзя.
Oxoron
13.06.2022 21:41+11Вопрос в том, где вы это будете проверять.
Я не хочу этого проверять. Вот вообще.
Не то, чтобы все эти проверки были чем-то плохим, просто я
относительнослабо разбираюсь в вопросах безопасности. Так что, если условный nginx закрывает over9000 "стандартных" сценариев, пусть и ценой докер-образа в 60 МБ -- я возьму nginx.cepera_ang
13.06.2022 22:14А если весь сайт — это бинарь, умеющий отдавать зашитые константы файлы (как предложено), то там и нет никаких ../../ откуда можно какие-то файлы читать, вообще ничего нет, кроме одинокого запущенного бинаря с одной фунцией
route(address) -> str
:)
0xd34df00d
13.06.2022 22:33+4А откуда вы знаете, что условный nginx это закрывает, и его конфиг не позволяет читать файлы откуда-то ещё? Я этого не знаю, например.
Oxoron
14.06.2022 08:30+5Вопрос резонный. Принципы работы с безопасностью (для самых маленьких):
Полной защиты не дает ничто (смотрим в сторону ZeroDay уязвимости, социальной инженерии, бекдоры от спецслужб). Вывод: наша задача (как людей не особо знакомых с безопасностью) -- закрыть наиболее ходовые сценарии, с минимальными затратами.
В случае малого\среднего сайта безопасник - максимум один. А посылать всякую ересь в порты сервиса будет толпа китайских ботов-сканеров. Велика вероятность, что один из толпы заюзает таки эксплоит, с которым наш безопасник не знаком.
Вывод: кастомные платформы рискованней поддерживаемой платформы с богатой историей.
Как выбирать сервер/framework для интернет-магазина/платформу для блога/etc:
Спросить друга безопасника. Друг не только посоветует что-то, но еще и расскажет (а то и проверит) самые критичные дыры.
Если друга безопасника нет - гуглим самое популярное решение. Пентест закладываем исходя из бюджета (в 90% случаев - не закладываем).
Гуглим "10 popular vulnerabilities for your-platform-name", закрываем уязвимости из списка.
Ставим напоминалку на через год: "обновить nginx/magento/wordpress/etc, продлить напоминалку".
Расслабляемся.Идем настраивать бекапы.
Расслабляемся
0xd34df00d
14.06.2022 16:15+1Друзья, безопасники, закрываем 10 уязвимостей… Не, извините, мне проще в этом своём хаскеле типами проверить, что я нигде не вылезаю за
../../
.
Refridgerator
14.06.2022 06:39+4Пример — если в веб-сервере не проверять выход выше корневой папки, то любой Петя прочитает с диска всё, до чего дотянутся его ../../
Совсем не обязательно мапить веб-запрос напрямую в файловую систему, особенно при использовании своего собственного веб-сервера. Html можно генерировать на лету, а не загружать его каждый раз с диска — в этом и смысл.
Sadler
13.06.2022 16:17+2Так-то можно ещё меньше зависимостей оставить, без docker'а, Go и sh-скриптов. Просто модулем к nginx запросы обрабатывать, мне приходилось такое реализовывать. НО это максимально нишевое решение с миллионом способов отстрелить себе ногу, и непонятно, зачем могут понадобиться такие костыли основной массе разработчиков.
vanyas
13.06.2022 16:49+12Затем использовал докеровский инструмент scratch для минификации образа. Эта программа оставляет внутри только ядро и скрипт для загрузки всего необходимого, после запуска скачивает и устанавливает Alpine (130 МБ), берёт снаружи файлы веб-сайта — и начинает работать:
Ну неправда же, в докер образе нет ядра. Ну scratch это не какая-то отдельная программа, а способ сборки докер образа. Очень похоже на кривой перевод
eps
14.06.2022 11:41+2И сама идея: скачивать при каждом запуске по 130 МБ ради того, чтобы уменьшить образ на 7 МБ?
Как-то не очень. И плохо сходится с идеей статьи о «минимуме зависимостей» и «только то, что нужно»
DistortNeo
14.06.2022 13:13+2Эти 130 мегов нужны, чтобы скомпилировать веб-сервер из исходников со статической линковкой. Дальше вы на выходе получаете образ минимального размера, с которым можете делать что угодно.
vikarti
13.06.2022 18:35+6Долговечность стека текущих зависимостей 20–30 лет?
А как решается проблема с https? Отказаться от него — браузеры начнут говорить сайт небезопасный (уже начинают), поддерживать — так лет через десять появится TLS1.7 а в TLS1.3 найдут чтонибудь ну очень ужасное и браузеры начнут ругатся на него. Даже если не найдут — как сертификат то обновлять? Каждый раз на старте бинарника (у нас один бинарник же — только в память сохранять) дергать Let's Encrypt на предмет сертификата? а что если протокол общения с Let's Encrypt сменится? Или Let's Encrypt в конкретной стране забанят (или он забанит страну)?
Или вешать nginx перед сервером? А нафига?Если у нас сайт это набор статических страниц без js — уже чем хостить — то найдется.
Javian
13.06.2022 21:08У знакомого статичный сайт лежит на амазоне - недавно показывал в какие копейки хост обходится в год.
olku
13.06.2022 23:01Oracle две виртуалки дает бесплатно. IO не очень, но крутит и Симфони, и Спринг бут с небольшими базами.
spinagon
14.06.2022 10:33+2В России уже не даёт, а кому дал тех банит
cepera_ang
14.06.2022 18:12Обещали забанить, кстати, но тьфу-тьфу, виртуалка продолжает работать уже три месяца после того, как пришло письмо «мы вас отключили».
alexzeed
13.06.2022 23:11Небольшой статичный наверное можно на GtHub Pages совсем бесплатно положить.
А насчет сайта-бинарника — еще никто не вспомнил про архитектуру. Конечно, сейчас «дефолтная» amd64 почти везде, но я бы не закладывался на то, что это сохранится через 30 лет. Вполне может arm ее потеснить, он энергоэффективнее — значит arm хостинг постепенно станет дешевле.
Хотя сайт все равно как-то обновлять надо, скорее всего пересобирая из исходников при этом.
KizhiFox
14.06.2022 11:22У меня есть статичный сайт без JS, который я писал на Markdown с последующей конвертацией в HTML с помощью Python-Markdown.
Вообще, нужно было сделать справочник по своему миру для компании в Dungeons & Dragons. Какие-то существующие вики-решения по типу Fandom показались слишком сложными в управлении. Неплохим вариантом были Notion и Telegraph, но в первом было слишком много лишних функций и чужой брендинг, а во втором, наоборот, функций было слишком мало. К тому же руки чесались сделать что-то самому.
В итоге родился небольшой проект, работающий примерно так: я пишу Markdown с несколькими самописными модулями (навигация по страницам, относительные ссылки, шаблоны для статблоков), прогоняю его через конвертер и заливаю на Github Pages. Также на случай, если захочется хостить самому (на практиже же просто смотреть результат в процессе написания), есть простенький Bash скрипт для питоновского http.server, который ещё и обновления в MD исходниках смотрит и HTML страницы пересобирает.
На выходе получается что-то эдакое: https://kizhifox.github.io/dnd-shard-wiki/
P.s.: Спасибо за абзац про WebP, возможно ещё пикчи в него перегоню, а то об этом как-то сам забыл :)
nmrulin
14.06.2022 14:20В своё время вот пытались делать сайты на IntraWeb -там тоже всё делает бинарник. Не взлетело.
Color
14.06.2022 16:19-1По сути, автор сделал аналог GitOps, только для статического сайта. Правда, я не очень понял претензию к чужим сервисам - что автору мешает хостить статику со своего же сервера, ну и билдить при деплое (если не нравится гитхаб, можно хоть на сервер пушить, а можно и по ftp заливать, коли совсем дело плохо).
На поиграться интересно, но это же 100% велосипед.
GothicJS
15.06.2022 09:18Так я не понял, теперь што js и react не нужОн чтоли? Што за жизнь, учишь сначала mvc-шный фреймворк с родным шаблонизатором и узнаешь, что такое давно не модно и все хотят отдельный фронт в виде SPA. Потом учишь фронт и вот оказывается, что SPA то и не нормально вовсе и снова взад к многостраничной статике.....вот это поворот! Нет, в чем то тут должен быть подвох!
F0iL
Было возможно еще аж в IE 4 :)
Тоже очень старая идея - такое еще с конца девяностых было в Allegro RomPager. Правда, и страданий это принесло немало.