Response Content-Type is text/html instead of application/json when using FrankenPHP
Response Content-Type is text/html instead of application/json when using FrankenPHP
Description
When switching from lsphp to frankenphp, the Content-Type of the response changes unexpectedly. With lsphp, the response is correctly identified as application/json. However, when running the same application under frankenphp, the Content-Type is text/html, even though the response content is clearly JSON.
Using openlistespeed as base image :
Responses that serve JSON content should include the correct header:
curl -i https://domain-name.com/api/api-endpoint HTTP/2 200 date: Tue, 01 Apr 2025 06:12:12 GMT content-type: text/html; charset=UTF-8
With Frankenphp
curl -i https://domain-name.com/api/api-endpoint HTTP/1.1 200 OK Content-Type: application/json
Dockerfile - lsphp
FROM litespeedtech/openlitespeed:1.8.1-lsphp81
# Set working directory
WORKDIR /var/www/vhosts/localhost/html
# Copy Laravel project files
COPY . .
# Install dependencies
RUN apt-get update && \
apt-get install -y curl \
unzip\
libpng-dev \
libjpeg-dev \
libfreetype6-dev \
libzip-dev \
php-gd \
php-mysql \
php-zip \
php8.1-xdebug\
php8.1-curl\
php8.1-xml\
php8.1-dom\
php8.1-zip\
php8.1-mbstring\
&& apt-get clean
RUN chmod 775 -R /var/www/vhosts/localhost/html/storage
RUN mkdir -p storage/framework/cache && \
mkdir -p storage/framework/sessions && \
mkdir -p storage/framework/views && \
mkdir -p bootstrap/cache && \
chmod -R 775 storage bootstrap/cache
RUN chown -R www-data:www-data /var/www/vhosts/localhost/html/bootstrap/cache
RUN chown -R www-data:www-data /var/www/vhosts/localhost/html/storage
COPY --from=public.ecr.aws/composer/composer:latest /usr/bin/composer /usr/bin/composer
RUN composer install --no-dev --optimize-autoloader --no-interaction
EXPOSE 80
# Start OpenLiteSpeed
CMD ["/usr/local/lsws/bin/lswsctrl", "start"]
Dockerfile - Frankenphp
FROM dunglas/frankenphp:php8.2
ENV SERVER_NAME="http://"
WORKDIR /var/www/html
COPY . .
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
curl \
git \
unzip \
libpng-dev \
zlib1g-dev
RUN mkdir -p storage/framework/cache storage/framework/sessions storage/framework/views bootstrap/cache
RUN chmod -R 775 storage bootstrap/cache
RUN chown -R www-data:www-data storage bootstrap/cache
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
RUN docker-php-ext-install gd
RUN composer install
RUN composer dump-autoload
RUN install-php-extensions \
pdo_mysql
CMD ["php", "artisan", "serve", "--host=0.0.0.0", "--port=80"]
Build Type
Docker (Debian Bookworm)
Worker Mode
Yes
Operating System
GNU/Linux
CPU Architecture
x86_64
PHP configuration
variable
Relevant log output
There's not enough information to understand what's going on here since we don't know about your endpoint or how it's served. This is more than likely a configuration default difference between artisan serve and lsphp and not related to FrankenPHP at all.
Correct. Caddy/FrankenPHP defaults to text/html while lightspeed perhaps defaults to application/json. This should be specified by your application, usually (even if there are defaults).