Worker mode does not use updated endpoints in Kubernetes cluster
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 11.3k
- Forks
- 488
- Avg merge
- 4d 10h
- Merged PRs (30d)
- 11
Description
What happened?
Good day,
We’ve been using FrankenPHP (in non-worker mode) for quite some time on our Kubernetes cluster with great success. It’s been running smoothly and reliably.
However, when we enable worker mode, FrankenPHP does not appear to pick up updated Kubernetes endpoints, such as new pod IP from services like PostgreSQL and/or RabbitMQ. We use PostgreSQL and RabbitMQ in a HA setup, with multiple replications. For both, the Kubernetes service endpoint always referes to a single replica. Whenever this endpoint changes within the cluster (e.g. we kill the main PostgreSQL/RabbitMQ replica), service discovery becomes stale or broken, even though everything continues to work as expected in non-worker mode.
We’re unsure if this behavior stems from a bug, a misconfiguration, or a limitation by design, and would appreciate any guidance or help you can offer. Especially since worker mode offers significant performance improvements that we’d like to benefit from.
Reproducible With Docker Images:
dunglas/frankenphp:1.4.2-php8.4-alpine
dunglas/frankenphp:1.5.0-php8.3-alpine
dunglas/frankenphp:1.5.0-php8.4-alpine
dunglas/frankenphp:1.5.0-php8.3-bookworm
dunglas/frankenphp:1.5.0-php8.4-bookworm
Reproducible with the following Caddy configs:
Worker mode enabled:
{
{$CADDY_GLOBAL_OPTIONS}
frankenphp {
worker {
file ./public/index.php
num 10
env APP_RUNTIME "Runtime\FrankenPhpSymfony\Runtime"
}
}
order php_server before file_server
}
{$CADDY_EXTRA_CONFIG}
{$SERVER_NAME:localhost} {
root * public/
encode zstd br gzip
{$CADDY_SERVER_EXTRA_DIRECTIVES}
php_server
}
Worker mode disabled (this solves our issue mentioned above):
{
{$CADDY_GLOBAL_OPTIONS}
frankenphp
order php_server before file_server
}
{$CADDY_EXTRA_CONFIG}
{$SERVER_NAME:localhost} {
root * public/
encode zstd br gzip
{$CADDY_SERVER_EXTRA_DIRECTIVES}
php_server
}
PHP configuration:
expose_php = 0
date.timezone = UTC
apc.enable_cli = 1
session.use_strict_mode = 1
zend.detect_unicode = 0
display_errors = 0
opcache.preload_user = root
opcache.preload = /app/config/preload.php
realpath_cache_size = 4096K
realpath_cache_ttl = 600
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.memory_consumption = 256
opcache.enable_file_override = 1
opcache.validate_timestamps = 0
variables_order = EGPCS
Kubernetes cluster environment:
- PostgreSQL Operator: https://cloudnative-pg.io/
- RabbitMQ Operator: https://www.rabbitmq.com/kubernetes/operator/using-operator/
PostgreSQL deployment:
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: db-cluster
spec:
instances: 3
storage:
storageClass: longhorn-static
size: 10Gi
walStorage:
storageClass: longhorn-static
size: 5Gi
RabbitMQ deployment:
apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
name: rabbitmq
labels:
app.kubernetes.io/instance: rabbitmq
spec:
replicas: 3
persistence:
storageClassName: longhorn-static
storage: 20Gi
service:
type: LoadBalancer
resources:
requests:
memory: 2Gi
limits:
memory: 2Gi
Application Environment Config
We use a ConfigMap to inject application-level environment variables:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-configmap
data:
APP_ENV: dev
APP_ENVIRONMENT: development
LOCK_DSN: semaphore
CORS_ALLOW_ORIGIN: '^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
DATABASE_HOST: db-cluster-rw
DATABASE_RO_HOST: db-cluster-ro
RABBITMQ_HOST: rabbitmq
[...]
These values are correctly visible within the pod via printenv, for example:
DATABASE_HOST=db-cluster-rw
DATABASE_RO_HOST=db-cluster-ro
RABBITMQ_HOST=rabbitmq
Network Resolution
DNS resolution seems to work fine even from within the pod:
/app # ping db-cluster-rw
PING db-cluster-rw (10.96.240.237): 56 data bytes
This refers to a standard Kubernetes service endpoint.
Expected Behavior
In worker mode, we expect the application to properly recognize updated service endpoints (e.g., whenever we kill/delete a replica and a service/endpoint IP changes) in line with what works in non-worker mode. Currently, these endpoint changes are not being picked up, and simple result in:
An exception occurred while executing a query: SQLSTATE[HY000]: General error: 7 no connection to the server
The issue remains unresolved until the FrankenPHP pod is killed or restarted.
Request for help
Could you confirm whether this is:
- A bug in FrankenPHP worker mode
- A configuration mistake on our side
- A known limitation (and if so, is there a recommended workaround?)
We’re happy to test any patches, experimental flags, or configuration tweaks that might help isolate or resolve this issue.
Thanks in advance for your support and for the amazing work on FrankenPHP!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the failure with one of the listed FrankenPHP Docker images and compare the supplied worker and non-worker Caddy configurations. Investigate whether Kubernetes service resolution or database and RabbitMQ connections remain stale in worker mode; done means endpoint changes recover without restarting the FrankenPHP pod, or the limitation and workaround are documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes, php, postgresql, rabbitmq
- Domain
- backend, databases, devops, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100