Когда «старое» вдруг становится авангардом

В мире, где каждые полгода появляется новый JavaScript-фреймворк, а слово «контейнер» стало синонимом «правильной архитектуры», один разработчик пошёл принципиально другим путём. Современное веб-приложение — написанное на C и поданное по старинке: CGI, SQLite и единственный бинарник. Никаких фреймворков, контейнеров — и никаких сожалений.

Это не учебный проект и не эксперимент ради эксперимента. Разработчик описывает создание и запуск коммерческого продукта marketyour.games полностью на C, обслуживаемого через CGI на OpenBSD с httpd и SQLite, следуя стеку BCHS. Давайте разберёмся, как это устроено, почему это работает и что из этого можно взять на вооружение.


Что такое marketyour.games и почему это важно

Всё в marketyour.games является современным: это веб-продукт с аккаунтами пользователей, поисковой панелью для контент-мейкеров, папками для их организации, платежами через Stripe и транзакционными письмами через Postmark. Он следует принципу прогрессивного улучшения и не требует JavaScript.

Всё современное — кроме того, как оно создано и как обслуживается. Это реальные мысли о написании продакшн-продукта на C и его подаче через CGI в 2026 году.

Продукт включает аккаунты пользователей, платежи через Stripe и транзакционную почту через Postmark — всё скомпилировано в единый статически слинкованный бинарник без фреймворка, шаблонизатора, контейнера или отдельного сервера базы данных.

ℹ Стек BCHS
BCHS расшифровывается как BSD + C + httpd + SQLite — минималистичный стек для создания веб-приложений, принципиально отказывающийся от тяжёлых зависимостей. Вместо nginx + Docker + PostgreSQL + Node.js — один бинарник на OpenBSD.

CGI в 2026: незаслуженно забытый или обоснованно похороненный?

CGI (Common Gateway Interface) получил плохую репутацию в начале 2000-х — и тому были причины: на тогдашнем железе каждый HTTP-запрос порождал новый процесс, что при нагрузке становилось узким местом.

Упадок CGI был оправдан в 2004 году, но не выдерживает критики в 2026-м.

Почему? Современное серверное железо настолько мощное, что накладные расходы на fork нового процесса под запрос стали статистически незначимы для подавляющего большинства веб-приложений. Типичный SaaS с несколькими тысячами пользователей не упрётся в CGI-ограничения никогда.

Автор доказывает, что репутация CGI из начала 2000-х больше неактуальна с учётом возможностей современного железа, подчёркивает минимальную цепочку зависимостей (только libcurl и libsodium), простоту отладки через gdb и shell-инструменты, а также операционное удобство SQLite в сравнении с Postgres.


graph LR
    A[HTTP-запрос] --> B[OpenBSD httpd]
    B --> C[CGI fork]
    C --> D[C-бинарник]
    D --> E[SQLite]
    D --> F[Stripe API / Postmark]
    D --> G[HTTP-ответ]
    G --> A

Архитектура выглядит почти неприлично простой. И в этом её сила.


Инструменты и зависимости: радикальный минимализм

Один из главных аргументов в пользу этого подхода — минимальное количество внешних зависимостей и богатый, зрелый инструментарий.

Сложные технологические стеки требуют сложного инструментария: они требуют language server, чтобы продираться через слои абстракций. Но этот стек достаточно прост, чтобы хватило обычного редактора. Всё приложение — это директория с C-файлами и Makefile.

Открываешь файл, читаешь — и сразу понимаешь, что он делает.

Санитайзеры, valgrind, gdb, ctags, cscope — это зрелые (даже «гериатрические») инструменты, отточенные десятилетиями, и они находятся в одной команде package install от любой системы, умеющей компилировать C. Зрелость выходит за рамки самих инструментов: интеграция встроена во многие редакторы. Vim поставляется с нативной поддержкой ctags, cscope и имеет графический frontend для gdb.

Зависимости проекта

Весь стек зависимостей умещается в таблицу:

КомпонентРольАльтернатива в типичном стеке
OpenBSD httpdВеб-серверnginx / Apache
CGIПротокол запрос-ответWSGI, ASGI, Node.js runtime
SQLiteБаза данныхPostgreSQL + отдельный сервер
libcurlHTTP-клиент (Stripe, Postmark)axios, requests, fetch
libsodiumКриптографияOpenSSL + bcrypt + …
MakefileСборкаnpm / webpack / gradle
💡 Почему SQLite, а не PostgreSQL?
SQLite не требует отдельного процесса-сервера, администрирования, репликации «из коробки» или настройки подключений. Для продуктов с умеренной нагрузкой это убийственно удобно: база данных — это просто файл рядом с бинарником.

Можно ли вообще писать веб на чистом C? Да, и вот как

Вы можете написать современное веб-приложение на C. Автор сделал это и выпустил его.

Вот как выглядит типичный обработчик маршрута в C-веб-приложении, использующем CGI:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    // CGI: читаем метод и путь из переменных окружения
    char *method  = getenv("REQUEST_METHOD");
    char *path    = getenv("PATH_INFO");
    char *query   = getenv("QUERY_STRING");

    // Минимальный роутинг
    printf("Content-Type: text/html\r\n\r\n");

    if (strcmp(path, "/hello") == 0) {
        printf("<h1>Hello from C!</h1>");
    } else {
        printf("<h1>404 Not Found</h1>");
    }

    return 0;
}

CGI-скрипт просто читает переменные окружения (которые httpd заполняет из HTTP-запроса), пишет заголовки и тело ответа в stdout. Всё. Никакого event loop, никакого async/await.

C уже питает «сантехнику» веба: веб-серверы, обратные прокси, базы данных и среды исполнения, на которых работают другие веб-языки. Напрямую строить на нём можно через CGI, встроенные HTTP-библиотеки, C-фреймворки или WebAssembly в браузере.

Для тех, кому CGI покажется слишком простым, существуют готовые решения:

Высокопроизводительный веб-сервер и фреймворк для создания веб-приложений на C для Linux. Построен на событийно-ориентированной архитектуре epoll, эффективно обрабатывающей большое количество одновременных соединений.

Фреймворк предоставляет полный набор инструментов для разработки современных веб-приложений: от базового HTTP-сервера до интеграции с базой данных, WebSocket-соединений, системы аутентификации и файлового хранилища.

⚠ Важно про безопасность
C не имеет встроенной защиты от переполнения буфера, use-after-free и других memory-safety проблем. Если вы пишете на C для веба, обязательно используйте санитайзеры (-fsanitize=address,undefined) на этапе разработки, valgrind для поиска утечек и libsodium вместо самописной криптографии.

Реальные плюсы и минусы подхода

Честный взгляд на то, что вы получаете и от чего отказываетесь.

КритерийC + CGI + SQLiteТипичный современный стек
Скорость запускаМгновенноСекунды (JVM, Node.js cold start)
Потребление памятиМинимальноеОт сотен МБ
ДеплойОдин бинарник + файл БДDocker, оркестратор, CI/CD pipeline
Отладкаgdb, valgrindDevTools, логи в облаке
Скорость разработкиНизкаяВысокая
Найм разработчиковСложноЛегко
Memory safetyРучнаяВстроенная / GC
Зависимости2 (libcurl, libsodium)Сотни (node_modules)
Обновление зависимостейРедкоПостоянно

Реальный компромисс — не скорость. Это время разработки, безопасность памяти и сложность найма людей, которые пишут на C безопасно.

«Сложные технологические стеки требуют сложного инструментария. Но этот стек достаточно прост, чтобы хватило обычного редактора.»

Это честная сделка: вы платите сложностью разработки, но получаете невероятную предсказуемость и простоту эксплуатации.


FastCGI как путь масштабирования

Одно из возражений против CGI — производительность при росте трафика. У автора есть ответ:

Если стоимость fork когда-либо станет проблемой, FastCGI — это достаточно простое обновление.

FastCGI устраняет накладные расходы на fork, позволяя процессу-обработчику работать постоянно и принимать несколько запросов. Переход с CGI на FastCGI — это изменение нескольких строк конфига httpd и небольшая правка кода, а не переписывание архитектуры.

Таким образом, стек остаётся масштабируемым: начинаете с CGI (простота), переходите на FastCGI (производительность), не меняя бизнес-логику.


Заключение: зачем это знать в 2026 году

Написание современного веб-приложения на C — это более чем осуществимо: marketyour.games — коммерческий продукт, работающий на одном бинарнике с использованием модели обслуживания, официально стандартизированной в 2004 году.

Это не призыв переписать всё на C. Это напоминание о нескольких важных вещах:

  1. Сложность стека — это выбор, а не необходимость. Для многих продуктов CGI + SQLite + один бинарник — идеальное решение.
  2. «Устаревшие» технологии не всегда устарели. CGI пережил волны фреймворков и по-прежнему работает.
  3. Понимание основ даёт преимущество. Освоение C — путь стать не просто кодером, а настоящим инженером, способным диагностировать глубокие проблемы производительности и строить системное ПО.
  4. Минимализм зависимостей — это конкурентное преимущество. Пока другие обновляют сотни npm-пакетов, ваш проект просто работает.
📝 Попробуйте сами
Если хотите погрузиться в этот подход: установите OpenBSD, изучите документацию по OpenBSD httpd и CGI, возьмите amalgamation-сборку SQLite (один .c-файл!) и напишите простой to-do менеджер. Это отличный способ понять, как веб работает на уровне протокола.

В конце концов, лучший стек — это тот, который решает вашу задачу с минимальной сложностью. Иногда этим стеком оказывается C.