C언어와 CGI로 만든 2026년형 상용 웹 서비스

1994년식 기술로 2026년에 상용 웹 서비스를 만든 개발자가 화제다. 개발자 prophitt는 자신의 블로그에 올린 글에서 “marketyour.games”라는 실제 상용 제품을 C언어와 CGI(Common Gateway Interface)만으로 만들었다고 밝혔다. 결제, 이메일 발송, 계정 관리 같은 기능을 모두 갖춘 현대적인 웹 서비스를 30년 전 기술로 구현했다는 점에서 개발자 커뮤니티의 관심을 끌고 있다.

BCHS 스택이란 무엇인가

저자가 사용한 스택은 BCHS로 불린다. OpenBSD(운영체제), C(언어), httpd(웹서버), SQLite(데이터베이스)의 앞글자를 딴 이름이다. 별도의 웹 프레임워크도, 템플릿 엔진도, 독립된 데이터베이스 서버도 없다. CGI 환경 변수를 읽어 HTML을 직접 출력하는 C 프로그램 하나가 전부다. 데이터베이스는 SQLite의 C API로 파일을 직접 열어 사용한다.

외부 의존성도 극히 적다. Stripe와 Postmark로 보내는 요청은 libcurl이, 무작위 식별자 생성과 비밀번호 해싱, Stripe 웹훅 검증 같은 보안 작업은 libsodium이 처리한다. JSON 파싱은 단일 파일로 된 libcjson이 담당한다. 이 중 실제 빌드 의존성은 libcurl과 libsodium 둘뿐이며, SQLite와 libcjson은 각각 단일 C 파일(amalgamation) 형태로 프로젝트에 함께 포함(vendoring)된다.

프로세스 하나가 요청 하나를 처리하는 방식

CGI의 기본 동작 방식은 단순하다. 요청이 들어올 때마다 새 프로세스를 띄워 처리하고 끝나면 종료한다. 이 덕분에 배포 과정도 극단적으로 단순해진다. 새 버전을 올리는 작업은 파일 하나를 교체하는 것으로 끝난다. 서버를 재시작할 필요도, 다운타임도 없다. 새로 들어오는 요청은 자동으로 새 바이너리를 실행하게 된다.

정적 자산을 다루는 방식도 독특하다. 일반적으로는 이미지나 CSS 같은 정적 파일을 서버가 직접 서빙하지만, 이 프로젝트는 모든 트래픽을 CGI 바이너리로 보내고 자산 자체를 실행 파일 안에 컴파일해 넣어 메모리에서 서빙한다.

nginx+애플리케이션 서버 구조와 무엇이 다른가

오늘날 흔한 웹 서비스 구조는 nginx 같은 웹서버를 앞단에 두고, 그 뒤에 Ruby, Python, Go, Rust 등으로 작성된 애플리케이션 서버를 리버스 프록시로 연결하는 방식이다. 저자는 이 구조에 대해 “웹서버가 두 개 있는데, 그중 하나가 동시에 비즈니스 로직까지 책임지는 모양새가 늘 이상하게 느껴졌다”고 지적한다.

반면 CGI 방식은 웹서버 하나가 비즈니스 로직을 직접 호출한다. 역할 구분이 명확해지고, 디버깅도 단순해진다는 것이 저자의 주장이다. 애플리케이션이 그냥 평범한 프로그램이므로 셸에서 직접 실행하고, 요청을 파이프로 흘려보내고, stderr를 지켜보고, gdb로 한 줄씩 추적할 수 있다는 설명이다.

저자는 이 구조를 서버리스 아키텍처에 비유하기도 한다. 요청마다 코드를 호출하고, 환경 변수 묶음을 건네주고, 결과를 수거해 가는 구조가 서버리스와 닮았다는 것이다. 다만 벤더도 없고 예상치 못한 과금 폭탄도 없다는 점에서 “벤더 없는 서버리스”라고 표현했다.

왜 지금 다시 CGI인가

CGI 1.1 스펙은 2004년에 발표된 이후 바뀐 적이 없다. 저자는 CGI가 쇠퇴한 이유가 2004년 당시에는 타당했을지 몰라도 2026년 기준으로는 설득력이 떨어진다고 주장한다. HTTP의 기본 개념인 요청 헤더, 요청 메서드, 쿼리 스트링, 바디 데이터 정도만 이해하면 CGI 전체를 이해한 것이나 다름없을 만큼 배울 내용이 거의 없고, 언어와 플랫폼에 종속되지 않아 한 번 익힌 지식이 오래간다는 점을 장점으로 꼽는다.

최근 패키지 저장소에 대한 공급망 공격이 잦아지고 자율 에이전트가 코드를 대량으로 생성하는 시대적 배경도 저자가 적은 의존성을 재조명하는 이유 중 하나다. 일반적인 현대 기술 스택은 패키지 매니저와 생태계를 갖추고 있어 편리하지만, 의존성 하나둘이 수백 개의 간접 의존성을 끌어들이는 경우가 흔하다. 반면 이 프로젝트는 전체 빌드 과정에 움직이는 부품이 거의 없고, 클린 빌드도 수 초, 재빌드는 0.5초 이내로 끝난다고 한다.

한국 개발자가 참고할 만한 지점

이 사례를 그대로 실무에 도입하라는 뜻은 아니다. 프레임워크와 풍부한 생태계가 주는 생산성, 커뮤니티 지원, 채용 시장에서의 범용성은 여전히 무시할 수 없는 요소다. 다만 이 글은 “두 개의 웹서버를 겹쳐 쓰는 구조가 당연한가”, “의존성이 많을수록 생산적인가”라는 질문을 다시 던진다는 점에서 의미가 있다. 사이드 프로젝트나 소규모 서비스에서 OpenBSD의 pledge, unveil 같은 보안 기능과 httpd의 기본 chroot 샌드박싱을 활용해 가벼운 구조를 실험해보고 싶은 개발자라면 한 번쯤 원문을 읽어볼 만하다.

원문: A Modern Web App in C


코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다