dunglas / frankenphp Goto Github PK
View Code? Open in Web Editor NEW๐ง The modern PHP app server
Home Page: https://frankenphp.dev
License: MIT License
๐ง The modern PHP app server
Home Page: https://frankenphp.dev
License: MIT License
Running this on an Apple M1 chip give the following warning:
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
Would be useful to have ARM variants of the container image.
It's unclear from the docker tags which PHP version I would be getting.
I think for adoption it'd be good to be specific about this, even if you only want to be building 8.2, make an :php-8.2
tag so that when you update to 8.3
people can stick on the older version
It REALLY sounds and looks like a very promising PHP Framework!
Thumbs Up!
Hugo Barbosa
Hi Dunglas ๐๐ป
First, thanks for this new SAPI, amazing to see how PHP can be improved for future applications.
Small issue that I'm facing while using the worker
mode, I followed the documentation for the Symfony application then launched it using Docker:
docker run \
-e FRANKENPHP_CONFIG="worker ./public/index.php" \
-v $PWD:/app \
-p 80:80 -p 443:443 \
dunglas/frankenphp
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
# ...
First, it seems that the v8
version is not automatically pulled, is there any issue using an arm64
image (I'm on M1 chip)?
Second, when launched (it launched even with the warning message, it seems that it cannot be started correctly:
{"level":"info","ts":1665988244.9370515,"msg":"using provided configuration","config_file":"/etc/Caddyfile","config_adapter":""}
{"level":"warn","ts":1665988244.965832,"msg":"Caddyfile input is not formatted; run the 'caddy fmt' command to fix inconsistencies","adapter":"caddyfile","file":"/etc/Caddyfile","line":3}
{"level":"info","ts":1665988244.9821901,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1665988244.9869301,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000518540"}
{"level":"info","ts":1665988244.9886699,"logger":"http","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
{"level":"info","ts":1665988244.989175,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"error","ts":1665988250.9599025,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1665988250.9616716,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1665988250.9628036,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1665988250.9642198,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1665988250.9654243,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1665988250.9677563,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
I'm not sure why it tries to restart the worker (maybe it's due to the arm64
architecture?) but the application does not respond ๐
Thanks for the help and sorry for this issue ๐
Consider the following code:
register_shutdown_function(function() { error_log('outside'); });
do {
$running = frankenphp_handle_request(function (): void {
register_shutdown_function(function() { error_log('in request'); });
});
} while ($running);
Nothing is output in the logs that I can see (tested SIGTERM, SIGINT to stop the server):
A number of frameworks/libraries use shutdown functions to trigger things after a request (I've abused them to process queues, I think WordPress uses them to process cron jobs, error reporting, etc). It'd also be useful to do things when the worker itself dies (outside the loop) though, but in most cases shut down functions are registered with an expectation of request ending.
Hi, thanks for the quick fix for #104!
I am now one step further, as in: the server now redirects and responds correctly, but it doesn't serve the file I gave it in the command line.
Running this command with the latest (sha-878a30d) image:
docker run --rm -e FRANKENPHP_CONFIG="worker ./example/worker.php" -p 80:80 -p 443:443 -v $pwd:/app -w /app dunglas/frankenphp
and this worker.php
file:
<?php
// ./example/worker.php
do {
$running = frankenphp_handle_request(
function () {
echo "hello world";
}
);
} while ($running);
Results in this output:
Warning: Unknown: Failed to open stream: No such file or directory in Unknown on line 0
Fatal error: Failed opening required '/app/public/worker.php' (include_path='.:/usr/local/lib/php') in Unknown on line 0
So I assume the public
path is hardcoded somehow? Which path do I need to give it in the FRANKENPHP_CONFIG
value for the worker mode?
Currently, there is one worker spawned per core (if I'm understanding correctly).
This severely limits concurrent connections as it appears only one request per worker can be handled at a time.
Changing this to 2x dramatically affects the techempower benchmarks:
from:
{
"latencyAvg": "421.56ms",
"latencyMax": "3.65s",
"latencyStdev": "766.41ms",
"totalRequests": 74185,
"startTime": 1671386842,
"endTime": 1671386858
}
to
{
"latencyAvg": "100.05ms",
"latencyMax": "1.01s",
"latencyStdev": "137.47ms",
"totalRequests": 112578,
"startTime": 1671387704,
"endTime": 1671387719
}
Anything beyond 2x has diminishing returns in my testing. FWIW, 2x on my hardware is 32 workers.
In the built-in Caddyfile, there is a built-in DEBUG
env var injected. This is quite generic and may conflict with other frameworks or applications. Perhaps we should call it FRANKENPHP_DEBUG
?
im getting ERR_SSL_PROTOCOL_ERROR
is there a way to server files with working ssl?
i want to use public ip or able to link it behind cloudflare with domain
is there env for custom crt?
I'm seeing random (but extremely rare: <0.5% of requests) fatal PHP errors in worker mode:
Cannot instantiate interface from
Cannot instantiate trait from
Cannot instantiate enum
Cannot instantiate abstract class
There's no interface or trait specified in the error, just to be clear, those errors are the literal messages given. The error occurs on random lines/files.
This never happens outside of worker mode and I cannot reproduce it in a smaller sample.
The relevant error messages are coming from these lines in php-src. It smells like some memory shenanigans but it isn't clear if it is a frankenphp bug or a PHP/extension bug.
Hi,
looks like there is currently no license. Could you please add one?
Thanks
What is the best way to add PHP extensions? Once approach I enjoy from Bref is how it includes the extensions but disables them. Are there plans to include enabling/disabling extensions like Postgres?
I am able to change {$SERVER_NAME:localhost}
to {$SERVER_NAME:demo.localhost}
in caddy/frankenphp/Cadyfile and it works. This way my url matches my Laravel .env APP_URL setting.
Is is possible to have that setting pulled from a project level Caddyfile or preferably from a .env file instead of hard coded into the image?
I am using the same setup as described in #100 and the request just hangs indefinitely. Any idea what I can do?
Also, but unrelated to this issue: is it possible to stop the server using ctrl+c? I always have to delete the container through Docker Desktop...
I attempted a very simple implementation of restarting a worker on a file change:
<?php
$startup = hash_file('crc32', __FILE__);
do {
$running = frankenphp_handle_request(function (): void {
echo "hi!!";
var_dump(hash_file('crc32', __FILE__));
});
if (hash_file('crc32', __FILE__) !== $startup) {
error_log('rebooting');
die();
}
} while ($running);
This causes a panic in frankenphp:
{"level":"info","ts":1666099933.9751377,"msg":"rebooting","syslog_level":"notice"}
{"level":"info","ts":1666099933.9752717,"logger":"http.log.access","msg":"handled request","request":{"remote_ip":"172.17.0.1","remote_port":"47406","proto":"HTTP/2.0","method":"GET","host":"localhost","uri":"/","headers":{"User-Agent":["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.47"],"Sec-Fetch-Dest":["document"],"Cache-Control":["max-age=0"],"Sec-Ch-Ua-Mobile":["?0"],"Upgrade-Insecure-Requests":["1"],"Accept-Encoding":["gzip, deflate, br"],"Accept-Language":["en-US,en;q=0.9"],"Sec-Ch-Ua-Platform":["\"Windows\""],"Dnt":["1"],"Sec-Fetch-Mode":["navigate"],"Sec-Fetch-User":["?1"],"Sec-Ch-Ua":["\"Chromium\";v=\"106\", \"Microsoft Edge\";v=\"106\", \"Not;A=Brand\";v=\"99\""],"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"],"Sec-Fetch-Site":["none"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"localhost"}},"user_id":"","duration":0.000535418,"size":24,"status":200,"resp_headers":{"Content-Type":["text/html; charset=UTF-8"],"Server":["Caddy"],"Alt-Svc":["h3=\":443\"; ma=2592000"],"X-Powered-By":["PHP/8.2.0-dev"]}}
{"level":"error","ts":1666099933.975745,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1666099933.9771106,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
panic: sync: negative WaitGroup counter
goroutine 117 [running, locked to thread]:
sync.(*WaitGroup).Add(0x48cf46?, 0x1e3ad80?)
/usr/local/go/src/sync/waitgroup.go:83 +0xda
sync.(*WaitGroup).Done(...)
/usr/local/go/src/sync/waitgroup.go:108
github.com/dunglas/frankenphp.go_frankenphp_worker_ready(...)
/go/src/app/worker.go:111
github.com/dunglas/frankenphp._Cfunc_frankenphp_execute_script(0x76b43c08dec0)
_cgo_gotypes.go:769 +0x48
github.com/dunglas/frankenphp.go_execute_script(0xc0000e8301?)
/go/src/app/frankenphp.go:385 +0x237
Installing a php8.2-{extension} and moving the .so
into /usr/local/lib/php/extensions/no-debug-zts-20220829
will end up with a core_symbols
error.
Hi, I use the FrankenPHP demo with the worker mode. If we modify a Twig template (with the dev env), docker has to be restarted, so the changes are taken in account. Is it a limitation of the worker mode?
And even if we clear the cache manually, we still have to restart FrankenPHP so see the new changes.
Wordpress REST API seems to fail because cURL times out after 10 seconds.
I noticed some comments that timeouts are broken because FrankenPHP uses ZTS? (probably for performance reasons?
)
I tried editing the Caddyfile main block and adding a timeouts
directive in the frankenphp block but it doesn't seem to affect the error.
Can someone point me in a solvable direction?
It would be nice to have the PG driver in the default docker image.
We currently build docker images in each PR but don't use them. We can, however, use those images and example repos like dunglas/frankenphp-drupal, dunglas/frankenphp-wordpress, etc. to spin up integration tests with "real world" code and verify (at least) a lack of seg-fault. The idea is to run it manually before merging (I imagine these tests will take a while to run).
Perhaps we can use something like dapr/mechanical-markdown to script it?
Run a different port is very convenient for development as it does not require to run with sudo and does not conflict with existing server.
However running the following does not up so well:
docker run -v $PWD:/app/public \
-p 8080:80 -p 443:443 \
dunglas/frankenphp
shoud allow to open a browser and read the app from http://localhost:8080
.
However we get redirected to https://localhost
.
It looks like we have a flaky test @withinboredom:
=== RUN TestConnectionAbortFinish_module
frankenphp_test.go:505:
Error Trace: /go/src/app/frankenphp_test.go:505
/go/src/app/frankenphp_test.go:80
/go/src/app/asm_amd64.s:1594
Error: Should be true
Test: TestConnectionAbortFinish_module
https://github.com/dunglas/frankenphp/actions/runs/3480116840/jobs/5819499909#step:5:4347
I also (rarely) get this error locally.
While doing some load testing and comparing frankenphp to apache and fpm, I noticed that a single gc cycle from golang can screw up everything.
Here's apache:
Here's fpm:
And here's frankenphp:
and the average graph to show the gc:
This is mostly to document this behavior and if benchmarking is desired, take note to tune two environment variables:
GOGC
: "a parameter that picks a point in the GC CPU and memory trade-off. The key takeaway is that doubling GOGC will double heap memory overheads and roughly halve GC CPU cost, and vice versa." A value of 512
will get you approx 2-3 minutes @ 200 rps before running into 2-3s stop-the-world gc pauses. If you're doing benchmarks, and not considering memory usage, setting it "off" might be worth considering, with a noted caveat that "memory/gc tuning will be required to achieve these values long-term."GOMEMLIMIT
: the maximum amount of memory to use. Due to the overhead of caddy, Go VM, and frankenphp, it should be larger than the PHP memory limit.Setting GOGC=off GOMEMLIMIT=4096
gives me nearly 8 minutes at full load before a GC pause. Take note that this is mostly an issue when load testing specifically. During normal usage, it is unlikely for every single thread to be in use and Go will coordinate these threads to perform a GC. When under load, there is no choice but to affect every request. In the "real world" if every server is running at 100%, there are bigger problems to worry about, so please ensure to remove these pauses from your benchmark to reflect real-world maximums in a perfectly tuned or bursty environment.
See this guide for more information about how these parameters work.
Currently this project is compatible with Linux and macOS (and likely with other UNIXes such as FreeBSD), but it hasn't been tested on Windows.
It would be nice to make it compatible for Windows and provide some binaries for this platform.
Minimal code to reproduce:
<?php
do {
$running = false;
//$running = frankenphp_handle_request(function (): void {
$fiber = new Fiber(function() {
echo "Starting Fiber\n";
});
$fiber->start();
//});
} while ($running);
With some slight modifications, it can also be reproduced in worker mode.
Probably related to #85.
Take the following code:
<?php
do {
$running = frankenphp_handle_request(
function () {
global $global;
echo $global ?? 'no global';
$global = 'global';
}
);
} while ($running);
After a worker does the first request, "global"
will be output instead of "no global"
which I (personally) wasn't expecting. Is this expected? I was under the expectation that super-globals are always reset (at least that is what it looks like is going on in the docs).
When PHP is compiled with the --enable-debug
flag, a potential memory leak is reported in worker mode when running the tests:
go test -v
[Fri Oct 21 08:21:09 2022] Script: '-'
/Users/dunglas/workspace/php-src/Zend/zend_hash.c(279) : Freeing 0x000000012aa5e000 (56 bytes), script=-
Last leak repeated 3 times
=== Total 4 memory leaks detected ===
I tried to track the potential leak with Valgrind but didn't find anything obvious yet.
Hello @dunglas,
Tried to install gd extension on FrankenPHP:
FROM dunglas/frankenphp:latest
# FROM dunglas/frankenphp:latest-alpine
# FROM php:8.2-apache
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions gd
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
COPY . /app
RUN composer install
It fails:
#0 277.0 /tmp/pear/temp/pecl_http/src/php_http_curl.c:28:13: fatal error: gcrypt.h: No such file or directory
It fails also with frankenphp:latest-alpine
:
php_http_client_response.lo -fPIC -DPIC -o src/.libs/php_http_client_response.o
#0 277.0 /tmp/pear/temp/pecl_http/src/php_http_curl.c:28:13: fatal error: gcrypt.h: No such file or directory
#0 277.0 28 | # include <gcrypt.h>
#0 277.0 | ^~~~~~~~~~
#0 277.0 compilation terminated.
#0 277.0 make: *** [Makefile:257: src/php_http_curl.lo] Error 1
#0 277.0 make: *** Waiting for unfinished jobs....
#0 278.5 ERROR: `make -j16' failed
I thought it was related to install-php-extensions
script but as it's working properly with php:8.2-apache
, I guess it's somewhat related to FrankenPHP specificity. My guess is that the script is not FrankenPHP ready and there are some differences to investigate?
Thank you
When I try to launch a Symfony project in worker mode without installing the runtime/frankenphp-symfony
library, I have this line in a loop into the log
{"level":"error","ts":1668116008.9931438,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
To reproduce:
symfony new --full test
cd test
docker run --rm -e FRANKENPHP_CONFIG="worker ./public/index.php" -e APP_RUNTIME=Runtime\\FrankenPhpSymfony\\Runtime -p 80:80 -p 443:443 -v $(pwd):/app dunglas/frankenphp
To solve:
symfony composer req runtime/frankenphp-symfony
Hello,
It seems that Docker image is quite heavy (around 700MB).
I looked at the Dockerfile
(https://github.com/dunglas/frankenphp/blob/main/Dockerfile) and it seems that $PHPIZE_DEPS
are never removed where as in think they are not needed after PHP and go compilation ?
I built the image removing these deps for testing but I have a problem with composer (I'll fill an issue about that too!)
++
I've noticed that if a worker dies due to OOM (due to a memory leak, for example), it should be possible to send the request to another thread. I think this should only happen for GET requests. Is this a good idea?
For https://memcached.org/ servers or proxies
This may be out of scope.
Memcached is heavily used in some web applications for caching state or the results of expensive operations (db queries, results of reading data from web services, etc)
If there are hundreds of workers, it'd reduce cpu and memory resource usage and syscalls if they shared a small finite number of memcache connections (pool)
(unless there are ~32+ cpu cores, 1 connection may suffice)
Both golang and php could use the same client, allowing moving method implementations to/from golang (e.g. check a json array for a value, add a value)
-m $MBUF_SIZE
if this is configured to connect to a twemproxy proxyIt would be extremely useful to have compatibility with the memcached flags
int used to indicate the chosen serializer https://github.com/php-memcached-dev/php-memcached/ (source of http://pecl.php.net/memcached )
The memcached client this uses is based on https://github.com/bradfitz/gomemcache
- This rewrites parts of it and adds pipelining support to that library.
Use existing memcached or memcache PECL normally
Hi everyone, I have an error when building the dockerfile.
=> ERROR [12/15] RUN cd caddy/frankenphp && go build && cp frankenphp /usr/local/bin && cp /go/src/app/caddy/frankenphp/Caddyfile /etc/Caddyfile && rm -Rf /go 49.1s
------
> [12/15] RUN cd caddy/frankenphp && go build && cp frankenphp /usr/local/bin && cp /go/src/app/caddy/frankenphp/Caddyfile /etc/Caddyfile && rm -Rf /go:
#16 0.212 go: downloading github.com/dunglas/mercure/caddy v0.14.1
#16 0.213 go: downloading github.com/caddyserver/caddy/v2 v2.6.1
#16 0.213 go: downloading github.com/dunglas/vulcain/caddy v0.0.0-20220906084821-705c1113298e
#16 0.327 go: downloading github.com/dunglas/mercure v0.14.1
#16 0.348 go: downloading github.com/dunglas/vulcain v0.4.0
#16 0.489 go: downloading go.uber.org/zap v1.23.0
#16 0.520 go: downloading github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b
#16 0.611 go: downloading github.com/caddyserver/certmagic v0.17.1
#16 0.645 go: downloading github.com/spf13/cobra v1.5.0
#16 0.673 go: downloading github.com/spf13/pflag v1.0.5
#16 0.724 go: downloading github.com/google/uuid v1.3.0
#16 0.724 go: downloading github.com/lucas-clemente/quic-go v0.29.1
#16 0.747 go: downloading github.com/prometheus/client_golang v1.13.0
#16 0.862 go: downloading golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
#16 0.862 go: downloading golang.org/x/term v0.0.0-20220919170432-7a66f970e087
#16 0.891 go: downloading github.com/dustin/go-humanize v1.0.1-0.20200219035652-afde56e7acac
#16 0.892 go: downloading github.com/mholt/acmez v1.0.4
#16 0.951 go: downloading github.com/google/cel-go v0.12.5
#16 1.136 go: downloading golang.org/x/net v0.0.0-20221004154528-8021a29435af
#16 1.137 go: downloading google.golang.org/genproto v0.0.0-20220929141241-1ce7b20da813
#16 1.287 go: downloading github.com/klauspost/cpuid/v2 v2.1.1
#16 1.358 go: downloading github.com/libdns/libdns v0.2.1
#16 1.376 go: downloading github.com/miekg/dns v1.1.50
#16 1.430 go: downloading golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be
#16 1.430 go: downloading go.uber.org/atomic v1.10.0
#16 1.436 go: downloading go.uber.org/multierr v1.8.0
#16 1.462 go: downloading github.com/cpuguy83/go-md2man/v2 v2.0.2
#16 1.539 go: downloading gopkg.in/yaml.v2 v2.4.0
#16 1.670 go: downloading github.com/beorn7/perks v1.0.1
#16 1.672 go: downloading github.com/cespare/xxhash/v2 v2.1.2
#16 1.692 go: downloading github.com/golang/protobuf v1.5.2
#16 1.694 go: downloading github.com/cespare/xxhash v1.1.0
#16 1.723 go: downloading github.com/prometheus/client_model v0.2.0
#16 1.739 go: downloading github.com/prometheus/common v0.37.0
#16 1.753 go: downloading github.com/prometheus/procfs v0.8.0
#16 1.875 go: downloading google.golang.org/protobuf v1.28.1
#16 1.878 go: downloading github.com/marten-seemann/qpack v0.2.1
#16 1.910 go: downloading github.com/smallstep/certificates v0.22.1
#16 2.325 go: downloading github.com/smallstep/cli v0.22.0
#16 2.879 go: downloading github.com/smallstep/truststore v0.12.0
#16 5.272 go: downloading github.com/tailscale/tscert v0.0.0-20220316030059-54bbcb9f74e2
#16 5.308 go: downloading golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2
#16 5.526 go: downloading github.com/stoewer/go-strcase v1.2.0
#16 5.527 go: downloading github.com/antlr/antlr4/runtime/Go/antlr v1.4.10
#16 5.529 go: downloading github.com/go-chi/chi v4.1.2+incompatible
#16 5.808 go: downloading github.com/smallstep/nosql v0.4.0
#16 5.969 go: downloading gopkg.in/natefinch/lumberjack.v2 v2.0.0
#16 5.980 go: downloading github.com/dgraph-io/ristretto v0.1.0
#16 6.332 go: downloading github.com/gofrs/uuid v4.2.0+incompatible
#16 6.351 go: downloading github.com/golang-jwt/jwt/v4 v4.4.2
#16 6.516 go: downloading github.com/gorilla/handlers v1.5.1
#16 6.549 go: downloading github.com/gorilla/mux v1.8.0
#16 6.581 go: downloading github.com/hashicorp/golang-lru v0.5.4
#16 6.646 go: downloading github.com/kevburnsjr/skipfilter v0.0.1
#16 6.649 go: downloading github.com/spf13/viper v1.12.0
#16 6.650 go: downloading github.com/unrolled/secure v1.12.0
#16 6.663 go: downloading github.com/yosida95/uritemplate/v3 v3.0.2
#16 6.687 go: downloading go.etcd.io/bbolt v1.3.6
#16 6.689 go: downloading github.com/dunglas/httpsfv v0.1.1
#16 6.697 go: downloading github.com/getkin/kin-openapi v0.55.0
#16 6.747 go: downloading github.com/tidwall/gjson v1.7.5
#16 6.747 go: downloading github.com/tidwall/sjson v1.1.6
#16 7.006 go: downloading github.com/russross/blackfriday/v2 v2.1.0
#16 7.008 go: downloading github.com/matttproud/golang_protobuf_extensions v1.0.2
#16 7.010 go: downloading golang.org/x/exp v0.0.0-20220929160808-de9c53c655b9
#16 7.010 go: downloading github.com/marten-seemann/qtls-go1-19 v0.1.0
#16 7.048 go: downloading github.com/pkg/errors v0.9.1
#16 7.048 go: downloading go.step.sm/cli-utils v0.7.5
#16 7.161 go: downloading go.step.sm/crypto v0.19.0
#16 7.243 go: downloading go.step.sm/linkedca v0.18.0
#16 7.243 go: downloading google.golang.org/grpc v1.49.0
#16 7.244 go: downloading gopkg.in/square/go-jose.v2 v2.6.0
#16 7.273 go: downloading github.com/slackhq/nebula v1.6.1
#16 7.356 go: downloading github.com/klauspost/compress v1.15.11
#16 7.596 go: downloading github.com/BurntSushi/toml v1.2.0
#16 7.598 go: downloading github.com/Masterminds/sprig/v3 v3.2.2
#16 7.648 go: downloading github.com/alecthomas/chroma v0.10.0
#16 7.667 go: downloading github.com/yuin/goldmark v1.5.2
#16 7.948 go: downloading github.com/yuin/goldmark-highlighting v0.0.0-20220208100518-594be1970594
#16 7.971 go: downloading gopkg.in/yaml.v3 v3.0.1
#16 8.005 go: downloading go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.36.1
#16 8.020 go: downloading go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0
#16 8.034 go: downloading go.opentelemetry.io/otel v1.10.0
#16 8.047 go: downloading go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0
#16 8.203 go: downloading go.opentelemetry.io/otel/sdk v1.10.0
#16 8.261 go: downloading github.com/felixge/httpsnoop v1.0.3
#16 8.261 go: downloading github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145
#16 8.285 go: downloading github.com/RoaringBitmap/roaring v1.2.1
#16 8.381 go: downloading github.com/fsnotify/fsnotify v1.5.4
#16 8.413 go: downloading github.com/mitchellh/mapstructure v1.5.0
#16 8.442 go: downloading github.com/spf13/afero v1.9.2
#16 8.501 go: downloading github.com/spf13/cast v1.5.0
#16 8.525 go: downloading github.com/spf13/jwalterweatherman v1.1.0
#16 8.546 go: downloading github.com/ghodss/yaml v1.0.0
#16 8.568 go: downloading github.com/go-openapi/jsonpointer v0.19.5
#16 8.592 go: downloading github.com/tidwall/match v1.0.3
#16 8.612 go: downloading github.com/tidwall/pretty v1.1.0
#16 8.634 go: downloading github.com/urfave/cli v1.22.10
#16 8.690 go: downloading github.com/mitchellh/go-ps v1.0.0
#16 8.717 go: downloading github.com/micromdm/scep/v2 v2.1.0
#16 8.769 go: downloading go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352
#16 8.809 go: downloading github.com/chzyer/readline v1.5.1
#16 8.845 go: downloading github.com/manifoldco/promptui v0.9.0
#16 8.881 go: downloading filippo.io/edwards25519 v1.0.0
#16 8.918 go: downloading github.com/Masterminds/goutils v1.1.1
#16 8.943 go: downloading github.com/Masterminds/semver/v3 v3.1.1
#16 8.973 go: downloading github.com/huandu/xstrings v1.3.2
#16 9.001 go: downloading github.com/imdario/mergo v0.3.13
#16 9.038 go: downloading github.com/mitchellh/copystructure v1.2.0
#16 9.089 go: downloading github.com/shopspring/decimal v1.3.1
#16 9.138 go: downloading go.opentelemetry.io/otel/metric v0.32.1
#16 9.173 go: downloading go.opentelemetry.io/otel/trace v1.10.0
#16 9.300 go: downloading go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0
#16 9.359 go: downloading go.opentelemetry.io/proto/otlp v0.19.0
#16 9.709 go: downloading github.com/rs/xid v1.4.0
#16 10.06 go: downloading github.com/sirupsen/logrus v1.9.0
#16 10.20 go: downloading github.com/dgraph-io/badger v1.6.2
#16 10.48 go: downloading github.com/dgraph-io/badger/v2 v2.2007.4
#16 10.86 go: downloading github.com/go-sql-driver/mysql v1.6.0
#16 10.98 go: downloading github.com/jackc/pgx/v4 v4.17.2
#16 11.16 go: downloading github.com/golang/glog v1.0.0
#16 11.25 go: downloading github.com/subosito/gotenv v1.4.0
#16 11.29 go: downloading github.com/hashicorp/hcl v1.0.0
#16 11.50 go: downloading gopkg.in/ini.v1 v1.67.0
#16 11.62 go: downloading github.com/magiconair/properties v1.8.6
#16 11.69 go: downloading github.com/pelletier/go-toml/v2 v2.0.2
#16 12.53 go: downloading github.com/pelletier/go-toml v1.9.5
#16 12.66 go: downloading github.com/go-openapi/swag v0.19.15
#16 12.73 go: downloading github.com/go-kit/kit v0.12.0
#16 13.11 go: downloading github.com/mitchellh/reflectwalk v1.0.2
#16 13.14 go: downloading github.com/dlclark/regexp2 v1.7.0
#16 13.73 go: downloading github.com/go-logr/logr v1.2.3
#16 13.79 go: downloading github.com/cenkalti/backoff/v4 v4.1.3
#16 13.85 go: downloading github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3
#16 14.74 go: downloading github.com/grpc-ecosystem/grpc-gateway v1.16.0
#16 14.84 go: downloading github.com/go-logr/stdr v1.2.2
#16 15.37 go: downloading github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13
#16 15.42 go: downloading github.com/jackc/pgconn v1.13.0
#16 15.43 go: downloading github.com/jackc/pgio v1.0.0
#16 15.52 go: downloading github.com/jackc/pgproto3/v2 v2.3.1
#16 15.53 go: downloading github.com/jackc/pgtype v1.12.0
#16 15.53 go: downloading github.com/mailru/easyjson v0.7.7
#16 15.94 go: downloading github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
#16 15.94 go: downloading github.com/go-kit/log v0.2.1
#16 15.99 go: downloading github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96
#16 16.01 go: downloading github.com/golang/snappy v0.0.4
#16 16.01 go: downloading github.com/jackc/chunkreader/v2 v2.0.1
#16 16.02 go: downloading github.com/jackc/pgpassfile v1.0.0
#16 16.03 go: downloading github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b
#16 16.10 go: downloading github.com/josharian/intern v1.0.0
#16 16.10 go: downloading github.com/shurcooL/sanitized_anchor_name v1.0.0
#16 16.11 go: downloading github.com/mattn/go-colorable v0.1.13
#16 16.13 go: downloading github.com/go-logfmt/logfmt v0.5.1
#16 16.18 go: downloading github.com/mattn/go-isatty v0.0.16
#16 47.73 # github.com/dunglas/frankenphp
#16 47.73 In file included from /usr/local/include/php/Zend/zend.h:409,
#16 47.73 from /usr/local/include/php/main/php.h:31,
#16 47.73 from /usr/local/include/php/main/php_variables.h:21,
#16 47.73 from frankenphp.go:14,
#16 47.73 from _cgo_export.c:4:
#16 47.73 /usr/local/include/php/Zend/zend_operators.h: In function 'zend_memrchr':
#16 47.73 /usr/local/include/php/Zend/zend_operators.h:205:22: warning: implicit declaration of function 'memrchr'; did you mean 'memchr'? [-Wimplicit-function-declaration]
#16 47.73 205 | return (const void*)memrchr(s, c, n);
#16 47.73 | ^~~~~~~
#16 47.73 | memchr
#16 47.73 /usr/local/include/php/Zend/zend_operators.h:205:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
#16 47.73 205 | return (const void*)memrchr(s, c, n);
#16 47.73 | ^
#16 47.73 # github.com/dunglas/frankenphp
#16 47.73 In file included from /usr/local/include/php/Zend/zend.h:409,
#16 47.73 from /usr/local/include/php/main/php.h:31,
#16 47.73 from /usr/local/include/php/main/php_variables.h:21,
#16 47.73 from ../../frankenphp.go:14:
#16 47.73 /usr/local/include/php/Zend/zend_operators.h: In function 'zend_memrchr':
#16 47.73 /usr/local/include/php/Zend/zend_operators.h:205:22: warning: implicit declaration of function 'memrchr'; did you mean 'memchr'? [-Wimplicit-function-declaration]
#16 47.73 205 | return (const void*)memrchr(s, c, n);
#16 47.73 | ^~~~~~~
#16 47.73 | memchr
#16 47.73 /usr/local/include/php/Zend/zend_operators.h:205:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
#16 47.73 205 | return (const void*)memrchr(s, c, n);
#16 47.73 | ^
#16 47.73 # github.com/dunglas/frankenphp
#16 47.73 In file included from /usr/local/include/php/Zend/zend.h:409,
#16 47.73 from /usr/local/include/php/main/php.h:31,
#16 47.73 from frankenphp.c:5:
#16 47.73 /usr/local/include/php/Zend/zend_operators.h: In function 'zend_memrchr':
#16 47.73 /usr/local/include/php/Zend/zend_operators.h:205:22: warning: implicit declaration of function 'memrchr'; did you mean 'memchr'? [-Wimplicit-function-declaration]
#16 47.73 205 | return (const void*)memrchr(s, c, n);
#16 47.73 | ^~~~~~~
#16 47.73 | memchr
#16 47.73 /usr/local/include/php/Zend/zend_operators.h:205:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
#16 47.73 205 | return (const void*)memrchr(s, c, n);
#16 47.73 | ^
#16 47.73 frankenphp.c: At top level:
#16 47.73 frankenphp.c:16:10: fatal error: C-Thread-Pool/thpool.h: No such file or directory
#16 47.73 16 | #include "C-Thread-Pool/thpool.h"
#16 47.73 | ^~~~~~~~~~~~~~~~~~~~~~~~
#16 47.73 compilation terminated.
------
executor failed running [/bin/sh -c cd caddy/frankenphp && go build && cp frankenphp /usr/local/bin && cp /go/src/app/caddy/frankenphp/Caddyfile /etc/Caddyfile && rm -Rf /go]: exit code: 2
PHP file
// public/worker.php
<?php
do {
$running = frankenphp_handle_request(
function () {
echo "hello world";
}
);
} while ($running);
Then:
docker run --rm -e FRANKENPHP_CONFIG="worker ./public/worker.php" -p 80:80 -p 443:443 -v $(pwd):/app -w /app dunglas/frankenphp
When I curl localhost, it just hangs forever. @dunglas, can you reproduce this or am I doing something wrong?
Currently, in worker mode, FrankenPHP automatically catches exceptions: https://github.com/dunglas/frankenphp/blob/main/frankenphp.c#L187-L196
Exceptions would be better handled in userland. This would simplify Franken's PHP code and make its behavior more predictable. AFAIK, other runtimes with a worker mode (RoadRunner) don't automatically handle exceptions as well.
Symfony never throws in worker mode: symfony/symfony#45997
WDYT @Nyholm, as you have a good experience of what is expected in these cases?
This is probably on PHPStorm, but it fails to do remote step debugging because $_SERVER['SERVER_PORT']
is unset.
From looking at the code around https://github.com/dunglas/frankenphp/blob/main/cgi.go#L126, it looks like it should be set, but a simple var_dump($_SERVER)
shows that it is indeed, not set.
Hello,
I would like to work on e.g. an alpine package for a testing build for frankenphp. But this requires a version number for frankenphp.
Edit:
/usr/src/app $ frankenphp version
v2.6.2 h1:wKoFIxpmOJLGl3QXoo6PNbYvGW4xLEgo32GPBEjWL8o=
This looks like the caddy version https://github.com/caddyserver/caddy/releases/tag/v2.6.2 . Can I use this? Or will there be specific git tags on frankenphp available?
Best regards
Can this run WordPress also or is it targeting custom symphony applications only?
Example code:
<?php
echo "hello";
flush();
sleep(2);
echo "world";
Frankenphp should send hello
, then 2 seconds later send world
. However, we end up with no response sent for 2 seconds, then helloworld
sent all in one go.
We can use GoReleaser to build both and also provide .deb, .rpm, etc: https://goreleaser.com/cookbooks/cgo-and-crosscompiling/
WDYT @withinboredom @back-2-95?
I'm trying to use a bigger Symfony application in worker mode. If the caches are warm, it generally works as long as no session is used.
If I visit actions containing e.g. flash message
<div class="flashbags container">
{% for type, messages in app.flashes %}
...
{% endfor %}
</div>
I get this:
<b>Fatal error</b>: Uncaught RuntimeException: Failed to start the session. in /app/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php:186
Stack trace:
#0 /app/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php(352): Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->start()
#1 /app/vendor/symfony/http-foundation/Session/Session.php(261): Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->getBag('flashes')
#2 /app/vendor/symfony/http-foundation/Session/Session.php(273): Symfony\Component\HttpFoundation\Session\Session->getBag('flashes')
#3 /app/vendor/symfony/twig-bridge/AppVariable.php(177): Symfony\Component\HttpFoundation\Session\Session->getFlashBag()
Hi,
Thank you very much for the amazing work done. I really wanted to use Nginx Unit but lack of gzip compression prevents me from using it. I have no complaint with Caddy as it supports all the features I need. Now I can use FrankenPHP to enjoy faster performance like Nginx unit because of vertical integration with PHP without missing the features and ease of Caddy.
I am using Caddy compiled with Cloudflare DNS Module right now with PHP-FPM. I am not using Docker. How do I use this without docker? Will there be any performance improvement for wordpress websites? I understand they won't run in worker mode and only benefit I'll get is easy integration here. Please let me know. Thanks again!
Hello,
A bit new here, but I am wondering if Frankenphp can be embedded inside another Go app that is being developed to have its own PHP server running as well?
Thanks
I kicked off a new build in GitHub Actions to pick up 8.2.3 which contains security fixes.
max_input_time
and max_execution_time
are currently disable as they conflict with ZTS.
PHP will need to be improved if we want to support these options: https://externals.io/message/118859
Posted from SymfonyCon ๐
I was trying to make a local run for my project https://github.com/florentdestremau/symfonycon-turbo and by following the docs, it doesn't work ๐ฌ It goes into an infinite log as seen below. I ended up cancelling the command with ctrl + C
, and even then I had to cancel twice.
โ symfonycon git:(main) docker run \
-e FRANKENPHP_CONFIG="worker ./public/index.php" \
-v $PWD:/app \
-p 80:80 -p 443:443 \
dunglas/frankenphp
{"level":"info","ts":1668702639.1660728,"msg":"using provided configuration","config_file":"/etc/Caddyfile","config_adapter":""}
{"level":"warn","ts":1668702639.1691551,"msg":"Caddyfile input is not formatted; run the 'caddy fmt' command to fix inconsistencies","adapter":"caddyfile","file":"/etc/Caddyfile","line":3}
{"level":"info","ts":1668702639.1704738,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1668702639.1707454,"logger":"http","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
{"level":"info","ts":1668702639.1707623,"logger":"http","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1668702639.1708112,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000710cb0"}
{"level":"error","ts":1668702639.4052052,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702639.4088736,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702639.409998,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702639.411147,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702639.6226852,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702639.6318924,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702639.63311,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702639.6401458,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702639.8418236,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702639.854498,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702639.8559601,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702639.8625023,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
^C{"level":"info","ts":1668702640.0067117,"msg":"shutting down","signal":"SIGINT"}
{"level":"warn","ts":1668702640.007078,"msg":"exiting; byeee!! ๐","signal":"SIGINT"}
{"level":"error","ts":1668702640.0708613,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702640.0882797,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702640.0896192,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
{"level":"error","ts":1668702640.094384,"msg":"unexpected termination, restarting","worker":"/app/public/index.php"}
^C{"level":"warn","ts":1668702640.2882946,"msg":"force quit","signal":"SIGINT"}
Create an index.php file with the following
<php
echo "Hey!";
?>
Start the docker and open the webrowser at https://localhost
, accept "the risk".
The following message occurs:
Warning: Unknown: Failed to open stream: No such file or directory in Unknown on line 0
Fatal error: Failed opening required '/app/public/index.php' (include_path='.:/usr/local/lib/php') in Unknown on line 0
fastcgi_finish_request
is often used to perform operations after a request is completed (such as sending an email). Should FrankenPHP implement this and/or create a similar function? There are pro/cons to implementing it with the same name (it will "just work" with existing code), and a con would be that if there are any differences in behavior, then things may not work as expected or code may use the existence of that function as a sentinel that it is running in a fastcgi context and do unexpected things.
I'd be happy to tackle implementing this, whatever is decided.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.