Closed laurent-bientz closed 1 month ago
Try to add the github.com/dunglas/caddy-cbrotli Caddy module. The final error looks related to this missing module.
Also, latest dev version of Souin fixed issues related to cgo IIRC, you may need to use the dev version of Souin.
Thank you @dunglas, if I had caddy-cbrotli
, I am able to build with souin
:
FROM dunglas/frankenphp:latest-builder AS builder
COPY --from=caddy:builder /usr/bin/xcaddy /usr/bin/xcaddy
ENV CGO_ENABLED=1 XCADDY_SETCAP=1 XCADDY_GO_BUILD_FLAGS="-ldflags \"-w -s -extldflags '-Wl,-z,stack-size=0x80000'\""
RUN xcaddy build \
--output /usr/local/bin/frankenphp \
--with github.com/dunglas/frankenphp=./ \
--with github.com/dunglas/frankenphp/caddy=./caddy/ \
--with github.com/dunglas/mercure/caddy \
--with github.com/dunglas/vulcain/caddy \
--with github.com/dunglas/caddy-cbrotli \
--with github.com/darkweak/souin
FROM dunglas/frankenphp:latest AS frankenphp_upstream
COPY --from=builder --link /usr/local/bin/frankenphp /usr/local/bin/frankenphp
However when trying to apply the suggested Caddyfile directive:
{
{$CADDY_GLOBAL_OPTIONS}
order cache before rewrite
cache {
api {
souin
}
}
frankenphp {
{$FRANKENPHP_CONFIG}
}
# https://caddyserver.com/docs/caddyfile/directives#sorting-algorithm
order mercure after encode
order vulcain after reverse_proxy
order php_server before file_server
}
{$CADDY_EXTRA_CONFIG}
[...]
I can't run the container with the following error:
2024/08/16 16:04:43.609 INFO using config from file {"file": "/etc/caddy/Caddyfile"}
2024-08-16 18:04:43 Error: adapting config using caddyfile: parsing caddyfile tokens for 'order': cache is not a registered directive, at /etc/caddy/Caddyfile:4
It looks like the Souin Caddy module is missing in the list (only Souin the library is there).
Hello @dunglas, I'm not sure to understand, I just followed the documentation (and added the missing caddy-cbrotli
as you suggested):
RUN xcaddy build \
--output /usr/local/bin/frankenphp \
--with github.com/dunglas/frankenphp=./ \
--with github.com/dunglas/frankenphp/caddy=./caddy/ \
--with github.com/dunglas/mercure/caddy \
--with github.com/dunglas/vulcain/caddy \
--with github.com/dunglas/caddy-cbrotli \
--with github.com/darkweak/souin
Do we've to add another module in addition to darkweak/souin
? If yes which one? Is it github.com/darkweak/souin/plugins/caddy
?
If I try to add this one, I can't build:
52.94 /root/go/pkg/mod/github.com/darkweak/souin/plugins/caddy@v0.0.0-20240814120347-65cb24114d76/configuration.go:238:59: cannot use (*Configuration)(nil) (value of type *Configuration) as configurationtypes.AbstractConfigurationInterface value in variable declaration: *Configuration does not implement configurationtypes.AbstractConfigurationInterface (wrong type for method GetLogger)
52.94 have GetLogger() "github.com/darkweak/storages/core".Logger
52.94 want GetLogger() *zap.Logger
52.94 /root/go/pkg/mod/github.com/darkweak/souin/plugins/caddy@v0.0.0-20240814120347-65cb24114d76/configuration.go:367:50: unknown field Found in struct literal of type configurationtypes.CacheProvider
52.94 /root/go/pkg/mod/github.com/darkweak/souin/plugins/caddy@v0.0.0-20240814120347-65cb24114d76/configuration.go:464:50: unknown field Found in struct literal of type configurationtypes.CacheProvider
52.94 /root/go/pkg/mod/github.com/darkweak/souin/plugins/caddy@v0.0.0-20240814120347-65cb24114d76/configuration.go:515:50: unknown field Found in struct literal of type configurationtypes.CacheProvider
52.94 /root/go/pkg/mod/github.com/darkweak/souin/plugins/caddy@v0.0.0-20240814120347-65cb24114d76/configuration.go:530:50: unknown field Found in struct literal of type configurationtypes.CacheProvider
52.94 /root/go/pkg/mod/github.com/darkweak/souin/plugins/caddy@v0.0.0-20240814120347-65cb24114d76/configuration.go:548:50: unknown field Found in struct literal of type configurationtypes.CacheProvider
52.94 /root/go/pkg/mod/github.com/darkweak/souin/plugins/caddy@v0.0.0-20240814120347-65cb24114d76/configuration.go:561:50: unknown field Found in struct literal of type configurationtypes.CacheProvider
52.94 /root/go/pkg/mod/github.com/darkweak/souin/plugins/caddy@v0.0.0-20240814120347-65cb24114d76/configuration.go:580:50: unknown field Found in struct literal of type configurationtypes.CacheProvider
52.94 /root/go/pkg/mod/github.com/darkweak/souin/plugins/caddy@v0.0.0-20240814120347-65cb24114d76/dispatch.go:11:41: s.Configuration.DefaultCache.Badger.Found undefined (type configurationtypes.CacheProvider has no field or method Found)
52.94 /root/go/pkg/mod/github.com/darkweak/souin/plugins/caddy@v0.0.0-20240814120347-65cb24114d76/dispatch.go:31:40: s.Configuration.DefaultCache.Badger.Uuid undefined (type configurationtypes.CacheProvider has no field or method Uuid)
52.94 /root/go/pkg/mod/github.com/darkweak/souin/plugins/caddy@v0.0.0-20240814120347-65cb24114d76/dispatch.go:31:40: too many errors
53.19 2024/08/19 08:01:18 [INFO] Cleaning up temporary folder: /tmp/buildenv_2024-08-19-0800.284806786
53.19 2024/08/19 08:01:18 [FATAL] exit status 1
------
failed to solve: process "/bin/bash -o pipefail -c xcaddy build --output /usr/local/bin/frankenphp --with github.com/dunglas/frankenphp=./ --with github.com/dunglas/frankenphp/caddy=./caddy/ --with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy \t--with github.com/dunglas/caddy-cbrotli --with github.com/darkweak/souin --with github.com/darkweak/souin/plugins/caddy" did not complete successfully: exit code: 1
I'm just trying to follow the official api platform doc.
If someone is interesting, following this comment from @darkweak and adapting the commit's hashs, I can build and run the container (note that I also have to apt-get git
:
Dockerfile
FROM dunglas/frankenphp:latest-builder AS builder
COPY --from=caddy:builder /usr/bin/xcaddy /usr/bin/xcaddy
+RUN apt-get update && apt-get install --no-install-recommends -y \
+ git
ENV CGO_ENABLED=1 XCADDY_SETCAP=1 XCADDY_GO_BUILD_FLAGS="-ldflags \"-w -s -extldflags '-Wl,-z,stack-size=0x80000'\""
RUN xcaddy build \
--output /usr/local/bin/frankenphp \
--with github.com/dunglas/frankenphp=./ \
--with github.com/dunglas/frankenphp/caddy=./caddy/ \
--with github.com/dunglas/mercure/caddy \
--with github.com/dunglas/vulcain/caddy \
- --with github.com/darkweak/souin
+ --with github.com/dunglas/caddy-cbrotli \
+ --with github.com/darkweak/souin/plugins/caddy@65cb24114d76a7de3f4e8c7b8ef7df3efd028899 \
+ --with github.com/darkweak/souin@65cb24114d76a7de3f4e8c7b8ef7df3efd028899 \
+ --with github.com/darkweak/storages/otter/caddy
FROM dunglas/frankenphp:latest AS frankenphp_upstream
COPY --from=builder --link /usr/local/bin/frankenphp /usr/local/bin/frankenphp
Caddyfile
{
{$CADDY_GLOBAL_OPTIONS}
# https://github.com/dunglas/frankenphp/issues/976
order cache before rewrite
cache {
api {
souin
}
}
frankenphp {
{$FRANKENPHP_CONFIG}
}
# https://caddyserver.com/docs/caddyfile/directives#sorting-algorithm
order mercure after encode
order vulcain after reverse_proxy
order php_server before file_server
}
{$CADDY_EXTRA_CONFIG}
api_platform.yaml
api_platform:
# ...
# Good defaults for REST APIs
defaults:
stateless: true
cache_headers:
vary: ['Content-Type', 'Authorization', 'Origin']
extra_properties:
standard_put: true
rfc_7807_compliant_errors: true
route_prefix: '/api'
event_listeners_backward_compatibility_layer: false
keep_legacy_inflector: false
# Souin cache
http_cache:
invalidation:
# We assume that your API can reach your caddy instance by the hostname http://caddy.
# The endpoint /souin-api/souin is the default path to the invalidation API.
urls: [ 'http://caddy/souin-api/souin' ]
purger: api_platform.http_cache.purger.souin
Now I'm trying to understand why I always have Cache-Control: no-cache, private
response header whereas Api Platform is stateless...
curl "https://localhost/api/sites?page=1" --compressed -H "Accept: application/ld+json" --ssl-no-revoke -v
* Host localhost:443 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:443...
* Connected to localhost (::1) port 443
* schannel: disabled automatic use of client certificate
* using HTTP/1.x
> GET /api/sites?page=1 HTTP/1.1
> Host: localhost
> User-Agent: curl/8.8.0
> Accept-Encoding: deflate, gzip, br, zstd
> Accept: application/ld+json
>
* Request completely sent off
* schannel: remote party requests renegotiation
* schannel: renegotiating SSL/TLS connection
* schannel: SSL/TLS connection renegotiated
< HTTP/1.1 200 OK
< Alt-Svc: h3=":443"; ma=2592000
< Cache-Control: no-cache, private
< Content-Encoding: zstd
< Content-Type: application/ld+json; charset=utf-8
< Date: Mon, 19 Aug 2024 08:59:56 GMT
< Etag: "b46cc82355655abca41ce1f2cdc070f1-zstd"
< Link: <https://localhost/docs.jsonld>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation"
< Permissions-Policy: browsing-topics=()
< Server: Caddy
< Vary: Accept
< Vary: Content-Type
< Vary: Authorization
< Vary: Origin
< Vary: Accept-Encoding
< X-Content-Type-Options: nosniff
< X-Debug-Token: 1855ee
< X-Debug-Token-Link: https://localhost/_profiler/1855ee
< X-Frame-Options: deny
< X-Robots-Tag: noindex
< Transfer-Encoding: chunked
Thank you very much @laurent-bientz! Would you mind updating API Platform docs with these changes?
Thank you very much @laurent-bientz! Would you mind updating API Platform docs with these changes?
I will @dunglas, I'm just trying to have a "cache hit" to ensure everything is working well before updating the doc.
Do you know why I got Cache-Control: no-cache, private
on every requests whereas api_platform is stateless
and it's a public api (no session, cookie, jwt, nor authorization)?
Are you in prod mode? IIRC Symfony always sets this header in dev mode.
Also, you need to explicitly set the public
Cache-Control directive (this can be done using the config).
Thanks @dunglas for your time, yes I was in dev mode and not having public: true
in api_platform http_cache
configuration!
Enabling prod mode + public
Cache-Control worked:
λ curl "https://localhost/api/sites/2" --compressed -H "Accept: application/ld+json" --ssl-no-revoke -v
* Host localhost:443 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:443...
* Connected to localhost (::1) port 443
* schannel: disabled automatic use of client certificate
* using HTTP/1.x
> GET /api/sites/2 HTTP/1.1
> Host: localhost
> User-Agent: curl/8.8.0
> Accept-Encoding: deflate, gzip, br, zstd
> Accept: application/ld+json
>
* Request completely sent off
* schannel: remote party requests renegotiation
* schannel: renegotiating SSL/TLS connection
* schannel: SSL/TLS connection renegotiated
< HTTP/1.1 200 OK
< Accept-Patch: multipart/form-data
< Alt-Svc: h3=":443"; ma=2592000
< Cache-Control: public
< Content-Encoding: zstd
< Content-Location: /api/sites/2
< Content-Type: application/ld+json; charset=utf-8
< Date: Mon, 19 Aug 2024 15:24:25 GMT
< Etag: "75d700cecda6aee64bef38d0666e85e7-zstd"
< Link: <https://localhost/docs.jsonld>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation"
< Permissions-Policy: browsing-topics=()
< Server: Caddy
< Surrogate-Key: /api/sites/2, /api/partners/1
< Vary: Accept
< Vary: Content-Type
< Vary: Authorization
< Vary: Origin
< Vary: Accept-Encoding
< X-Content-Type-Options: nosniff
< X-Frame-Options: deny
< Content-Length: 665
I also updated API Platform docs with these changes, see https://github.com/api-platform/docs/pull/1969
Cheers.
What happened?
Hello,
I'm trying to build frankenphp with HTTP cache module in Caddy, I followed the API Platform documentation: https://api-platform.com/docs/core/performance/#built-in-caddy-http-cache
My Dockerfile:
With
souin
I can build but when I try to run the container:If I try to build with
cache-handler
instead ofsouin
, I can't even build:Build Type
Standalone binary
Worker Mode
No
Operating System
GNU/Linux
CPU Architecture
x86_64
PHP configuration
Relevant log output
No response