Run ThinkPHP8 with FrankenPHP and Docker in Minutes

This guide shows how to install ThinkPHP8, create a controller, configure a Caddyfile for FrankenPHP, launch the Docker container, and test the application, providing all commands and code snippets needed for a fast backend setup.

Open Source Tech Hub
Open Source Tech Hub
Open Source Tech Hub
Run ThinkPHP8 with FrankenPHP and Docker in Minutes

What is FrankenPHP

FrankenPHP is a high‑performance PHP runtime built on the Caddy web server, essentially combining a PHP interpreter with Caddy.

Quick Start

Install ThinkPHP8 via Composer, create a controller (IndexController.php) with example methods, and note that the project directory name can be changed.

composer create-project topthink/think ThinkPHP8
<?php
/**
 * @desc FrankenPHP Index
 * @author Tinywan(ShaoBo Wan)
 */
declare(strict_types=1);

namespace app\controller;

use app\BaseController;
use think\Response;

class Index extends BaseController {
    public function index(): string {
        return 'FrankenPHP 开源技术小栈! ThinkPHP8';
    }

    public function test(): Response {
        return json(['name' => '开源技术小栈']);
    }

    public function hello($name = "FrankenPHP"): string {
        return "hello," . $name;
    }
}

Configure Caddy

Create a Caddyfile in the project root, set the web root to /app/public, enable compression, configure the built‑in php_server directive, pass PATH_INFO, and add a rewrite rule to hide index.php. Also configure logging.

:80 {
    # website root (maps to /app/public inside the container)
    root * /app/public

    # enable response compression
    encode zstd br gzip

    # PHP service configuration (FrankenPHP built‑in directive)
    php_server {
        env PATH_INFO {http.matchers.file.remainder}
        try_files {path} index.php/{path}
    }

    # logging configuration
    log {
        output file /app/runtime/log/caddy.log
        level DEBUG
    }
}

Start Container

Run the FrankenPHP Docker image, mounting the ThinkPHP8 source and the Caddyfile, and map host port 8089 to container port 80 (adjust if port 80 is already in use).

docker run \
  --name tinywan-frankenphp \
  -v d:/dnmp/www/frankenphp/ThinkPHP8:/app \
  -v d:/dnmp/www/frankenphp/ThinkPHP8/Caddyfile:/etc/frankenphp/Caddyfile \
  -p 8089:80 \
  dunglas/frankenphp:1.11.3-php8.4

Local code path: d:/dnmp/www/frankenphp/ThinkPHP8 (Caddy serves /app/public as the root).

If host port 80 is occupied, the container maps it to 8089.

Docker image dunglas/frankenphp:1.11.3-php8.4 is recommended; newer 8.5 may cause errors.

Test Access

Open http://127.0.0.1:8089/ to see the default message "FrankenPHP 开源技术小栈! ThinkPHP8".

Visit http://127.0.0.1:8089/index/hello?name=Tinywan to receive the personalized greeting "hello,Tinywan".

backendDockerPHPCaddyFrankenPHPThinkPHP8
Open Source Tech Hub
Written by

Open Source Tech Hub

Sharing cutting-edge internet technologies and practical AI resources.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.