Skip to content

Conversation

@jaydrogers
Copy link
Member

@jaydrogers jaydrogers commented Feb 8, 2024

4.0 Release: Say hello to FrankenPHP 👋

🚀 What this PR does

This PR is our home base for testing our new 4.0 release. This adds the highly anticipated variation of FrankenPHP and further optimizes serversideup/php to be highly optimized for deploying and maintaining Laravel applications.

🫵 WE NEED YOU: Help us test test this release

Important

Please keep reading the notes in this post before cowboy coding and throwing this into production 🤠

  1. This PR is in an "alpha" state and could change at anytime
  2. The images are located on a special "development" repository php-dev (not php)
  3. There are more changes than just adding FrankenPHP. Read the entire post for what's new

View Test Images on Dockerhub →

Anything tagged with 283- will reference this PR and should be tested. Notice we're testing on php-dev (not php).

serversideup/php-dev:283-*

🐛 Reporting Issues

👨‍🔬 What to test

We really need the community's help on testing these images as we progress towards stable.

1️⃣ All variations: Laravel Automations

There were huge improvements made to the 50-laravel-automations.sh script.

  1. Does the script still work after upgrading an existing FPM-NGINX image?
  2. Is the script behaving well and giving you the results you anticipate?

2️⃣ FrankenPHP: Caddyfile structure

  1. Do you like the structure of the Caddyfile?
  2. Do you find the script flexible and easy to expand?
  3. Do the performance defaults make sense and follow best practices?
  4. Do the security defaults make sense and follow best practices?
  5. Are you getting the RealIP when the container is behind a CloudFlare proxy?
  6. How is your experience with logging? Does the LOG_LEVEL_OUTPUT help you out? Are the logs too noisy?

3️⃣ Test start up scripts

We made improvements to the entrypoint script.

  1. Are you getting any weird behaivor with old scripts?
  2. Do you like how we execute things in a subshell to isolate scripts and have a more natural developer experience?

🌎 Latest Documentation

Use the link below to reference the latest documentation (it will automatically update as we keep improving the docs).
View the latest documentation →

⚡️ What's new

🧟‍♂️ FrankenPHP variations now added

The highly anticipated release of FrankenPHP is now available. These images come with many enhancements compared to the official FrankenPHP images.

Images are unprivileged by default

For best security practices, we're running things as www-data. This dramatically reduces your security footprint when running PHP in production. Because of this, we're listening on 8080 (HTTP) and 8443 (HTTPS). This follows the same design pattern as our other images.

Native health checks

Health checks are critical for ensureing zero-downtime deployments. Our images come "batteries included" with intelligent health check endpoints that can easily be customized with $HEALTHCHECK_PATH. By default, our images ensure /healthcheck is alive with Caddy, but you can change this variable to HEALTHCHECK_PATH=/up and it will use the built-in Laravel health check endpoint to ensure Laravel is actually ready to accept requests.

Extremely flexible and production-grade Caddyfile by default

The default FrankenPHP Caddyfile gives you enough to get started, but we spent a ton of time making sure that we're shipping production-grade and secure configurations by default. This includes:

  1. Native CloudFlare support with trusted IP addresses
  2. Performance and caching rules made available by default
  3. Security headers included by default
  4. Flexible and powerful logging defaults
  5. Simple and intelligent self-signed certificate generation (but still allowing you to use Let's Encrypt if you wanted)

Designed for mass-scale production deployments

It's almost unbelievable and amazing how well FrankenPHP works with Caddy as a proxy. This tight integration allows you to do magical things like deploy trusted SSLs with Let's Encrypt. The only problem is, you probably have something else serving SSL termination and you most likely would not use that feature in a single container.

Our approach is "orchestrator first", meaning the image is designed for mass-scale in mind.

This means we're shipping the image assuming that you're doing TLS termination elsewhere. This makes it easier for you to scale and perform zero-downtime deployments:

flowchart TD
    A["Reverse Proxy 
    (Not FrankenPHP)"] -->C{Container Service}
    C -->|STOP| D[MyApp:v1]
    C -->|START| E[MyApp:v2]
Loading

Flexible environment configuration

Just like the experience with our other PHP variations, we also have things like SSL_MODE, LOG_OUTPUT_LEVEL, changing PHP INI settings with environment variables, all our helper scripts for changing permissions, etc. that make it a breeze for you to customize how the PHP image behaves.

More operating system variations

We are able to compile FrankenPHP by source, which allows us to open up support for many operating systems.

How tagging works
There's more to it, but in general the primary principle is:

{php-minor-version}-{variation}-{os-version}

This means we're offering FrankenPHP with the following operating systems:

  1. trixie: Debian Trixie (13)
  2. bookworm: Debian Bookworm (12)
  3. alpine3.22: Alpine 3.22
  4. alpine3.21: Alpine 3.21

🌐 New Documentation Site

We completely rewrote our documentation site and improved the user experience dramatically. Not only did we add a ton of new documentation, we used many native Nuxt Content components to improve the experience when reading the docs.

🌎 New Environment Variables

The following environment variables are now available:

Environment Variable Default Authored By
APACHE_HTTP_PORT 8080 @jaydrogers
APACHE_HTTPS_PORT 8443 @jaydrogers
AUTORUN_DEBUG false @jaydrogers
AUTORUN_LARAVEL_OPTIMIZE true @aSeriousDeveloper
AUTORUN_LARAVEL_MIGRATION_FORCE true @jaydrogers
AUTORUN_LARAVEL_MIGRATION_MODE default @jaydrogers
AUTORUN_LARAVEL_MIGRATION_SEED false @jaydrogers
AUTORUN_LARAVEL_MIGRATION_SKIP_DB_CHECK false @jaydrogers
NGINX_ACCESS_LOG /dev/stdout @robsontenorio
NGINX_CLIENT_MAX_BODY_SIZE 100M @dlundgren
NGINX_ERROR_LOG /dev/stderr @robsontenorio
NGINX_HTTP_PORT 8080 @jaydrogers
NGINX_HTTPS_PORT 8443 @jaydrogers
NGINX_LISTEN_IP_PROTOCOL all @yuuzukatsu, @jaydrogers
PHP_FPM_PM_MAX_REQUESTS 0 @ifaridjalilov, @thueske
PHP_FPM_PM_STATUS_PATH /status @jaydrogers
PHP_MAX_INPUT_VARS 1000 @RadeJR
PHP_OPCACHE_ENABLE_FILE_OVERRIDE 0 @jaydrogers
PHP_OPCACHE_FORCE_RESTART_TIMEOUT 180 @aSeriousDeveloper, @jaydrogers
PHP_OPCACHE_JIT off @aSeriousDeveloper, @jaydrogers
PHP_OPCACHE_JIT_BUFFER_SIZE 0 @aSeriousDeveloper, @jaydrogers
PHP_OPCACHE_SAVE_COMMENTS 1 @aSeriousDeveloper, @jaydrogers
PHP_OPCACHE_VALIDATE_TIMESTAMPS 1 @aSeriousDeveloper, @jaydrogers
PHP_REALPATH_CACHE_TTL 120 @jaydrogers
PHP_ZEND_DETECT_UNICODE null @jaydrogers
PHP_ZEND_MULTIBYTE Off @jaydrogers

🤩 New Features

Laravel Automations Script Improvements

The Laravel Automations script has been completely refactored to make it easier to support advanced Laravel features. Tons of new features are now available:

"php artisan optmize" now run by default

Instead of setting AUTORUN_LARAVEL_ROUTE_CACHE, AUTORUN_LARAVEL_VIEW_CACHE etc, we use AUTORUN_LARAVEL_OPTIMIZE by default, which calls php artisan optimize. Readjusting our logic to this new structure not only simplifies our approach to follow Laravel's best practices, it allows you to hook into the optimize command if you need to use it for your own application.

If you don't want to use php artisan optimize or if you're running an older version of Laravel, no sweat! Our refactored approach is backwards compatible and you can enable/disable certain functions by just setting your desired values to AUTORUN_LARAVEL_ROUTE_CACHE, AUTORUN_LARAVEL_VIEW_CACHE etc.

Added support for "migration modes"

We now support different migration modes of refresh or fresh by Laravel. This is super helpful if you need to seed a preview environment.

Migration Mode Description
default (our default behavior) Runs php artisan migrate - standard forward migrations
fresh Runs php artisan migrate:fresh - drops all tables and re-runs migrations
refresh Runs php artisan migrate:refresh - rolls back and re-runs migrations

Specify which database connections to run migrations with

If you run multiple databases with a multi-tenant Laravel application, you may need to specify your exact database connection that you'd like to use. We created AUTORUN_LARAVEL_MIGRATION_DATABASE so you can set the configuration name of the database connection you'd like to run migrations on (ie. mysql). Supports running against multiple databases too (ie. mysql,pgsql).

Added "--seed" option to migrations

Laravel has a helpful flag of --seed that you can run with php artisan migrate that will indicate if the seed task should be re-run. If you need this, just set AUTORUN_LARAVEL_MIGRATION_SEED to true.

Easier debugging

If you're running into issues with automations, set AUTORUN_DEBUG to true and you'll get helpful output to help you figure out why you're running into issues.

Control NGINX IP listening protocols with NGINX_LISTEN_IP_PROTOCOL

Are you running an IPv6 only cluster with fpm-nginx? Now you can set NGINX_LISTEN_IP_PROTOCOL: ipv6 and NGINX will listen on IPv6 stacks only. Same thing works if you set it to ipv4, then IPv6 will be disabled.

Great for Kubernetes clusters! 🤓

Default behavior is to keep a non-breaking change of all which will listen on IPv4 and IPv6.

🧘‍♂️ Quality Of Life Improvements

Improved health checks

A brilliant PR by @aSeriousDeveloper was merged which dramatically improves our "definition of healthy", especially on container start up. This approach utilizes start-period and start-interval which will give us more accurate readings and flexibility for container start up.

Option Description Old Value New Value
start-period start period provides initialization time for containers that need time to bootstrap. Probe failure during that period will not be counted towards the maximum number of retries. However, if a health check succeeds during the start period, the container is considered started and all consecutive failures will be counted towards the maximum number of retries. - 60s
start-interval start interval is the time between health checks during the start period. - 3s
timeout If a single run of the check takes longer than timeout seconds then the check is considered to have failed. 3s 3s
retries It takes retries consecutive failures of the health check for the container to be considered unhealthy. 3 3
interval The health check will first run interval seconds after the container is started, and then again interval seconds after each previous check completes. 5s 10s

Startup and Entrypoint Scripts

  • Changed approach to executing entrypoint.d scripts so we can gracefully handle exit 0 in a entrypoint script
  • Re-designed container start up info script

Changing file permissions (docker-php-serversideup-set-file-permissions)

  • Added automated service detection (--service is now optional)
  • Added --dir parameter for specifying extra directories (you can specify multiple --dir flags for multiple directories)

Quiet health check access logs

  • Improved fpm-nginx and fpm-apache logs to never show access log output for any request$HEALTHCHECK_PATH. Things are much quieter now 😃

🐛 Bug Fixes

All images

S6-based images (fpm-nginx and fpm-apache)

fpm-nginx

fpm-apache

⏫ Dependency updates

  • Updates install-php-extensions script to v2.9.11

✅ Jay's Checklist

These are notes to myself so I can remember where I left off as I start merging more things in:

Development

  • Adds FrankenPHP be offered as a variation
  • Test LOG_LEVEL_OUTPUT
  • Convert Caddyfile to work like our fpm-nginx image
  • Allow the "autorun" scripts and other custom init scripts to run before bringing up FrankenPHP
  • Allow the PHP minor version to be selected with FrankenPHP
  • Allow the PHP_ environment variables from other Server Side Up images to work with FrankenPHP
  • Ensure set-id and set-filepermissions scripts work well
  • Ensure CloudFlare Real IPs work
  • Create native healthchecks
  • See if I can quiet the logs by default
  • Ensure FrankenPHP healthchecks are dynamic with $HEALTHCHECK_PATH

Documentation

  • Go through all pages and see if it is appropriate to update FrankenPHP
  • Add FrankenPHP on the homepage
  • Document the healthchecks for FrankenPHP

@jaydrogers jaydrogers linked an issue Feb 8, 2024 that may be closed by this pull request
@jaydrogers jaydrogers marked this pull request as draft February 8, 2024 00:01
@Sammyjo20
Copy link

This would be super cool to have! Great work on this so far!

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented May 13, 2024

Deploying serversideup-php with  Cloudflare Pages  Cloudflare Pages

Latest commit: d5898c9
Status: ✅  Deploy successful!
Preview URL: https://c34aaa1d.serversideup-php.pages.dev
Branch Preview URL: https://280-create-a-frankenphp-vari.serversideup-php.pages.dev

View logs

@GunniBusch
Copy link

This would really be a nice addition..

@thinkstylestudio
Copy link

This will be a wonderful addition!

@mihai-burduselu-ptt
Copy link

mihai-burduselu-ptt commented Aug 27, 2024

This would be a great feature! 🚀
Any updates here?

@jaydrogers
Copy link
Member Author

Not sure how I missed your message @mihai-burduselu-ptt.

I am getting v3.4 updates out the door for the last major optimizations for fpm-nginx. Then it's FrankenPHP time 😎

@hstoenescu
Copy link

This is a great addition to serversideup. Any updates regarding frankenPHP?

@hookenz
Copy link

hookenz commented Nov 18, 2024

I'd like to see FrankenPHP added too.

@jaydrogers
Copy link
Member Author

Thanks for your patience, all! I'm looking for the future of PHP and I really hope FrankenPHP is it.

I've been very busy with Spin and once I get this big release of Spin v3 out the door, then I will be swinging to this.

Exploring FrankenPHP is very important to me and I will definitely be getting this accomplished 💯

@jaydrogers
Copy link
Member Author

I am back from holiday break and will be evaluating this for v3.6. I have taken about 3 attempts at this and have paused and deleted each time 🙃🔥

My challenge is I believe I need to compile FrankenPHP from source so I can maintain the "single source of truth" from the official Docker PHP images. I need to spend more time ensuring this is the way, since I haven't compiled a Go app in my life 😅

I will keep everyone posted once I have an update but please chime in below if you have any thoughts 🙏

@thomasaull
Copy link

@jaydrogers Not sure if this is feasible? The frankenphp images are based on the official docker images and add their stuff on top, so the php images would still be the source of truth? It’s additional work to keep the build working, which is done by the frankenphp maintainers anyway. Since it’s based on official docker images, you should be able to do anything you want with the frankenphp images, don’t you?

That being said, I have no deep understanding about what you’re adding, so my opinion might be invalid 😅

@jaydrogers
Copy link
Member Author

jaydrogers commented Jan 7, 2025

Thanks for chiming in! Yes, you're totally right -- and I've tried this path. This might be a complicated for a single GitHub issue post, but here is an attempt on simpliying a few critical background parts:

  1. I use https://www.php.net/releases/active.php as my "source of truth" in get-php-versions.sh
  2. This builds a php-versions.yml file (base config is here)

If a new version of PHP is made available and FrankenPHP hasn't released that version yet, the build will fail.

This adds two layers of dependencies for all Server Side Up images (if they are FrankenPHP or not):

  1. Official PHP images must be built
  2. FrankenPHP must have images built with the EXACT patches that we're trying to use

This is where I hit my head against the wall and decided to take a break and circle back later 😃

I believe my latest theory was to use Multi-stage builds take the official build PHP image, check out a specific version of FrankenPHP, then compile it following their methods -- but I don't want to re-invent the wheel on compiling either 😅

Full build process

- name: Check out code
uses: actions/checkout@v4
- name: Prepare PHP versions for the matrix. 😎
run: |
chmod +x ./scripts/get-php-versions.sh
./scripts/get-php-versions.sh
env:
SKIP_DOWNLOAD: false
- name: Ensure our PHP Versions file exists.
run: |
if [ ! -f "${{ inputs.php-versions-file }}" ]; then
echo "PHP Versions file does not exist. Exiting."
exit 1
else
cat ${{ inputs.php-versions-file }}
fi
- name: Assemble PHP versions into the matrix. 😎
id: get-php-versions
run: |
MATRIX_JSON=$(yq -o=json scripts/conf/php-versions.yml | jq -c '{include: [(.php_variations[] | {name, supported_os: (.supported_os // ["alpine", "bullseye", "bookworm"])} ) as $variation | .php_versions[] | .minor_versions[] | .patch_versions[] as $patch | .base_os[] as $os | select($variation.supported_os | if length == 0 then . else . | index($os.name) end) | {patch_version: $patch, base_os: $os.name, php_variation: $variation.name}]} | {include: (.include | sort_by(.patch_version | split(".") | map(tonumber) | . as $nums | ($nums[0]*10000 + $nums[1]*100 + $nums[2])) | reverse)}')
echo "php-version-map-json=${MATRIX_JSON}" >> $GITHUB_OUTPUT
echo "${MATRIX_JSON}" | jq '.'
- name: Upload the php-versions.yml file
uses: actions/upload-artifact@v4
with:
name: php-versions.yml
path: ${{ inputs.php-versions-file }}
docker-publish:
needs: setup-matrix
runs-on: ubuntu-24.04
## Use AWS runners
# runs-on:
# - runs-on
# - runner=4cpu-linux-x64
# - run-id=${{ github.run_id }}
strategy:
matrix: ${{fromJson(needs.setup-matrix.outputs.php-version-map-json)}}
steps:
- name: Check out code.
uses: actions/checkout@v4
- name: Download PHP Versions file
uses: actions/download-artifact@v4
with:
name: php-versions.yml
path: ./artifacts
- name: Move PHP Versions file
run: mv ./artifacts/php-versions.yml ${{ inputs.php-versions-file }}
##
# Docker build & publish
##
- name: Login to DockerHub
uses: docker/login-action@v3
if: ${{ inputs.push-to-registry }}
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
if: ${{ inputs.push-to-registry && inputs.authenticate_with_ghcr }}
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: "📦 Assemble the Docker Tags"
run: |
chmod +x ./scripts/assemble-docker-tags.sh
./scripts/assemble-docker-tags.sh
env:
PHP_VERSIONS_FILE: "${{ inputs.php-versions-file }}"
DEFAULT_IMAGE_VARIATION: ${{ inputs.default-image-variation }}
PHP_BUILD_VERSION: ${{ matrix.patch_version }}
PHP_BUILD_VARIATION: ${{ matrix.php_variation }}
PHP_BUILD_BASE_OS: ${{ matrix.base_os }}
DOCKER_TAG_PREFIX: ${{ inputs.tag-prefix }}
DOCKER_REGISTRY_REPOSITORIES: ${{ inputs.registry-repositories }}
RELEASE_TYPE: ${{ inputs.release-type }}
GITHUB_RELEASE_TAG: ${{ github.ref_name }}
GITHUB_REF_TYPE: ${{ github.ref_type }}
- name: Set REPOSITORY_BUILD_VERSION
id: set_version
run: |
if [ "${{ github.ref_type }}" == "tag" ]; then
echo "🚀 Setting REPOSITORY_BUILD_VERSION to Tag"
echo "REPOSITORY_BUILD_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV
else
echo "👨‍🔬 Setting REPOSITORY_BUILD_VERSION to GIT Short SHA and GitHub Run ID"
SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
echo "REPOSITORY_BUILD_VERSION=git-${SHORT_SHA}-${{ github.run_id }}" >> $GITHUB_ENV
fi
- name: Build images
uses: docker/build-push-action@v6
with:
file: src/variations/${{ matrix.php_variation }}/Dockerfile
cache-from: type=gha
cache-to: type=gha
## Run-on cache
# cache-from: type=s3,blobs_prefix=cache/${{ github.repository }}/,manifests_prefix=cache/${{ github.repository }}/,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }}
# cache-to: type=s3,blobs_prefix=cache/${{ github.repository }}/,manifests_prefix=cache/${{ github.repository }}/,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }},mode=max
build-args: |
BASE_OS_VERSION=${{ matrix.base_os }}
PHP_VERSION=${{ matrix.patch_version }}
PHP_VARIATION=${{ matrix.php_variation }}
REPOSITORY_BUILD_VERSION=${{ env.REPOSITORY_BUILD_VERSION }}
platforms: |
linux/amd64
linux/arm64/v8
pull: true
push: ${{ inputs.push-to-registry }}
tags: ${{ env.DOCKER_TAGS }}
outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=Supercharge your PHP experience with Docker images that are based off the official PHP images but are optimized to be run in production environments for Laravel and WordPress and more

@thomasaull
Copy link

thomasaull commented Jan 8, 2025

@jaydrogers Thanks for the explaination, I definitely see your point. I guess it’s a trade of between path a) or b) where both require extra work then 😅

If it where up to me to decide, I'd probably add the additional dependency of frankenphp to the automated pipeline: Additionally check the frankenphp releases and only build this flavour of serversideup if the release is available. Again I might be missing something from a lack of knowledge.

Also the frankenphp images apparently are automatically built when a new php image is available: https://frankenphp.dev/docs/docker/#updates

@joshmanders
Copy link

I like @thomasaull's suggestions above. I'm re-evaluating switching back to serversideup/php since things have improved a lot since my last evaluation and I was just considering if there was a frankenphp variation as I personally use caddy in my own image and would like to keep using a caddy variant over nginx or apache.

@hookenz
Copy link

hookenz commented Apr 11, 2025

@jaydrogers - eager to get this going I've decided to give you a hand.

Here's a PR that gets us a bit further down the road. #527

@hookenz
Copy link

hookenz commented Apr 15, 2025

@jaydrogers I've been thinking about your dependency problem and I think you should build off the official frankenphp image rather than build franken yourself.

According to this link: https://frankenphp.dev/docs/docker/#updates

Like yours, the images will be built automatically with each PHP released.
So maybe your images just need to kick off a bit after that. According to the FrankenPHP website 4am UTC?
Although, we don't know how long it might take to appear on dockerhub.

So I think probably you should have the images build independently of each other so the whole build doesn't fail.
And then publish on your website which version is available for each. Most of the time I would expect it to be the latest.
But sometimes it might be held back. I guess you can have the script email you if there is a problem.

Regarding the images apparently the tags follow this pattern:

dunglas/frankenphp:<frankenphp-version>-php<php-version>-<os>

<frankenphp-version> and <php-version> are version numbers of FrankenPHP and PHP respectively, ranging from major (e.g. 1), minor (e.g. 1.2) to patch versions (e.g. 1.2.3).
<os> is either bookworm (for Debian Bookworm) or alpine (for the latest stable version of Alpine).

You can either query the dockerhub api via curl and some scripting magic or use this tool.
https://github.com/docker/hub-tool

Script adapted from the internet.

 #!/bin/sh

listTags() {
    repo="$1"
    size="${2:-25}"
    page="${3:-1}"

    if [ -z "$repo" ]; then
        echo "Usage: listTags <repoName> [size] [pageIndex]" >&2
        return 1
    fi

    #curl "https://hub.docker.com/v2/repositories/${repo}/tags?page=${page}&page_size=${size}"
    curl -s "https://hub.docker.com/v2/repositories/${repo}/tags?page=${page}&page_size=${size}" 2>/dev/null | jq -r '.results[].name' | sort
}

listTags dunglas/frankenphp 10 1

Just some thoughts. Very happy to help out. If you want some more in depth discussion or a sounding board on it let me know. I haven't delved very deep into your build process as yet.

@sawirricardo
Copy link

Hi, any update on this?

@hookenz
Copy link

hookenz commented May 19, 2025

Hi, any update on this?

I think @jaydrogers has been quite busy. So have I. It's certainly not forgotten. I will be needing this soon also.

@mihai-burduselu-ptt
Copy link

Hi, @jaydrogers . Any roadmap or updates on this? 😄

@jaydrogers
Copy link
Member Author

Haven't forgotten. Working on a big update that's related to this, then I will swing back.

Stay tuned 😃👍

@juddisjudd
Copy link

Just checking in on this, thanks!

@jaydrogers
Copy link
Member Author

I'm out of the office this week, but I plan on doing serversideup/php items once I get back next week 👍

@django23
Copy link

Do you need some help on this? I have some time next week to pick this up if needed.

jaydrogers and others added 30 commits October 31, 2025 14:30
…iling the transition from development to production images, creating Dockerfiles, best practices, and image versioning strategies. This guide aims to enhance user understanding of building secure and reliable Docker images for production environments.
…se 'compose.yml' for consistency across task scheduler, queue, horizon, and reverb guides.
…' to 'compose.yml' for consistency in configuration examples.
…mpose.yml' instead of 'docker-compose.yml' across all examples.
…addressing common challenges and providing solutions for managing UID/GID alignment between host and container environments. This guide includes examples for development and production setups to enhance user experience and security.
…larity on user and permission management in development environments. Updated image path syntax for consistency and enhanced user understanding of file permission challenges across different operating systems.
…' with 'compose.yml' for consistency across examples.
…on using Docker. Covers deployment challenges, Docker benefits, production image building, deployment strategies, automation, and introduces Spin for simplified workflows. Aims to enhance user confidence in deploying PHP applications.
…yml' for consistency in configuration examples and improve clarity in Docker setup instructions.
…cludes requirements, execution order, and examples for integrating scripts into the entrypoint.d directory, as well as guidance on using S6 Overlay for long-running services.
…s examples for using environment variables and custom php.ini files, along with validation methods to ensure changes are applied correctly.
…roduced icons for DigitalOcean, Hetzner, Vultr, and Sevalla, enhancing visual representation of hosting options in the application.
…ntainerized PHP applications. The guide covers portability, hosting options, recommended hosts, and key considerations for selecting the right host, enhancing user understanding of deployment strategies.
…documentation. Include a link to the guide on using healthchecks with Laravel for better user guidance.
…C_PATH` with `CADDY_SERVER_ROOT` for clarity and consistency. Adjust Caddyfile configuration to reflect the new variable, ensuring accurate root directory settings for the Caddy server.
…ER_ROOT` for improved clarity in server configuration.
…erversideup/php image. This includes usage guidelines, feature comparisons, setup instructions, and environment variable configurations, aimed at enhancing user understanding and adoption of this modern PHP application server.
…ng setup instructions, health check implementation, and performance considerations. Introduce a health check script for Octane to ensure proper application status monitoring.
…proved navigation. Adjusted paths to ensure they are correctly formatted for internal referencing.
…sure users are properly redirected when a page has a redirect property. This change enhances user experience by maintaining expected navigation behavior.
…the `SSL_PRIVATE_KEY_FILE` entry, enhancing clarity on supported configurations for HTTPS.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ Enhancement Items that are new features requested to be added.

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Create a FrankenPHP variation