4P by GN⁺ | ★ favorite | 댓글 1개
  • PHP 앱을 별도 PHP-FPM 없이 띄우려는 배포 흐름에서, FrankenPHP는 Caddy에 공식 PHP 실행기를 내장한 Go 기반 앱 서버로 PHP 웹 앱과 CLI 스크립트를 한 명령으로 실행하게 함
  • HTTP/1.1·HTTP/2·HTTP/3, 자동 HTTPS 인증서, Brotli/Zstandard/Gzip 압축, 구조화 로깅, Prometheus 메트릭을 기본 기능으로 묶어 서버 구성을 줄임
  • Worker mode는 앱을 한 번 부팅해 메모리에 유지하며, API Platform 앱 자체 벤치마크에서 FPM보다 3.5배 빠른 결과를 냈다고 설명함
  • PHP 8.2+, 대부분의 PHP 확장, Caddy 모듈과 호환되고 OPcache·XDebug 같은 인기 확장도 네이티브로 지원함
  • Docker 이미지, Kubernetes, 클라우드 플랫폼, 독립 실행형 정적 바이너리 배포를 지원해 PHP 앱 배포 단위를 단순하게 만들 수 있음

실행 방식과 기본 사용 흐름

  • FrankenPHP는 Go로 작성된 현대적인 PHP 앱 서버를 지향하며, PHP 앱 서버 설치와 실행을 한 명령 중심으로 구성함
  • 설치 예시는 운영체제별로 나뉨
  • 로컬 실행은 웹 서버와 CLI 양쪽을 모두 다룸
    • frankenphp php-server -r public/: public/ 디렉터리 서빙
    • frankenphp php-cli script.php: 명령줄 PHP 스크립트 실행
  • Docker 실행도 같은 이미지로 처리함
    • dunglas/frankenphp 이미지로 public/ 디렉터리를 서빙
    • 같은 이미지에서 php script.php 같은 CLI 스크립트 실행 가능
  • 설정은 Caddy 기반이며, 예시 구성은 localhost 블록 안에서 압축을 켜고 php_server로 현재 디렉터리의 PHP 파일과 정적 자산을 처리함

서버 기능과 PHP 호환성

  • 웹 서버 기능

    • 공식 PHP 실행기를 Caddy에 내장함
    • HTTP/1.1, HTTP/2, HTTP/3를 네이티브 지원함
    • Let’s Encrypt 또는 ZeroSSL을 통한 HTTPS 인증서 생성·갱신·폐기를 자동화함
    • Brotli, Zstandard, Gzip 압축을 기본 지원함
    • 구조화 로깅과 Prometheus 지원을 포함함
  • PHP 실행 환경

    • PHP 8.2+, 대부분의 PHP 확장, 모든 Caddy 모듈과 호환됨
    • OPcacheXDebug를 포함한 인기 PHP 확장을 네이티브로 지원함
    • PHP-FPM이 필요 없고, Go 웹 서버용으로 만든 자체 SAPI를 사용함

Worker mode와 성능 지향 기능

  • Worker mode는 애플리케이션을 한 번 부팅한 뒤 메모리에 유지해, 요청을 몇 밀리초 안에 처리할 준비 상태로 둠
  • Symfony, API Platform, Laravel에서 네이티브로 지원됨
  • PSR-7 없이 기존 PHP 슈퍼글로벌을 사용함
  • 앱이 Worker mode와 호환되지 않아도 그대로 서빙할 수 있음
  • 코드 변경 시 워커를 자동 재시작하는 watcher를 제공함
  • API Platform 앱 기준 자체 벤치마크에서 FPM보다 3.5배 빠른 성능을 보였다고 소개함

배포와 패키징

  • Docker 이미지로 클라우드 네이티브 앱을 배포할 수 있음
  • Kubernetes와 현대적 클라우드 플랫폼과 호환됨
  • PHP 웹 애플리케이션과 명령줄 도구를 독립 실행형 정적 바이너리로 패키징할 수 있음
  • 하나의 서비스와 하나의 바이너리로 실행되며 외부 서비스가 필요 없다고 설명함

추가 웹 플랫폼 기능

  • 103 Early Hints를 지원하며, Cloudflare 글을 근거로 웹사이트 로드 시간을 30% 개선할 수 있는 기능으로 소개함
  • 내장 Mercure 허브를 통해 PHP 앱에서 연결된 브라우저로 이벤트를 보내고, 브라우저가 JavaScript 이벤트로 페이로드를 즉시 받을 수 있음
  • Graceful reload로 무중단 배포를 지원함

댓글과 토론

Hacker News 의견들
  • PHP 개발은 거의 10년 안 했는데, 이 랜딩 페이지를 보고 거의 hello world라도 띄워볼 뻔했음
    코끼리 프랑켄슈타인 캐릭터가 괴상하면서 못생기고 귀여움. 디자인, 색상, 문구, 애니메이션도 깔끔함. 한동안 PHP 개발에서 떨어져 있던 입장에서는 가치 제안이 잘 드러나고, 작은 걸 빠르게 시작하기 좋아 보임
    • 10년 좀 넘게 전에 PHP에서 Golang으로 옮겼는데, 바이너리 배포가 너무 좋았기 때문임
      별로인 소프트웨어나 꼬인 의존성을 격리하려고 컨테이너 8개를 띄우고 싶지 않음. 설치 가능한 소프트웨어를 내놓는 대신 “내 컴퓨터에서는 됨”을 포장해서 세상에 던지는 식은 싫음. 향수 때문에 한번 만져볼 수는 있겠지만, 이런 걸 더는 운영 환경에 넣고 싶은지는 잘 모르겠음
    • 지금까지 본 것 중 손에 꼽히는 랜딩 페이지임. 재미있고 바로 이해됨
  • C#을 오래 했고 지금은 주로 PHP 8로 코딩하는데, 빠르게 뭔가를 만들기 좋은 훌륭한 언어임
    예전 LAMP처럼 다소 복잡한 Apache 설정이 필요한 방향보다, 언어가 이런 방향으로 가야 함
    • PHP 18년 차인데, nginx + php-fpm을 쓰면 설정에 5분이면 충분함
      이것도 한번 써볼 생각이지만 nginx든 Apache든 병목을 겪어본 적은 없음. 둘 다 길어야 몇 분이면 띄울 수 있음
    • 또 다른 선택지로 Nginx Unit도 있음: https://unit.nginx.org/
      Apache + mod_php처럼 단일 서비스로 실행되고, PHP와 다른 언어의 멀티프로세싱, 정적 파일, 리버스 프록시를 처리하며, 파일이나 소켓을 통한 런타임 방식으로 자기 자신과 PHP를 하나의 설정에서 다룰 수 있음: https://unit.nginx.org/configuration/#php
      실제 설정 예시는 https://github.com/PrivateBin/docker-unit-alpine/blob/master...이고, 결과 컨테이너 이미지도 꽤 작게 만들 수 있음: https://hub.docker.com/r/privatebin/unit-alpine
    • PHP를 거의 설정하지 않지만, 데스크톱을 재설치할 때마다 한 번씩 했던 기억으로는 apt-get으로 아주 빠르고 매끄럽게 끝났음
      Apache를 재시작한 것 말고는 딱히 더 한 일이 기억나지 않음
    • Apache 설정이 정말 그렇게 나쁜가 싶음. PHP-FPM 같은 걸 쓰면 꽤 괜찮아 보임: https://news.ycombinator.com/item?id=40256843
      LoadModule proxy_fcgi_module "/usr/lib/apache2/modules/mod_proxy_fcgi.so"SetHandler "proxy:fcgi://127.0.0.1:9000" 정도임. Apache를 설정하는 방식과 개념적으로 비슷한 Nginx 예시도 있고, 필요한 패키지 설치까지 포함됨: https://news.ycombinator.com/item?id=37443911
      비슷한 결과를 얻을 수 있는 미리 빌드된 컨테이너 이미지도 있지만, 내부가 어떻게 돌아가는지 보고 싶으면 직접 해볼 수 있음. 예전 Java 애플리케이션 서버에서 Tomcat이나 GlassFish를 수동 설정하던 것보다는 확실히 쉽고, 어떤 환경이든 단일 실행 명령이 더 낫긴 해도 LAMP가 다른 스택에 비해 그렇게 나쁘지는 않음
    • 동의함. PostgreSQL/MySQL 대신 SQLite에 의존하는 문화가 자리 잡으면, 서버 사이드 애플리케이션 전체가 단순한 독립 실행 바이너리가 될 수 있음
      바이너리가 있으면 Electron 앱에 묶기도 쉬워짐
  • 개발 중에는 PHP 내장 웹서버를 자주 씀: php -S 0.0.0.0:8000 public/index.php
    하지만 단일 스레드이고 느려서 운영 환경용은 아님. FrankenPHP는 유망해 보이지만, 코어/스레드 제한 이슈[2]도 운영에서 문제가 될 수 있어 보임. 그래도 pure-todo[1] 프로젝트에 한번 적용해서 같은 문제가 있는지 볼 수도 있겠음. 기본 Docker 이미지가 꽤 좋아 보임
    1: https://github.com/sandreas/pure-todo
    2: https://github.com/dunglas/frankenphp/discussions/294
    • PHP 내장 서버는 문서에서 명시적으로 운영용이 아니며, 개발 목적 전용이라고 되어 있음
      페이지 상단 경고 참고: https://www.php.net/manual/en/features.commandline.webserver...
      이 맥락에서 비교 대상으로 삼는 게 공정한지도 잘 모르겠음
    • PHP_CLI_SERVER_WORKERS를 설정하면 여러 스레드로 실행할 수 있음
    • 운영 환경에 못 쓴다는 게 성능만의 문제인지 궁금함
      사용자 수가 적은 작은 사이트라면, 다른 “운영 준비 완료” 환경에 비해 무엇을 놓치게 되는지 알고 싶음
    • 단일 스레드이고 느려서 운영용이 아니라는 특정 문제들은 이게 해결하는 것으로 알고 있음. 그 밖의 문제도 더 해결할 듯함
  • 직접 써봤는데 정말 느렸고, 코어도 제대로 못 쓰는 것 같았음. 부족한 문서를 한참 봤지만 해결하지 못함
    몇 가지 명령만으로 운영 준비가 되고 FPM보다 3.5배 빠르다고 하지만, 내 환경에서는 FPM 성능의 1% 정도로 동작함. 실행 파일도 시도했지만 같은 문제였고, hello world라면 최소 200K rps는 기대했음
    • FrankenPHP 만든 사람임. 재현 가능한 예제를 정말 받고 싶음
      대부분의 벤치마크에서는 작업자 모드가 켜졌을 때 FrankenPHP가 보통 FPM보다 훨씬 빠르며, 대략 3배 정도임. 그래도 일부 예외 사례가 있고 PHP 유지보수자들과 함께 고치고 있음
    • 그 경험을 공유해주면 이걸 해결하는 데 도움이 됨: https://github.com/dunglas/frankenphp/discussions/294
      Caddy 자체는 PHP와 함께 써도 성능이 아주 잘 나오기 때문에 꽤 이상한 상황임
  • TechEmpower 벤치마크에서 어떻게 나올지 궁금함: https://www.techempower.com/benchmarks/#hw=ph&test=fortune&s...
    지금은 did not complete로 맨 아래에 있음
  • 관련 글: Show HN: FrankenPHP, Go로 작성한 PHP용 앱 서버 - https://news.ycombinator.com/item?id=33205282 - 2022년 10월, 댓글 83개
  • https://github.com/dunglas/frankenphp/discussions/294
    성능 이슈가 있음. 그걸 제외하면 정말 유망한 프로젝트임
    • 재현할 수만 있다면 기꺼이 회사에서 2주 휴가를 내고 고칠 것임. 아무도 재현 방법을 알려주지 않았음
  • WordPress를 FrankenPHP와 Apache Mod-PHP에서 벤치마크해봤는데, FPHP가 이긴다는 근거는 못 봤음
    다만 깊게 파보지는 않았고 테스트도 일반 설정이 아니라 Docker 안에서 했음. WordPress도 거의 기본 설정이라 무거운 테마 같은 게 없어 현실적인 조건은 아니었음. 그래도 테스트를 다시 해보고 더 잘 이해하고 싶음
    • Laravel과 Symfony와 달리 WordPress는 아직 FrankenPHP의 작업자 모드를 지원하지 않아서, 성능상 이점이 많지 않음
      다만 103 Early Hints로 자산을 미리 불러와 페이지 로드 지연 시간을 30% 줄일 수는 있음. 그래도 FrankenPHP는 WordPress에서 HTTP 캐시를 켜기 쉽게 만들고 배포도 단순화함. WordPress와 FrankenPHP 전용 프로젝트도 있고, Souin Go 라이브러리를 사용한 WordPress 맞춤 내장 HTTP 캐시가 포함되어 있음: https://github.com/StephenMiracle/frankenwp
    • 익숙해서 그 이름을 쓰는 것일 수도 있지만, 표준적으로는 Apache에서 proxy_fcgi를 써야 함
      Apache 메모리를 조금 더 아끼고 더 많은 PHP 요청을 처리할 여지를 만들 수 있음
  • docker run -v $PWD:/app/public -p 443:443 \ dunglas/frankenphp
    앱을 서비스할 Docker 컨테이너를 직접 만들고 싶다면, 새 Debian을 필요한 컨테이너로 바꾸는 데 아래 명령이면 충분할 듯함: apt install -y apache2 libapache2-mod-php/etc/apache2/sites-enabled/000-default.conf 설정
    친구들과 함께 여러 인기 언어와 프레임워크로 0부터 실행 중인 웹 애플리케이션까지 가는 과정을 보여주는 저장소를 유지하고 있음: https://github.com/no-gravity/web_app_from_scratch
    • 한 달 전부터 mod_php를 쓰는 회사에서 일하기 시작했는데 고통스러움
      xdebug를 켤 때마다 디버깅 세션 후 Apache를 재시작해야 함. 어제부터 apache2를 php-fpm으로 쓰도록 설정하기 시작했는데, 적어도 개발 환경에서는 이 FrankenPHP가 우리에게 맞을지 궁금함. 다만 문서에서 php 확장을 설치하는 방법을 못 찾겠음
    • 내가 착각한 게 아니라면 이건 동작하지 않을 듯함. 기본 Apache 000-default.conf 가상 호스트가 443에서 80으로 리다이렉트하나?
  • HN 첫 페이지에서 이걸 보니 반가움
    FPM과 그 무공유 아키텍처는 오래전 PHP 성공의 핵심이었지만, 동시에 PHP의 족쇄이기도 했다고 느낌