Files
puppet-frankenphp/README.md
2025-10-28 14:35:40 +01:00

4.9 KiB

Puppet FrankenPHP Module

Overview

This Puppet module installs and manages FrankenPHP on Debian-based systems (Debian, Ubuntu) using the official .deb package.

It is designed for a secure, multi-tenant architecture by managing two distinct components:

  1. FrankenPHP (Proxy): A main Caddy/FrankenPHP service, installed via .deb and managed by systemd, which acts as a reverse proxy.
  2. Isolated Applications: Individual PHP applications, each running in its own frankenphp process under a dedicated system user. These processes are managed by Supervisor for process and user isolation.

Prerequisites

This module has external dependencies (see metadata.json):

  • puppetlabs/concat: Used to assemble the main Caddyfile from fragments.
  • puppetlabs/stdlib: For data types (Stdlib::Absolutepath).
  • ajcrowe/supervisord: Used to manage the isolated application processes.

You must ensure that Supervisor is installed on the target node. This module only manages configurations for Supervisor, not its installation.

# In your base profile or site.pp
include 'supervisor'

Usage

The architecture is deployed in two steps for each website:

  1. Declare the isolated application (frankenphp::app).
  2. Declare the public-facing vhost that points to it (frankenphp::vhost).

1. Base Installation

Simply include the main class. This installs the FrankenPHP binary and configures the proxy service (which is empty by default).

include 'frankenphp'

2. Defining an Isolated Application (frankenphp::app)

This defined type creates a dedicated user, a root directory, a specific Caddyfile for the app, and a Supervisor service to run it on a local port.

# Declare a 'blog-app' application
frankenphp::app { 'blog-app':
  ensure      => present,
  root_dir    => '/var/www/blog',
  user        => 'bloguser',
  listen_port => '9010', # Ensure this port is free
}

This code will:

  • Create the bloguser user.
  • Create the /var/www/blog directory (owned by bloguser).
  • Create a Caddyfile for this app (listening on localhost:9010).
  • Create the /etc/supervisor/conf.d/frankenphp-blog-app.conf file to launch this process as the bloguser.

3. Exposing the Application (frankenphp::vhost)

This adds an entry to the main proxy Caddyfile to route public traffic to the isolated application.

# Create the public vhost for blog.example.com
frankenphp::vhost { 'blog.example.com':
  ensure       => present,
  mode         => 'proxy',
  proxy_target => 'localhost:9010', # Must match the app's listen_port
  extra_config => @(EOT)
    # Caddy will handle HTTPS automatically.
    # We add the Host header for the proxy.
    header_up Host {host}
  EOT
  ,
  # Ensure the proxy isn't defined until the app is managed
  require      => Frankenphp::App['blog-app'],
}

Classes and Defines

Class: frankenphp

The main class that orchestrates installation (frankenphp::install), proxy configuration (frankenphp::config), and the main service (frankenphp::service).

Parameters:

  • version (String): The FrankenPHP version to download (e.g., '1.9.1').
  • service_ensure (String): The state of the main service (default: 'running').
  • service_enable (Boolean): Enable the main service on boot (default: true).

Define: frankenphp::app

Manages a single isolated PHP application.

Parameters:

  • root_dir (Stdlib::Absolutepath): The application's document root.
  • user (String): The username to create for this application.
  • listen_port (String): The local port the application will listen on (e.g., '9010').
  • group (String): The group for the user (default: $user).
  • ensure (Enum['present', 'absent']): Whether the application should exist (default: 'present').

Define: frankenphp::vhost

Manages an entry (a "site") in the main proxy Caddyfile.

Parameters:

  • server_name (String): The vhost name (default: $title, e.g., 'https://www.google.com/url?sa=E&source=gmail&q=blog.example.com').
  • mode (Enum['proxy', 'fastcgi', 'php_server']): How Caddy should handle this vhost. For this architecture, always use 'proxy'.
  • proxy_target (Optional[String]): The reverse proxy target (e.g., 'localhost:9010').
  • fpm_socket (Optional[String]): (For fastcgi mode) Path to the FPM socket.
  • root_dir (Stdlib::Absolutepath): (For php_server/fastcgi modes) Document root.
  • extra_config (String): A raw string of extra Caddy directives for this vhost (for logs, headers, etc.).
  • ensure (Enum['present', 'absent']): Whether the vhost should exist (default: 'present').

Limitations

  • This module only installs FrankenPHP via the .deb package. It does not support other installation methods or operating systems.
  • The installation of the supervisor service itself is not handled. You must install it via another module or package resource.

License

Apache 2.0