Files
frankenphp/CONTRIBUTING.md
Marc bbbfdb31b5 ci: build .rpm and .deb packages (#1497)
* add ./create-rpm.sh file to build a "frankenphp" rpm package

* also build a deb package

* renamed to build-packages

* linter...

* add depends

* linter again?

* linter number 3

* linter number 4

* set default locations for ini file, conf files and extensions

* set unified path for modules that should be ok on all dists

* add default content into "package" folder

* make file executable

* worker is in public folder

* what on earth did I do x)

* use same FRANKENPHP_VERSION and make sure to let pr's run the rpm generation too (version 0.0.0) to see issues

* install ruby, fpm and rpm-build

* move to after changing base urls because it would fail with packages not found

* ruby 3 build needs gcc 10

* rpm-build is necessary too...

* and I forgot to link the package folder

* create directories if they don't exist

* copy out all frankenphp* files?

* lint fix

* only copy frankenphp-* files

* only copy frankenphp-* files

* the .deb file is name frankenphp_1.5.0... - create output folder instead and upload all things inside that
will simplify things when later adding xdebug.so and ffi.so

* update the last two steps to use the gh-output directory

* add post install script to set frankenphp able to bind to port 80 for non-root users

* dnf over yum, I think the yum alias was removed in RH 9.5

* newlines

* newlines

* add text what missing libcap means

* copy php.ini-production from php-src, linter, update ruby version

* move Caddyfile to /etc/frankenphp/Caddyfile

* linter

* fix a copy and paste error

* better describe fallback to 0.0.0

* linter

* copy installation scripts from official caddy packages, change user to frankenphp too

* bombombom

* make files executable

* tabs

* linter

* linter again

* use empty directory for three different destinations instead of keeping three empty local directories

* caddy says the file is incorrectly formatted without these spaces

* remove wildcard matcher from root directive

* Apply suggestions from code review

commit suggested changes to preinstall/postinstall scripts

Co-authored-by: Kévin Dunglas <kevin@dunglas.fr>

* Update dev.Dockerfile

Co-authored-by: Kévin Dunglas <kevin@dunglas.fr>

* remove misleading comment

* update documentation for paths

* update documentation for paths some more

* fix musl opcache-jit issue

* markdown linter

* the damn tab

* Apply suggestions from code review

Co-authored-by: Kévin Dunglas <kevin@dunglas.fr>

* drop dev.Dockerfile php location from config.md

* add php config note to CONTRIBUTING.md

* dashes instead of asterisks in chinese docs

* fix package building

* create frankenphp user in case it doesn't exist for deb packages

* create users if they don't exist, delete them again if they didn't exist

* satisfy linter

* create the user with the same commands as the postinst/preinstall scripts

* Removes toolchain requirements.

* trigger

* Removes explicit calls to go get

* trigger

* setcap by default

* simplify example project

* bring page more in line with the caddy / apache / nginx default page

* update to html 5

* oopsies

* revert style to original

* remove https:// (caddy uses http:// on RHEL, :80 on Debian)

---------

Co-authored-by: Kévin Dunglas <kevin@dunglas.fr>
Co-authored-by: Alliballibaba <alliballibaba@gmail.com>
2025-05-14 07:33:05 +02:00

6.5 KiB

Contributing

Compiling PHP

With Docker (Linux)

Build the dev Docker image:

docker build -t frankenphp-dev -f dev.Dockerfile .
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -p 8080:8080 -p 443:443 -p 443:443/udp -v $PWD:/go/src/app -it frankenphp-dev

The image contains the usual development tools (Go, GDB, Valgrind, Neovim...) and uses the following php setting locations

  • php.ini: /etc/frankenphp/php.ini A php.ini file with development presets is provided by default.
  • additional configuration files: /etc/frankenphp/php.d/*.ini
  • php extensions: /usr/lib/frankenphp/modules/

If your docker version is lower than 23.0, the build will fail due to dockerignore pattern issue. Add directories to .dockerignore.

 !testdata/*.php
 !testdata/*.txt
+!caddy
+!internal

Without Docker (Linux and macOS)

Follow the instructions to compile from sources and pass the --debug configuration flag.

Running the test suite

go test -tags watcher -race -v ./...

Caddy module

Build Caddy with the FrankenPHP Caddy module:

cd caddy/frankenphp/
go build -tags watcher,brotli,nobadger,nomysql,nopgx
cd ../../

Run the Caddy with the FrankenPHP Caddy module:

cd testdata/
../caddy/frankenphp/frankenphp run

The server is listening on 127.0.0.1:80:

Note

if you are using Docker, you will have to either bind container port 80 or execute from inside the container

curl -vk http://127.0.0.1/phpinfo.php

Minimal test server

Build the minimal test server:

cd internal/testserver/
go build
cd ../../

Run the test server:

cd testdata/
../internal/testserver/testserver

The server is listening on 127.0.0.1:8080:

curl -v http://127.0.0.1:8080/phpinfo.php

Building Docker Images Locally

Print bake plan:

docker buildx bake -f docker-bake.hcl --print

Build FrankenPHP images for amd64 locally:

docker buildx bake -f docker-bake.hcl --pull --load --set "*.platform=linux/amd64"

Build FrankenPHP images for arm64 locally:

docker buildx bake -f docker-bake.hcl --pull --load --set "*.platform=linux/arm64"

Build FrankenPHP images from scratch for arm64 & amd64 and push to Docker Hub:

docker buildx bake -f docker-bake.hcl --pull --no-cache --push

Debugging Segmentation Faults With Static Builds

  1. Download the debug version of the FrankenPHP binary from GitHub or create your custom static build including debug symbols:

    docker buildx bake \
        --load \
        --set static-builder.args.DEBUG_SYMBOLS=1 \
        --set "static-builder.platform=linux/amd64" \
        static-builder
    docker cp $(docker create --name static-builder-musl dunglas/frankenphp:static-builder-musl):/go/src/app/dist/frankenphp-linux-$(uname -m) frankenphp
    
  2. Replace your current version of frankenphp by the debug FrankenPHP executable

  3. Start FrankenPHP as usual (alternatively, you can directly start FrankenPHP with GDB: gdb --args frankenphp run)

  4. Attach to the process with GDB:

    gdb -p `pidof frankenphp`
    
  5. If necessary, type continue in the GDB shell

  6. Make FrankenPHP crash

  7. Type bt in the GDB shell

  8. Copy the output

Debugging Segmentation Faults in GitHub Actions

  1. Open .github/workflows/tests.yml

  2. Enable PHP debug symbols

        - uses: shivammathur/setup-php@v2
          # ...
          env:
            phpts: ts
    +       debug: true
    
  3. Enable tmate to connect to the container

        - name: Set CGO flags
          run: echo "CGO_CFLAGS=$(php-config --includes)" >> "$GITHUB_ENV"
    +   - run: |
    +       sudo apt install gdb
    +       mkdir -p /home/runner/.config/gdb/
    +       printf "set auto-load safe-path /\nhandle SIG34 nostop noprint pass" > /home/runner/.config/gdb/gdbinit
    +   - uses: mxschmitt/action-tmate@v3
    
  4. Connect to the container

  5. Open frankenphp.go

  6. Enable cgosymbolizer

    -	//_ "github.com/ianlancetaylor/cgosymbolizer"
    +	_ "github.com/ianlancetaylor/cgosymbolizer"
    
  7. Download the module: go get

  8. In the container, you can use GDB and the like:

    go test -tags watcher -c -ldflags=-w
    gdb --args frankenphp.test -test.run ^MyTest$
    
  9. When the bug is fixed, revert all these changes

Misc Dev Resources

Useful Command

apk add strace util-linux gdb
strace -e 'trace=!futex,epoll_ctl,epoll_pwait,tgkill,rt_sigreturn' -p 1

Translating the Documentation

To translate the documentation and the site in a new language, follow these steps:

  1. Create a new directory named with the language's 2-character ISO code in this repository's docs/ directory
  2. Copy all the .md files in the root of the docs/ directory into the new directory (always use the English version as source for translation, as it's always up to date)
  3. Copy the README.md and CONTRIBUTING.md files from the root directory to the new directory
  4. Translate the content of the files, but don't change the filenames, also don't translate strings starting with > [! (it's special markup for GitHub)
  5. Create a Pull Request with the translations
  6. In the site repository, copy and translate the translation files in the content/, data/ and i18n/ directories
  7. Translate the values in the created YAML file
  8. Open a Pull Request on the site repository