<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
    <title>denisqsound</title>
    <subtitle>Блог и статьи Дениса: звук, код и инфраструктура.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://denisqsound.tech/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://denisqsound.tech"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-09-15T00:00:00+00:00</updated>
    <id>https://denisqsound.tech/atom.xml</id>
    <entry xml:lang="ru">
        <title>Как устроен этот сайт</title>
        <published>2026-09-15T00:00:00+00:00</published>
        <updated>2026-09-15T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://denisqsound.tech/articles/kak-ustroen-sajt/"/>
        <id>https://denisqsound.tech/articles/kak-ustroen-sajt/</id>
        
        <content type="html" xml:base="https://denisqsound.tech/articles/kak-ustroen-sajt/">&lt;p&gt;Личный сайт не должен быть сложным. Здесь весь стек умещается в один Dockerfile и один скрипт деплоя.&lt;/p&gt;
&lt;h2 id=&quot;stek&quot;&gt;Стек&lt;a class=&quot;zola-anchor&quot; href=&quot;#stek&quot; aria-label=&quot;Anchor link for: stek&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Zola&lt;/strong&gt; генерирует статику из Markdown. Один бинарь, никаких зависимостей в рантайме.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;nginx&lt;/strong&gt; внутри контейнера раздаёт готовые файлы.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;edge-proxy&lt;/strong&gt; на хосте принимает TLS и проксирует запросы в контейнер по внутренней docker-сети.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;sborka&quot;&gt;Сборка&lt;a class=&quot;zola-anchor&quot; href=&quot;#sborka&quot; aria-label=&quot;Anchor link for: sborka&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Образ собирается в два этапа: сначала Zola собирает &lt;code&gt;public/&lt;/code&gt;, затем результат копируется в образ с nginx.&lt;/p&gt;
&lt;pre class=&quot;giallo z-l-code z-d-code&quot; &gt;&lt;code data-lang=&quot;docker&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;FROM&lt;/span&gt;&lt;span&gt; alpine:3.22 &lt;/span&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;AS&lt;/span&gt;&lt;span&gt; build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;RUN&lt;/span&gt;&lt;span&gt; apk add --no-cache zola&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; . /site&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;RUN&lt;/span&gt;&lt;span&gt; cd /site &amp;amp;&amp;amp; zola build&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;FROM&lt;/span&gt;&lt;span&gt; nginx:1.29-alpine&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-l-8 z-d-10&quot;&gt;COPY&lt;/span&gt;&lt;span&gt; --from=build /site/public /usr/share/nginx/html&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Итоговый образ весит около 20 Мб. Внутри нет ни Node, ни Python: только nginx и статика.&lt;/p&gt;
&lt;h2 id=&quot;deploi&quot;&gt;Деплой&lt;a class=&quot;zola-anchor&quot; href=&quot;#deploi&quot; aria-label=&quot;Anchor link for: deploi&quot;&gt;🔗&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Машина на Oracle A1 имеет aarch64, как и мой Mac, поэтому образ собирается локально и уезжает на хост через &lt;code&gt;docker save | ssh docker load&lt;/code&gt;. Никакого registry, никакого CI: &lt;code&gt;deploy/deploy.sh&lt;/code&gt; делает всё за один запуск.&lt;/p&gt;
&lt;p&gt;TLS-сертификаты выпускает certbot-контейнер через HTTP-01: edge-proxy отдаёт ему &lt;code&gt;/.well-known/acme-challenge/&lt;/code&gt;, всё остальное уходит в 301 на HTTPS.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Минимум движущихся частей: если что-то сломается, сломается один контейнер со статикой, и чинить его будет не стыдно в два часа ночи.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Исходники лежат в репозитории &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https://github.com/denisqsound/denisqsound.tech&quot;&gt;denisqsound.tech&lt;/a&gt;.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;https://denisqsound.tech/articles/kak-ustroen-sajt/#fn-1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;Включая конфиг vhost&#39;а и скрипт выпуска сертификатов: инфраструктура тоже в git. &lt;a href=&quot;https://denisqsound.tech/articles/kak-ustroen-sajt/#fr-1-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
        
    </entry>
    <entry xml:lang="ru">
        <title>Первая запись</title>
        <published>2026-09-15T00:00:00+00:00</published>
        <updated>2026-09-15T00:00:00+00:00</updated>
        
        <author>
          <name>Unknown</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://denisqsound.tech/blog/pervyj-post/"/>
        <id>https://denisqsound.tech/blog/pervyj-post/</id>
        
        <content type="html" xml:base="https://denisqsound.tech/blog/pervyj-post/">&lt;p&gt;Это первая запись в блоге. Сайт собран на Zola, живёт в контейнере на маленькой виртуалке в Oracle Cloud, раздаётся через общий nginx-прокси.&lt;/p&gt;
&lt;p&gt;План простой: короткие заметки в блоге, длинные разборы в статьях. Пишу для себя в первую очередь, но если кому-то пригодится, тем лучше.&lt;/p&gt;
</content>
        
    </entry>
</feed>
