Getting Started

Building FrankenPHP

Compile a FrankenPHP binary with one or more Pogo plugins.

Pogo plugins are Caddy/FrankenPHP modules. They must be compiled into the FrankenPHP binary with xcaddy.

Local workspace build

From the local pogos workspace, this build includes all four documented plugins:

Terminal
PHP_CONFIG="$HOME/.local/frankenphp/php-8.5-zts/bin/php-config"
PHP_PREFIX="$HOME/.local/frankenphp/php-8.5-zts"

CGO_CFLAGS="-D_GNU_SOURCE -g -O0 $($PHP_CONFIG --includes)" \
CGO_LDFLAGS="-L$PHP_PREFIX/lib -Wl,-rpath,$PHP_PREFIX/lib $($PHP_CONFIG --ldflags) $($PHP_CONFIG --libs)" \
XCADDY_GO_BUILD_FLAGS="-buildvcs=false -ldflags='-w -s' -tags=nobadger,nomysql,nopgx,nowatcher" \
CGO_ENABLED=1 \
xcaddy build \
  --output frankenphp \
  --with github.com/dunglas/frankenphp/caddy=./frankenphp-main/caddy \
  --with github.com/dunglas/frankenphp=./frankenphp-main \
  --with github.com/dunglas/caddy-cbrotli \
  --with github.com/y-l-g/queue/module=./queue/module \
  --with github.com/y-l-g/scheduler/module=./scheduler/module \
  --with github.com/y-l-g/pogo/module=./pogo/module \
  --with github.com/y-l-g/websocket/module=./websocket/module

Use local paths while developing the modules. Use versioned remote modules for deployable builds.

Remote module build

Terminal
CGO_ENABLED=1 \
XCADDY_SETCAP=1 \
XCADDY_GO_BUILD_FLAGS="-ldflags='-w -s' -tags=nobadger,nomysql,nopgx,nowatcher" \
CGO_CFLAGS="$(php-config --includes)" \
CGO_CPPFLAGS="$(php-config --includes)" \
CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
xcaddy build \
  --output /usr/local/bin/frankenphp \
  --with github.com/dunglas/frankenphp@v1.12.3 \
  --with github.com/dunglas/frankenphp/caddy@v1.12.3 \
  --with github.com/dunglas/caddy-cbrotli \
  --with github.com/y-l-g/queue/module@main \
  --with github.com/y-l-g/scheduler/module@main \
  --with github.com/y-l-g/pogo/module@main \
  --with github.com/y-l-g/websocket/module@main

For production, pin plugin versions or commits instead of @main.

Docker pattern

Dockerfile
FROM dunglas/frankenphp:builder AS builder

COPY --from=caddy:builder /usr/bin/xcaddy /usr/bin/xcaddy

RUN CGO_ENABLED=1 \
    XCADDY_SETCAP=1 \
    XCADDY_GO_BUILD_FLAGS="-ldflags='-w -s' -tags=nobadger,nomysql,nopgx,nowatcher" \
    CGO_CFLAGS="$(php-config --includes)" \
    CGO_CPPFLAGS="$(php-config --includes)" \
    CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
    xcaddy build \
      --output /usr/local/bin/frankenphp \
      --with github.com/dunglas/frankenphp@v1.12.3 \
      --with github.com/dunglas/frankenphp/caddy@v1.12.3 \
      --with github.com/dunglas/caddy-cbrotli \
      --with github.com/y-l-g/queue/module@main \
      --with github.com/y-l-g/scheduler/module@main \
      --with github.com/y-l-g/pogo/module@main \
      --with github.com/y-l-g/websocket/module@main

FROM dunglas/frankenphp AS runner
COPY --from=builder /usr/local/bin/frankenphp /usr/local/bin/frankenphp

Then copy your PHP application and Caddyfile into the runner image.

Verify the binary

Run FrankenPHP with a Caddyfile that uses the plugin you compiled. If the binary was built without a required module, Caddy will fail during config load with an unknown directive or missing app error.