From 20ecec1d9668088200d3ef1cc9b80186935ccde2 Mon Sep 17 00:00:00 2001
From: Jay Rogers
Date: Mon, 5 Feb 2024 13:22:46 -0600
Subject: [PATCH] Release/v3.0 (#207)
* Improved query accuracy
* Removed sort
* Removed version data
* Changed docker repo
* Restructured docker repository name
* Moved readme control to beta for now
* Improved error handling
* Removed unset check
* Added dev script
* Removed copy command
* Fixed merging of YML
* Disabled debugging
* Fixed merge
* Remove debug
* Improved dependency install
* Fixed structure of dev command
* Improved documentation
* Initial commit of S6
* Initial commit of other variations
* Added early exits
* Fixed separation of commands
* Added init script
* Removed whitespace
* Sort scripts to run by numerical order
* Fixed execution of commands
* Improved development script
* Removed debug
* WIP migrated FPM and NGINX over
* Removed wget dependency
* Fixed reference to php-fpm
* Changed shells
* Fixed dependency installer
* WIP - adding nginx
* Converted logic to shell
* Added trace
* Working NGINX
* Working NGINX-FPM
* Working Alpine support
* Functioning Alpine image
* Added special thanks
* Cleaned up error output
* Removed whitespace
* Fixed error reference
* Remove unnecessary code
* WIP Nginx Unit
* Set script name
* Renamed nginx-unit to unit
* Fixed base image reference
* Improved error output
* Working NGINX Unit with SSL-Off
* Cleaned up output
* Explicit script names
* Added debug
* WIP Unit Mixed
* Renamed SSL to self-signed
* Working SSL configuration
* Changed to serversideup/php
* Changed docker-php-pro to docker-php-serversideup
* Fixed illegal character error
* Added minimum TLS
* Updated ciphers
* Working NGINX Unit configuration
* Changed name reference
* Changed branch name for beta
* Added usage notes
* Refactored tag script
* Renamed base config file
* Renamed base config
* Moved RC and added usage instructions
* Removed whitespace
* Removed whitespace
* Require base config
* Clarified defaults
* Renamed DEPENDENCY_PACKAGES_BOOKWORM to DEPENDENCY_PACKAGES_DEBIAN
* Refactored and improved readability
* Added base operating systems
* Updated php-version.yml structure
* Added base os for RC
* Refactored assemble-docker-tags
* Adjusted Base OS Logic
* Fixed variable name
* Variable name change
* Pretty print
* Changed permissions
* Added help menu
* Fixed help menu
* Remove help tag
* Added fpm configs
* Added default variables
* Organized and renamed variables for better clarity
* Remove PHP open base dir
* Fixed permissions on configs
* Moved PHP_SESSION_COOKIE_SECURE to ini. Fixes #105. Ref #107
* Moved init scripts to be at a higher number
* Added PHP_ERROR_LOG
* Changed order of execution for debug
* Changed debug output order
* Removed default base os
* Prepared for push of images
* Default to any debian os
* Updated landing page
* Updated readme
* Improved NGINX Unit description
* Updated features
* Improved output
* Added newer versions
* Added build process
* Removed fpm-apache for now
* Updated NGINX Unit version to 1.31.1
* Added variations from config file
* Fixed tagging issues for default_base_os
* Added comment for why we can't include an alpine version of Unit
* Ignore DS_Store files
* Added PHP extensions
* Removed whitespace
* Commented out sqllit
* Specified branch due to https://github.com/cloudflare/pages-action/issues/97
* Update s6-overlay version to v3.1.6.2
* Updated comparison and moved S6 overlay to its own page
* Added APP_BASE_DIR
* Clarified release notes location
* Started migration guide
* Removed whitespace
* Update migration guide with v3 changes
* Updated Laravel automations
* Fixed heading reference
* Add branch parameter to Cloudflare deployment
* Cleaned up GitHub Action names
* Added skip-download option
* Temporarily set skip download
* Add expanded Laravel automations
* Clarified output
* Fix autorun Laravel migration to true
* Update PHP Docker Images and Add New Features
* Clarified comment
* Enabled downloads again
* Add PHP 8.3 with Alpine and Bookworm support
* Default to 8.3
* Added debug mode
* Moved debug mode to entrypoint
* Update Dockerfile and entrypoint scripts
* Added labels and ability to set repo versions
* Adjusted argument order
* Update environment variable specification
* Update REPOSITORY_BUILD_VERSION to include GIT
Short SHA and GitHub Run ID
* Update Dockerfile comments for CLI and FPM
variations
* Update PHP Docker Images description
* Add explanation for "Optimized for Laravel &
WordPress" in getting started guide
* Simplified checkout process
* Added ability to push to GHCR
* Add multi-arch support and published registry URLs
* Remove Discourse link
* Updated installation instructions
* Update upgrade guide with version selection
details
* Add links to view available images and tags
* Update installation.md with information about
selecting the version of PHP
* Update link to guide on selecting the right image
* Updated contribution guide
* Update docker-compose.yml to include .dockerignore
file
* Add composer support
* Set S6 Overlay version in variable instead of file
* Update project credits and special thanks
* Update title in marketing layout
* Adjusted default PHP extensions
* Added $build_major_version-$build_base_os tag
* Add default entrypoint scripts and disable default
configuration
* Fix typo in default configurations
* Add guide for migrating from official PHP Docker
images
* Fix missing image tag and add link to installation
guide
* Update PHP image migration guide
* Add default environment variable specification
* Add guide on changing common PHP settings
* Remove customizing the image guide
* Add migration guide from v2 to v3
* Update Docker Compose and add Dockerfile for
installing additional PHP extensions
* Fix image tag not found issue in older versions of
PHP
* Add instructions for rebuilding Docker image on
Docker Compose initialization
* Add install-php-extensions support
* Refactor Docker tag generation logic
* WIP of SSL and start up scripts
* Docs Upgrade (#245)
* Upgraded to Nuxt 3.8
* Added about images and content ref #238
* Updated to H1 Title
* Removed methods for SEO data
* Added OG Image template
* Cleaned up SEO
* Fixed undefined page variable
* Added sign up form
* Added nvm
* Add Node.js setup and update build process
* Update link to customizations guide
* Update environment name in marketing site preview
workflow
* Updated to base 64
* Update environment name in
action_marketing-site-publish.yml
* Add BASE_PATH to .env.example
* Add SSL configuration options
* Update SSL configuration options
* Update ogImage and twitterImage URLs in marketing
layout
* Allow for nuxt base url to be null
* Adjusted w and h of image
---------
Co-authored-by: Jay Rogers
* Update SSL configuration
* Updated logo
* Update PHP patch versions
* Fixed code highlights
* Update SSL configuration and provide examples for
self-signed and custom certificates
* Add note about php.ini in
changing-common-php-settings.md
* Update Dockerfile versions and install additional
PHP extensions
* Add guide for adding custom startup scripts
* Organized variables better
* Update migration guide with v3 changes
* Update PHP installation instructions and remove
deprecated features
* Removed arrow for compatibility reasons
* Update link to discussion
* Update PHP Docker Images with improved
customization
* Added PHP 8.3 support
* Update description in index.md file
* Update description of serversideup/php Docker
images
* Update PHP Docker Images name
* Changed to PNG image
* Update ogImageHeight in marketing layout
* Update ogDescription and twitterDescription in
marketing layout
* Update social image file type
* Update social image
* Adjusted OG image template
* Adjusted borders
* Update border and rounded styles in OgImage
component
* Update command reference in PHP Docker image
* Updated favicon Url ref #251
* Add PHP_OPEN_BASEDIR environment variable to Dockerfiles. Fixes #258
* Add port exposure for HTTP and HTTPS. Fixes #260
* Add PHP_MAX_INPUT_TIME environment variable. Fixes #257
* Added ZIP to Debian images. Fixes #261
* Add WORKDIR instruction. Fixes #263
* Update environment names for marketing site workflows
* Test CI
* CI test 2
* Revert environment names
* Cleaned up environment names
* CI test 1
* Remove testing
* Update PHP_EXT_INSTALLER_VERSION to 2.1.71
* Update PHP_EXT_INSTALLER_VERSION to 2.1.73
* Update Docker actions to latest versions
* Add prefix option for Docker image tag
* Add composer cache directory creation and ownership
* Added docker-php-serversideup-set-id script
* Removed --chown flag. Fixes #265
* Added video embed component
* Added Book & updated header
* Fix typo
* Fixed code execution
* Improved s6-init build process
* Added Dockerfile support
* Added S6 overlay script customization
* Add book recommendation for building multi-platform browser extensions
* Update menu link to Bugflow and change "Books" to "Products"
* Added automated checks to ensure database connection is alive before running migrations
* Added AUTORUN_LARAVEL_MIGRATION_TIMEOUT. Default timeout of 30 seconds
* Update PHP_EXT_INSTALLER_VERSION to 2.1.76
* Improved test connection to database. Fixes #279
* Upgraded to actions/checkout@v4
* Prepare for merge
* Update PHP patch versions in base config
---------
Co-authored-by: Dan Pastori
---
.dockerignore | 1 +
.../action_marketing-site-preview.yml | 14 +
.../action_marketing-site-publish.yml | 14 +
.../workflows/action_publish-beta-images.yml | 20 +
.../action_publish-production-images.yml | 16 +
.../publish_docker-images-production.yml | 65 -
.../scheduled-task_update-sponsors.yml | 2 +-
.../workflows/service_deploy-static-site.yml | 48 +
.../service_docker-build-and-publish.yml | 150 +-
.github/workflows/site_deploy-static-site.yml | 43 -
.github/workflows/site_preview-setup.yml | 40 -
.gitignore | 4 +-
README.md | 20 +-
dev.sh | 80 -
docs/.env.example | 2 +
docs/.nvmrc | 1 +
docs/components/Global/OgImage/DocsImage.vue | 35 +
docs/components/Global/ServerSideUp.vue | 59 +-
docs/components/content/About.vue | 26 +
docs/components/content/CodeGroup.vue | 2 +-
docs/components/content/CodePanel.vue | 4 +-
docs/components/content/Features.vue | 22 +-
docs/components/content/LandingSignup.vue | 41 +
docs/components/content/MarketingGrid.vue | 24 +-
docs/components/content/MarketingHeader.vue | 6 +-
docs/components/content/MarketingHero.vue | 4 +-
docs/components/content/VideoEmbed.vue | 21 +
docs/content/docs/1.index.md | 6 +-
.../1.these-images-vs-others.md | 106 +-
.../docs/2.getting-started/2.installation.md | 83 +-
.../3.default-configurations.md | 66 +
.../docs/2.getting-started/3.upgrade-guide.md | 63 +-
.../docs/2.getting-started/5.changelog.md | 4 +-
.../content/docs/2.getting-started/6.about.md | 48 +-
.../docs/2.getting-started/7.contributing.md | 75 +-
.../3.guide/1.choosing-the-right-image.md | 43 -
.../1.migrating-from-official-php-images.md | 28 +
.../3.guide/2.changing-common-php-settings.md | 58 +
.../docs/3.guide/2.customizing-the-image.md | 145 -
.../3.installing-additional-php-extensions.md | 121 +
.../4.adding-your-own-start-up-scripts.md | 157 +
.../content/docs/3.guide/5.configuring-ssl.md | 101 +
.../docs/3.guide/6.using-s6-overlay.md | 96 +
.../docs/3.guide/7.migrating-from-v2-to-v3.md | 57 +
.../4.laravel/2.laravel-task-scheduler.md | 4 +-
.../content/docs/4.laravel/3.laravel-queue.md | 4 +-
.../docs/4.laravel/4.laravel-horizon.md | 4 +-
.../1.environment-variable-specification.md | 83 +-
.../docs/6.reference/2.command-reference.md | 14 +
docs/content/index.md | 3 +
docs/layouts/docs.vue | 40 +-
docs/layouts/marketing.vue | 27 +-
docs/nuxt.config.ts | 24 +-
docs/package.json | 16 +-
.../public/images/icons/cloudflare-square.svg | 6 +
docs/public/images/icons/php-square.svg | 7 +
docs/public/images/icons/ubuntu-square.svg | 5 -
docs/public/images/logos/og-logo.png | Bin 0 -> 5098 bytes
docs/public/images/logos/og-ssu-logo.png | Bin 0 -> 3732 bytes
docs/public/images/logos/php-docker-logo.svg | 21 +-
docs/public/images/logos/x-logo.svg | 3 +
docs/public/images/social-image.jpg | Bin 66528 -> 229668 bytes
docs/yarn.lock | 8857 +++++++++++------
scripts/assemble-docker-tags.sh | 317 +
scripts/conf/php-versions-base-config.yml | 52 +
scripts/dev.sh | 150 +
scripts/get-php-versions.sh | 144 +
src/cli/Dockerfile | 69 -
src/cli/README.md | 3 -
.../etc/s6-overlay/s6-rc.d/runas-user/type | 1 -
src/cli/etc/s6-overlay/s6-rc.d/runas-user/up | 1 -
.../s6-rc.d/user/contents.d/runas-user | 0
src/cli/etc/s6-overlay/scripts/runas-user | 43 -
src/cli/php-version-packages/7.4.txt | 14 -
src/cli/php-version-packages/8.0.txt | 13 -
src/cli/php-version-packages/8.1.txt | 13 -
src/cli/php-version-packages/8.2.txt | 13 -
.../etc/entrypoint.d/0-container-info.sh | 31 +
src/common/etc/entrypoint.d/1-debug-mode.sh | 30 +
.../entrypoint.d/50-laravel-automations.sh | 112 +
...docker-php-serversideup-dep-install-alpine | 46 +
...docker-php-serversideup-dep-install-debian | 48 +
.../bin/docker-php-serversideup-entrypoint | 38 +
...php-serversideup-install-php-ext-installer | 27 +
.../local/bin/docker-php-serversideup-set-id | 58 +
src/common/usr/local/etc/php/php.ini | 1975 ++++
src/fpm-apache/Dockerfile | 78 -
src/fpm-apache/README.md | 5 -
.../etc/apache2/conf-available/remoteip.conf | 26 -
.../etc/apache2/conf-available/security.conf | 103 -
.../etc/apache2/mods-available/mpm_event.conf | 18 -
.../etc/apache2/sites-available/ssl-full.conf | 23 -
.../apache2/sites-available/ssl-mixed.conf | 7 -
.../etc/apache2/sites-available/ssl-off.conf | 3 -
.../etc/apache2/vhost-templates/http.conf | 40 -
.../etc/apache2/vhost-templates/https.conf | 48 -
.../php/fpm/pool.d/z-fpm-with-overrides.conf | 6 -
.../etc/s6-overlay/s6-rc.d/apache2/data/check | 10 -
.../s6-overlay/s6-rc.d/apache2/dependencies | 3 -
.../etc/s6-overlay/s6-rc.d/apache2/run | 6 -
.../s6-rc.d/configure-ssl/dependencies | 1 -
.../etc/s6-overlay/s6-rc.d/configure-ssl/type | 1 -
.../etc/s6-overlay/s6-rc.d/configure-ssl/up | 1 -
.../s6-rc.d/debug-apache2/dependencies | 1 -
.../etc/s6-overlay/s6-rc.d/debug-apache2/type | 1 -
.../etc/s6-overlay/s6-rc.d/debug-apache2/up | 1 -
.../etc/s6-overlay/s6-rc.d/msmtp/type | 1 -
.../etc/s6-overlay/s6-rc.d/msmtp/up | 1 -
.../s6-rc.d/user/contents.d/apache2 | 0
.../s6-rc.d/user/contents.d/configure-ssl | 0
.../s6-rc.d/user/contents.d/debug-apache2 | 0
.../s6-overlay/s6-rc.d/user/contents.d/msmtp | 0
.../etc/s6-overlay/scripts/configure-ssl | 34 -
.../etc/s6-overlay/scripts/debug-apache2 | 13 -
src/fpm-apache/etc/s6-overlay/scripts/msmtp | 13 -
src/fpm-nginx/Dockerfile | 44 -
src/fpm-nginx/README.md | 5 -
src/fpm-nginx/etc/nginx/nginx.conf | 56 -
.../php/fpm/pool.d/z-fpm-with-overrides.conf | 6 -
.../s6-rc.d/configure-ssl/dependencies | 1 -
.../etc/s6-overlay/s6-rc.d/configure-ssl/type | 1 -
.../etc/s6-overlay/s6-rc.d/configure-ssl/up | 1 -
.../s6-rc.d/debug-nginx/dependencies | 1 -
.../etc/s6-overlay/s6-rc.d/debug-nginx/type | 1 -
.../etc/s6-overlay/s6-rc.d/debug-nginx/up | 1 -
.../etc/s6-overlay/s6-rc.d/msmtp/type | 1 -
src/fpm-nginx/etc/s6-overlay/s6-rc.d/msmtp/up | 1 -
.../etc/s6-overlay/s6-rc.d/nginx/dependencies | 3 -
.../s6-rc.d/user/contents.d/configure-ssl | 0
.../s6-rc.d/user/contents.d/debug-nginx | 0
.../s6-overlay/s6-rc.d/user/contents.d/msmtp | 0
.../etc/s6-overlay/scripts/configure-ssl | 34 -
.../etc/s6-overlay/scripts/debug-nginx | 13 -
src/fpm-nginx/etc/s6-overlay/scripts/msmtp | 13 -
src/fpm/Dockerfile | 50 -
src/fpm/README.md | 3 -
.../s6-rc.d/laravel-automations/dependencies | 1 -
.../s6-rc.d/laravel-automations/type | 1 -
.../s6-overlay/s6-rc.d/laravel-automations/up | 1 -
.../etc/s6-overlay/s6-rc.d/php-fpm/data/check | 2 -
.../s6-overlay/s6-rc.d/php-fpm/dependencies | 2 -
.../s6-rc.d/php-fpm/notification-fd | 1 -
src/fpm/etc/s6-overlay/s6-rc.d/php-fpm/type | 1 -
.../user/contents.d/laravel-automations | 0
.../s6-overlay/scripts/laravel-automations | 33 -
.../docker-php-serversideup-pool.conf} | 118 +-
.../entrypoint.d/10-init-webserver-config.sh | 127 +
.../etc/s6-overlay/s6-rc.d/php-fpm/data/check | 2 +
.../s6-overlay/s6-rc.d/php-fpm/dependencies | 1 +
.../s6-rc.d/php-fpm}/notification-fd | 0
.../etc/s6-overlay/s6-rc.d/php-fpm/run | 2 +-
.../etc/s6-overlay/s6-rc.d/php-fpm}/type | 0
.../s6-rc.d/user/contents.d/php-fpm | 0
.../local/bin/docker-php-serversideup-s6-init | 57 +
.../bin/docker-php-serversideup-s6-install | 38 +
src/variations/cli/Dockerfile | 64 +
src/variations/fpm-nginx/Dockerfile | 162 +
.../fpm-nginx/etc/nginx/nginx.conf.template | 33 +
.../etc/nginx/server-opts.d/performance.conf | 0
.../etc/nginx/server-opts.d/remoteip.conf | 0
.../etc/nginx/server-opts.d/security.conf | 0
.../etc/nginx/site-opts.d/http.conf.template} | 8 +-
.../nginx/site-opts.d/https.conf.template} | 15 +-
.../etc/nginx/sites-available/ssl-full | 0
.../etc/nginx/sites-available/ssl-mixed | 0
.../etc/nginx/sites-available/ssl-off | 0
.../etc/s6-overlay/s6-rc.d/nginx/data/check | 4 +-
.../etc/s6-overlay/s6-rc.d/nginx/dependencies | 1 +
.../s6-overlay/s6-rc.d/nginx/notification-fd | 0
.../etc/s6-overlay/s6-rc.d/nginx/run | 0
.../etc/s6-overlay/s6-rc.d/nginx/type | 0
.../s6-overlay/s6-rc.d/user/contents.d/nginx | 0
src/variations/fpm/Dockerfile | 80 +
src/variations/unit/Dockerfile | 144 +
.../unit/etc/entrypoint.d/10-init-unit.sh | 194 +
.../etc/unit/config.d/ssl-full.json.template | 106 +
.../etc/unit/config.d/ssl-mixed.json.template | 94 +
.../etc/unit/config.d/ssl-off.json.template | 57 +
178 files changed, 11412 insertions(+), 4953 deletions(-)
create mode 100644 .dockerignore
create mode 100644 .github/workflows/action_marketing-site-preview.yml
create mode 100644 .github/workflows/action_marketing-site-publish.yml
create mode 100644 .github/workflows/action_publish-beta-images.yml
create mode 100644 .github/workflows/action_publish-production-images.yml
delete mode 100644 .github/workflows/publish_docker-images-production.yml
create mode 100644 .github/workflows/service_deploy-static-site.yml
delete mode 100644 .github/workflows/site_deploy-static-site.yml
delete mode 100644 .github/workflows/site_preview-setup.yml
delete mode 100755 dev.sh
create mode 100644 docs/.nvmrc
create mode 100644 docs/components/Global/OgImage/DocsImage.vue
create mode 100644 docs/components/content/About.vue
create mode 100644 docs/components/content/LandingSignup.vue
create mode 100644 docs/components/content/VideoEmbed.vue
create mode 100644 docs/content/docs/2.getting-started/3.default-configurations.md
delete mode 100644 docs/content/docs/3.guide/1.choosing-the-right-image.md
create mode 100644 docs/content/docs/3.guide/1.migrating-from-official-php-images.md
create mode 100644 docs/content/docs/3.guide/2.changing-common-php-settings.md
delete mode 100644 docs/content/docs/3.guide/2.customizing-the-image.md
create mode 100644 docs/content/docs/3.guide/3.installing-additional-php-extensions.md
create mode 100644 docs/content/docs/3.guide/4.adding-your-own-start-up-scripts.md
create mode 100644 docs/content/docs/3.guide/5.configuring-ssl.md
create mode 100644 docs/content/docs/3.guide/6.using-s6-overlay.md
create mode 100644 docs/content/docs/3.guide/7.migrating-from-v2-to-v3.md
create mode 100644 docs/content/docs/6.reference/2.command-reference.md
create mode 100644 docs/public/images/icons/cloudflare-square.svg
create mode 100644 docs/public/images/icons/php-square.svg
delete mode 100644 docs/public/images/icons/ubuntu-square.svg
create mode 100644 docs/public/images/logos/og-logo.png
create mode 100644 docs/public/images/logos/og-ssu-logo.png
create mode 100644 docs/public/images/logos/x-logo.svg
create mode 100755 scripts/assemble-docker-tags.sh
create mode 100644 scripts/conf/php-versions-base-config.yml
create mode 100755 scripts/dev.sh
create mode 100755 scripts/get-php-versions.sh
delete mode 100644 src/cli/Dockerfile
delete mode 100644 src/cli/README.md
delete mode 100644 src/cli/etc/s6-overlay/s6-rc.d/runas-user/type
delete mode 100644 src/cli/etc/s6-overlay/s6-rc.d/runas-user/up
delete mode 100644 src/cli/etc/s6-overlay/s6-rc.d/user/contents.d/runas-user
delete mode 100644 src/cli/etc/s6-overlay/scripts/runas-user
delete mode 100644 src/cli/php-version-packages/7.4.txt
delete mode 100644 src/cli/php-version-packages/8.0.txt
delete mode 100644 src/cli/php-version-packages/8.1.txt
delete mode 100644 src/cli/php-version-packages/8.2.txt
create mode 100644 src/common/etc/entrypoint.d/0-container-info.sh
create mode 100644 src/common/etc/entrypoint.d/1-debug-mode.sh
create mode 100644 src/common/etc/entrypoint.d/50-laravel-automations.sh
create mode 100644 src/common/usr/local/bin/docker-php-serversideup-dep-install-alpine
create mode 100644 src/common/usr/local/bin/docker-php-serversideup-dep-install-debian
create mode 100644 src/common/usr/local/bin/docker-php-serversideup-entrypoint
create mode 100644 src/common/usr/local/bin/docker-php-serversideup-install-php-ext-installer
create mode 100644 src/common/usr/local/bin/docker-php-serversideup-set-id
create mode 100644 src/common/usr/local/etc/php/php.ini
delete mode 100644 src/fpm-apache/Dockerfile
delete mode 100644 src/fpm-apache/README.md
delete mode 100644 src/fpm-apache/etc/apache2/conf-available/remoteip.conf
delete mode 100644 src/fpm-apache/etc/apache2/conf-available/security.conf
delete mode 100644 src/fpm-apache/etc/apache2/mods-available/mpm_event.conf
delete mode 100644 src/fpm-apache/etc/apache2/sites-available/ssl-full.conf
delete mode 100644 src/fpm-apache/etc/apache2/sites-available/ssl-mixed.conf
delete mode 100644 src/fpm-apache/etc/apache2/sites-available/ssl-off.conf
delete mode 100644 src/fpm-apache/etc/apache2/vhost-templates/http.conf
delete mode 100644 src/fpm-apache/etc/apache2/vhost-templates/https.conf
delete mode 100644 src/fpm-apache/etc/php/fpm/pool.d/z-fpm-with-overrides.conf
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/apache2/data/check
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/apache2/dependencies
delete mode 100755 src/fpm-apache/etc/s6-overlay/s6-rc.d/apache2/run
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/configure-ssl/dependencies
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/configure-ssl/type
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/configure-ssl/up
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/debug-apache2/dependencies
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/debug-apache2/type
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/debug-apache2/up
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/msmtp/type
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/msmtp/up
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/user/contents.d/apache2
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/user/contents.d/configure-ssl
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/user/contents.d/debug-apache2
delete mode 100644 src/fpm-apache/etc/s6-overlay/s6-rc.d/user/contents.d/msmtp
delete mode 100644 src/fpm-apache/etc/s6-overlay/scripts/configure-ssl
delete mode 100644 src/fpm-apache/etc/s6-overlay/scripts/debug-apache2
delete mode 100644 src/fpm-apache/etc/s6-overlay/scripts/msmtp
delete mode 100644 src/fpm-nginx/Dockerfile
delete mode 100644 src/fpm-nginx/README.md
delete mode 100644 src/fpm-nginx/etc/nginx/nginx.conf
delete mode 100644 src/fpm-nginx/etc/php/fpm/pool.d/z-fpm-with-overrides.conf
delete mode 100644 src/fpm-nginx/etc/s6-overlay/s6-rc.d/configure-ssl/dependencies
delete mode 100644 src/fpm-nginx/etc/s6-overlay/s6-rc.d/configure-ssl/type
delete mode 100644 src/fpm-nginx/etc/s6-overlay/s6-rc.d/configure-ssl/up
delete mode 100644 src/fpm-nginx/etc/s6-overlay/s6-rc.d/debug-nginx/dependencies
delete mode 100644 src/fpm-nginx/etc/s6-overlay/s6-rc.d/debug-nginx/type
delete mode 100644 src/fpm-nginx/etc/s6-overlay/s6-rc.d/debug-nginx/up
delete mode 100644 src/fpm-nginx/etc/s6-overlay/s6-rc.d/msmtp/type
delete mode 100644 src/fpm-nginx/etc/s6-overlay/s6-rc.d/msmtp/up
delete mode 100644 src/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/dependencies
delete mode 100644 src/fpm-nginx/etc/s6-overlay/s6-rc.d/user/contents.d/configure-ssl
delete mode 100644 src/fpm-nginx/etc/s6-overlay/s6-rc.d/user/contents.d/debug-nginx
delete mode 100644 src/fpm-nginx/etc/s6-overlay/s6-rc.d/user/contents.d/msmtp
delete mode 100644 src/fpm-nginx/etc/s6-overlay/scripts/configure-ssl
delete mode 100644 src/fpm-nginx/etc/s6-overlay/scripts/debug-nginx
delete mode 100644 src/fpm-nginx/etc/s6-overlay/scripts/msmtp
delete mode 100644 src/fpm/Dockerfile
delete mode 100644 src/fpm/README.md
delete mode 100644 src/fpm/etc/s6-overlay/s6-rc.d/laravel-automations/dependencies
delete mode 100644 src/fpm/etc/s6-overlay/s6-rc.d/laravel-automations/type
delete mode 100644 src/fpm/etc/s6-overlay/s6-rc.d/laravel-automations/up
delete mode 100644 src/fpm/etc/s6-overlay/s6-rc.d/php-fpm/data/check
delete mode 100644 src/fpm/etc/s6-overlay/s6-rc.d/php-fpm/dependencies
delete mode 100644 src/fpm/etc/s6-overlay/s6-rc.d/php-fpm/notification-fd
delete mode 100644 src/fpm/etc/s6-overlay/s6-rc.d/php-fpm/type
delete mode 100644 src/fpm/etc/s6-overlay/s6-rc.d/user/contents.d/laravel-automations
delete mode 100644 src/fpm/etc/s6-overlay/scripts/laravel-automations
rename src/{fpm/etc/php/fpm/pool.d/y-override-php-defaults.conf => php-fpm.d/usr/local/etc/php-fpm.d/docker-php-serversideup-pool.conf} (70%)
create mode 100644 src/s6/etc/entrypoint.d/10-init-webserver-config.sh
create mode 100644 src/s6/etc/s6-overlay/s6-rc.d/php-fpm/data/check
create mode 100644 src/s6/etc/s6-overlay/s6-rc.d/php-fpm/dependencies
rename src/{fpm-apache/etc/s6-overlay/s6-rc.d/apache2 => s6/etc/s6-overlay/s6-rc.d/php-fpm}/notification-fd (100%)
rename src/{fpm => s6}/etc/s6-overlay/s6-rc.d/php-fpm/run (60%)
rename src/{fpm-apache/etc/s6-overlay/s6-rc.d/apache2 => s6/etc/s6-overlay/s6-rc.d/php-fpm}/type (100%)
rename src/{fpm => s6}/etc/s6-overlay/s6-rc.d/user/contents.d/php-fpm (100%)
create mode 100644 src/s6/usr/local/bin/docker-php-serversideup-s6-init
create mode 100644 src/s6/usr/local/bin/docker-php-serversideup-s6-install
create mode 100644 src/variations/cli/Dockerfile
create mode 100644 src/variations/fpm-nginx/Dockerfile
create mode 100644 src/variations/fpm-nginx/etc/nginx/nginx.conf.template
rename src/{ => variations}/fpm-nginx/etc/nginx/server-opts.d/performance.conf (100%)
rename src/{ => variations}/fpm-nginx/etc/nginx/server-opts.d/remoteip.conf (100%)
rename src/{ => variations}/fpm-nginx/etc/nginx/server-opts.d/security.conf (100%)
rename src/{fpm-nginx/etc/nginx/site-opts.d/http.conf => variations/fpm-nginx/etc/nginx/site-opts.d/http.conf.template} (79%)
rename src/{fpm-nginx/etc/nginx/site-opts.d/https.conf => variations/fpm-nginx/etc/nginx/site-opts.d/https.conf.template} (57%)
rename src/{ => variations}/fpm-nginx/etc/nginx/sites-available/ssl-full (100%)
rename src/{ => variations}/fpm-nginx/etc/nginx/sites-available/ssl-mixed (100%)
rename src/{ => variations}/fpm-nginx/etc/nginx/sites-available/ssl-off (100%)
rename src/{ => variations}/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/data/check (76%)
create mode 100644 src/variations/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/dependencies
rename src/{ => variations}/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/notification-fd (100%)
rename src/{ => variations}/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/run (100%)
rename src/{ => variations}/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/type (100%)
rename src/{ => variations}/fpm-nginx/etc/s6-overlay/s6-rc.d/user/contents.d/nginx (100%)
create mode 100644 src/variations/fpm/Dockerfile
create mode 100644 src/variations/unit/Dockerfile
create mode 100644 src/variations/unit/etc/entrypoint.d/10-init-unit.sh
create mode 100644 src/variations/unit/etc/unit/config.d/ssl-full.json.template
create mode 100644 src/variations/unit/etc/unit/config.d/ssl-mixed.json.template
create mode 100644 src/variations/unit/etc/unit/config.d/ssl-off.json.template
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..6a3e68da
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1 @@
+**/.DS_Store
\ No newline at end of file
diff --git a/.github/workflows/action_marketing-site-preview.yml b/.github/workflows/action_marketing-site-preview.yml
new file mode 100644
index 00000000..72d40978
--- /dev/null
+++ b/.github/workflows/action_marketing-site-preview.yml
@@ -0,0 +1,14 @@
+name: Site Deployment - Preview đ¨âđŦ
+
+on:
+ pull_request:
+ types: [opened, synchronize, reopened]
+ paths:
+ - docs/**
+
+jobs:
+ publish-preview-site:
+ uses: ./.github/workflows/service_deploy-static-site.yml
+ secrets: inherit
+ with:
+ environment-name: 'docker-php (Preview)'
\ No newline at end of file
diff --git a/.github/workflows/action_marketing-site-publish.yml b/.github/workflows/action_marketing-site-publish.yml
new file mode 100644
index 00000000..31adc686
--- /dev/null
+++ b/.github/workflows/action_marketing-site-publish.yml
@@ -0,0 +1,14 @@
+name: Site Deployment - Production đ
+on:
+ push:
+ branches:
+ - main
+ paths:
+ - docs/**
+
+jobs:
+ publish-production-site:
+ secrets: inherit
+ uses: ./.github/workflows/service_deploy-static-site.yml
+ with:
+ environment-name: 'docker-php (Production)'
\ No newline at end of file
diff --git a/.github/workflows/action_publish-beta-images.yml b/.github/workflows/action_publish-beta-images.yml
new file mode 100644
index 00000000..f5064673
--- /dev/null
+++ b/.github/workflows/action_publish-beta-images.yml
@@ -0,0 +1,20 @@
+name: Docker Publish (Beta Images)
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - main
+ paths:
+ - src/**
+ - .github/workflows/**
+ - scripts/**
+ schedule:
+ - cron: '0 8 * * 1'
+
+jobs:
+ build-beta-images:
+ uses: ./.github/workflows/service_docker-build-and-publish.yml
+ with:
+ tag-prefix: "beta-"
+ secrets: inherit
\ No newline at end of file
diff --git a/.github/workflows/action_publish-production-images.yml b/.github/workflows/action_publish-production-images.yml
new file mode 100644
index 00000000..b5e7b70b
--- /dev/null
+++ b/.github/workflows/action_publish-production-images.yml
@@ -0,0 +1,16 @@
+name: Docker Publish (Production Images)
+
+on:
+ workflow_dispatch:
+ release:
+ types: [released]
+ # Commenting out until 3.x is launched
+ # schedule:
+ # - cron: '0 8 * * 2'
+
+jobs:
+ build-production-images:
+ uses: ./.github/workflows/service_docker-build-and-publish.yml
+ with:
+ tag-prefix: ''
+ secrets: inherit
\ No newline at end of file
diff --git a/.github/workflows/publish_docker-images-production.yml b/.github/workflows/publish_docker-images-production.yml
deleted file mode 100644
index ff138fee..00000000
--- a/.github/workflows/publish_docker-images-production.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-name: Docker Publish (Production Images)
-
-on:
- workflow_dispatch:
- release:
- types: [released]
- schedule:
- - cron: '0 8 * * 2'
-
-jobs:
- cli:
- uses: ./.github/workflows/service_docker-build-and-publish.yml
- with:
- upstream-channel-prefix: ''
- tag-prefix: ''
- php-variation: cli
- checkout-type: latest-stable
- secrets: inherit
-
- fpm:
- needs: cli
- uses: ./.github/workflows/service_docker-build-and-publish.yml
- with:
- upstream-channel-prefix: ''
- tag-prefix: ''
- php-variation: fpm
- checkout-type: latest-stable
- secrets: inherit
-
- fpm-nginx:
- needs: fpm
- uses: ./.github/workflows/service_docker-build-and-publish.yml
- with:
- upstream-channel-prefix: ''
- tag-prefix: ''
- php-variation: fpm-nginx
- checkout-type: latest-stable
- secrets: inherit
-
- fpm-apache:
- needs: fpm
- uses: ./.github/workflows/service_docker-build-and-publish.yml
- with:
- upstream-channel-prefix: ''
- tag-prefix: ''
- php-variation: fpm-apache
- checkout-type: latest-stable
- secrets: inherit
-
- update_container_readme:
- runs-on: ubuntu-latest
- name: Push README to Docker Hub
- steps:
- - name: git checkout
- uses: actions/checkout@v3
- with:
- ref: main
-
- - name: push README to Dockerhub
- uses: peter-evans/dockerhub-description@v3
- with:
- username: ${{ secrets.DOCKER_HUB_README_USERNAME }}
- password: ${{ secrets.DOCKER_HUB_README_PASSWORD }}
- repository: serversideup/php
- short-description: ${{ github.event.repository.description }}
\ No newline at end of file
diff --git a/.github/workflows/scheduled-task_update-sponsors.yml b/.github/workflows/scheduled-task_update-sponsors.yml
index 4c2144cf..7e61ffc3 100644
--- a/.github/workflows/scheduled-task_update-sponsors.yml
+++ b/.github/workflows/scheduled-task_update-sponsors.yml
@@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout đī¸
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Generate Sponsors đ
uses: JamesIves/github-sponsors-readme-action@v1
diff --git a/.github/workflows/service_deploy-static-site.yml b/.github/workflows/service_deploy-static-site.yml
new file mode 100644
index 00000000..ec62b629
--- /dev/null
+++ b/.github/workflows/service_deploy-static-site.yml
@@ -0,0 +1,48 @@
+on:
+ workflow_call:
+ inputs:
+ environment-name:
+ required: true
+ type: string
+
+jobs:
+ deploy-static-site:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ deployments: write
+ environment:
+ name: ${{ inputs.environment-name }}
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version-file: './docs/.nvmrc'
+
+ - name: Set env file
+ run: |
+ if [[ -z "$BASE_64_SECRET" ]]; then
+ echo 'đ¨đ¨đ¨ ENV File not set đ¨đ¨đ¨' 1>&2
+ exit 1
+ fi
+ echo $BASE_64_SECRET | base64 -d > .env
+ working-directory: ./docs
+ env:
+ BASE_64_SECRET: ${{ secrets.ENV_FILE_BASE64 }}
+
+ - run: |
+ yarn install --frozen-lockfile
+ yarn build
+ npx nuxi generate
+ working-directory: ./docs
+
+ - name: Publish to Cloudflare Pages
+ uses: cloudflare/pages-action@v1
+ with:
+ apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
+ accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
+ projectName: docker-php
+ directory: docs/.output/public
+ branch: ${{ github.head_ref || github.ref_name }}
+ gitHubToken: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/service_docker-build-and-publish.yml b/.github/workflows/service_docker-build-and-publish.yml
index 87baf499..0ea3de0c 100644
--- a/.github/workflows/service_docker-build-and-publish.yml
+++ b/.github/workflows/service_docker-build-and-publish.yml
@@ -1,65 +1,72 @@
on:
workflow_call:
inputs:
- upstream-channel-prefix:
- required: true
- type: string
- default: ''
tag-prefix:
required: true
type: string
- default: 'beta-'
- php-variation:
- required: true
+ default: 'edge-'
+ php-versions-file:
type: string
- checkout-type:
- required: true
+ default: 'scripts/conf/php-versions.yml'
+ default-image-variation:
type: string
+ default: 'cli'
jobs:
+ setup-matrix:
+ runs-on: ubuntu-22.04
+ outputs:
+ php-version-map-json: ${{ steps.get-php-versions.outputs.php-version-map-json }}
+ steps:
+ - 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
+
+ - 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}]}')
+ echo "php-version-map-json=${MATRIX_JSON}" >> $GITHUB_OUTPUT
+ echo "${MATRIX_JSON}" | jq '.'
+
+ - name: Upload the php-versions.yml file
+ uses: actions/upload-artifact@v3
+ with:
+ name: php-versions.yml
+ path: ${{ inputs.php-versions-file }}
+
docker-publish:
+ needs: setup-matrix
runs-on: ubuntu-22.04
strategy:
- matrix:
- php-version:
- - "7.4"
- - "8.0"
- - "8.1"
- - "8.2"
- steps:
- ##
- # Checkout branch (for push deployments)
- ##
- - name: Get branch name
- if: inputs.checkout-type == 'branch'
- id: branch-name
- uses: tj-actions/branch-names@v6
+ matrix: ${{fromJson(needs.setup-matrix.outputs.php-version-map-json)}}
- - uses: actions/checkout@v3
- if: inputs.checkout-type == 'branch'
+ steps:
+ - name: Check out code.
+ uses: actions/checkout@v4
+
+ - name: Download PHP Versions file
+ uses: actions/download-artifact@v3
with:
- ref: ${{ steps.branch-name.outputs.current_branch }}
+ name: php-versions.yml
+ path: ./artifacts
+
+ - name: Move PHP Versions file
+ run: mv ./artifacts/php-versions.yml ${{ inputs.php-versions-file }}
- ##
- # Checkout latest stable release (for production releases)
- ##
- - name: Get latest stable release
- if: inputs.checkout-type == 'latest-stable'
- id: latest-stable-version
- run: |
- echo "LATEST_STABLE_VERSION=$(curl --silent --header "Accept: application/vnd.github.v3.sha" "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')" >> $GITHUB_OUTPUT
-
- - name: Confirm release tag
- if: inputs.checkout-type == 'latest-stable'
- run: |
- echo "Latest Stable Release Tag: ${{ steps.latest-stable-version.outputs.LATEST_STABLE_VERSION }}"
-
- - name: Checkout latest stable tag
- if: inputs.checkout-type == 'latest-stable'
- uses: actions/checkout@v3
- with:
- ref: ${{ steps.latest-stable-version.outputs.LATEST_STABLE_VERSION }}
-
##
# Docker build & publish
##
@@ -69,27 +76,52 @@ jobs:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
+ - name: Login to GitHub Container Registry
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
- name: Set up QEMU
- uses: docker/setup-qemu-action@v2
+ uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v2
-
- - name: "đ¨âđŦ Set docker tags: Non-Release "
- if: inputs.checkout-type == 'branch'
- run: echo "DOCKER_TAGS=serversideup/php:${{ inputs.tag-prefix}}${{ matrix.php-version }}-${{ inputs.php-variation }}" >> $GITHUB_ENV
+ uses: docker/setup-buildx-action@v3
- - name: "đ Set docker tags: Release"
- if: inputs.checkout-type == 'latest-stable'
- run: echo "DOCKER_TAGS=serversideup/php:${{ inputs.tag-prefix}}${{ matrix.php-version }}-${{ inputs.php-variation }}, serversideup/php:${{ inputs.tag-prefix}}${{ matrix.php-version }}-${{ inputs.php-variation }}-${{ steps.latest-stable-version.outputs.LATEST_STABLE_VERSION }}" >> $GITHUB_ENV
+ - 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 }}
+
+ - 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 and push
- uses: docker/build-push-action@v3
+ uses: docker/build-push-action@v5
with:
+ file: src/variations/${{ matrix.php_variation }}/Dockerfile
build-args: |
- UPSTREAM_CHANNEL=${{ inputs.upstream-channel-prefix }}
- PHP_VERSION=${{ matrix.php-version }}
- context: src/${{ inputs.php-variation }}/.
+ 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/arm/v7
diff --git a/.github/workflows/site_deploy-static-site.yml b/.github/workflows/site_deploy-static-site.yml
deleted file mode 100644
index 49a6e65d..00000000
--- a/.github/workflows/site_deploy-static-site.yml
+++ /dev/null
@@ -1,43 +0,0 @@
-name: đ Deploy Static Site
-
-on:
- push:
- branches:
- - main
- paths:
- - docs/**
-
-jobs:
- deploy-static-site:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- deployments: write
- steps:
- - uses: actions/checkout@v3
-
- - name: Set env file
- run: |
- if [[ -z "$BASE_64_SECRET" ]]; then
- echo 'đ¨đ¨đ¨ ENV File not set đ¨đ¨đ¨' 1>&2
- exit 1
- fi
- echo $BASE_64_SECRET | base64 -d > .env
- working-directory: ./docs
- env:
- BASE_64_SECRET: ${{ secrets.ENV_FILE_BASE64_PROD }}
-
- - run: |
- yarn install --frozen-lockfile
- yarn build
- npx nuxi generate
- working-directory: ./docs
-
- - name: Publish to Cloudflare Pages
- uses: cloudflare/pages-action@v1
- with:
- apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
- accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
- projectName: docker-php
- directory: docs/.output/public
- gitHubToken: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/site_preview-setup.yml b/.github/workflows/site_preview-setup.yml
deleted file mode 100644
index 86a3d6bd..00000000
--- a/.github/workflows/site_preview-setup.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-name: đ CloudFlare Pages Preview
-
-on:
- pull_request:
- types: [opened, synchronize, reopened]
-
-jobs:
- build-site:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- deployments: write
- steps:
- - uses: actions/checkout@v3
-
- - name: Set env file
- run: |
- if [[ -z "$BASE_64_SECRET" ]]; then
- echo 'đ¨đ¨đ¨ ENV File not set đ¨đ¨đ¨' 1>&2
- exit 1
- fi
- echo $BASE_64_SECRET | base64 -d > .env
- working-directory: ./docs
- env:
- BASE_64_SECRET: ${{ secrets.ENV_FILE_BASE64 }}
-
- - run: |
- yarn install --frozen-lockfile
- yarn build
- npx nuxi generate
- working-directory: ./docs
-
- - name: Publish to Cloudflare Pages
- uses: cloudflare/pages-action@v1
- with:
- apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
- accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
- projectName: docker-php
- directory: docs/.output/public
- gitHubToken: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 50f5a290..cbc1be6a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,6 @@
package-lock.json
package.json
yarn.lock
-node_modules
\ No newline at end of file
+node_modules
+php-versions.yml
+*.tmp
\ No newline at end of file
diff --git a/README.md b/README.md
index 5c6d59ff..2f4fabc1 100644
--- a/README.md
+++ b/README.md
@@ -6,13 +6,12 @@
-
-
+
## Introduction
-`PHP Docker Images` is an optimized set of Docker Images for running PHP applications in production. Everything is designed around improving the developer experience with PHP and Docker. Gone are the days of configuring each environment differently, and gone are the days of trying to figure out why your code works in one environment and not the other.
+`serversideup/php` is an optimized set of Docker Images for running PHP applications in production. Everything is designed around improving the developer experience with PHP and Docker. Gone are the days of configuring each environment differently, and gone are the days of trying to figure out why your code works in one environment and not the other.
These images are highly optimized to run modern PHP applications, no matter where you want your application to run.
@@ -25,10 +24,10 @@ Experience the ***true difference*** of using these images vs the other options
Features
-| | | |
+| | | |
|:---:|:---:|:---:|
-| | | |
-| | | |
+| | | |
+| | | |
@@ -86,6 +85,14 @@ All of our software is free an open to the world. None of this can be brought to
#### Individual Supporters
+#### Special thanks
+We'd like to specifically thank a few folks for taking the time for being a sound board that deeply influenced the direction of this project.
+
+Please check out all of their work:
+- [Chris Fidao](https://twitter.com/fideloper)
+- [Joel Clermont](https://twitter.com/joelclermont)
+- [Patricio](https://twitter.com/PatricioOnCode)
+
## About Us
We're [Dan](https://twitter.com/danpastori) and [Jay](https://twitter.com/jaydrogers) - a two person team with a passion for open source products. We created [Server Side Up](https://serversideup.net) to help share what we learn.
@@ -112,6 +119,7 @@ If you appreciate this project, be sure to check out our other projects.
### đ Books
- **[The Ultimate Guide to Building APIs & SPAs](https://serversideup.net/ultimate-guide-to-building-apis-and-spas-with-laravel-and-nuxt3/)**: Build web & mobile apps from the same codebase.
+- **[Building Multi-Platform Browser Extensions](https://serversideup.net/building-multi-platform-browser-extensions/)**: Ship extensions to all browsers from the same codebase.
### đ ī¸ Software-as-a-Service
- **[Bugflow](https://bugflow.io/)**: Get visual bug reports directly in GitHub, GitLab, and more.
diff --git a/dev.sh b/dev.sh
deleted file mode 100755
index 411396df..00000000
--- a/dev.sh
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/bin/bash
-
-#exit on error
-set -e
-
-##########################
-# Environment Settings
-DEV_UPSTREAM_CHANNEL="beta-"
-
-# UI Colors
-function ui_set_yellow {
- printf $'\033[0;33m'
-}
-
-function ui_set_green {
- printf $'\033[0;32m'
-}
-
-function ui_set_red {
- printf $'\033[0;31m'
-}
-
-function ui_reset_colors {
- printf "\e[0m"
-}
-
-# Script Configurations
-SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
-
-##########################
-# Set versions to build
-if [ $# -eq 0 ]; then
- # Set versions
- phpVersions=()
-
- echo "Running build for these PHP versions..."
- # Loop through each .txt file in the current directory
- for file in src/cli/php-version-packages/*.txt; do
- # Trim the extension off the filename and add it to the array
- phpVersion=$(basename -- "$file")
- phpVersion="${phpVersion%.*}"
- phpVersions+=("$phpVersion")
-
- # Print the filename without the extension
- echo "$phpVersion"
- done
-else
- phpVersions=$1
-fi
-
-##########################
-# Functions
-
-function build (){
- label=$(echo $1 | tr '[:lower:]' '[:upper:]')
- ui_set_yellow && echo "âĄī¸ Running build for $label - ${2} ..." && ui_reset_colors
-
- # Use "docker build"
- docker build \
- --build-arg UPSTREAM_CHANNEL="${DEV_UPSTREAM_CHANNEL}" \
- --build-arg PHP_VERSION="${2}" \
- -t "serversideup/php:beta-${2}-$1" \
- $SCRIPT_DIR/src/$1/
-
- ui_set_green && echo "â
Build completed for $label - ${2} (serversideup/php:beta-${2}-$1)" && ui_reset_colors
-}
-
-function build_versions {
- # Grab each PHP version defined in `build.sh` and deploy these images to our LOCAL registry
- for version in ${phpVersions[@]}; do
- build cli ${version[$i]}
- build fpm ${version[$i]}
- build fpm-apache ${version[$i]}
- build fpm-nginx ${version[$i]}
- done
-}
-
-##########################
-# Main script starts here
-build_versions
\ No newline at end of file
diff --git a/docs/.env.example b/docs/.env.example
index 08b6fe36..e2fe96ab 100644
--- a/docs/.env.example
+++ b/docs/.env.example
@@ -1,5 +1,7 @@
NUXT_APP_BASE_URL=/open-source/docker-php
TOP_LEVEL_DOMAIN=http://localhost:3000
+BASE_PATH=http://localhost:3000/open-source/docker-php
+TOP_LEVEL_DOMAIN=http://localhost:3000
ALGOLIA_API_KEY=changeme
ALGOLIA_APPLICATION_ID=changeme
ALGOLIA_INDEX=changeme
\ No newline at end of file
diff --git a/docs/.nvmrc b/docs/.nvmrc
new file mode 100644
index 00000000..2edeafb0
--- /dev/null
+++ b/docs/.nvmrc
@@ -0,0 +1 @@
+20
\ No newline at end of file
diff --git a/docs/components/Global/OgImage/DocsImage.vue b/docs/components/Global/OgImage/DocsImage.vue
new file mode 100644
index 00000000..bc5448b8
--- /dev/null
+++ b/docs/components/Global/OgImage/DocsImage.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/components/Global/ServerSideUp.vue b/docs/components/Global/ServerSideUp.vue
index de38cde4..e2d83491 100644
--- a/docs/components/Global/ServerSideUp.vue
+++ b/docs/components/Global/ServerSideUp.vue
@@ -1,5 +1,5 @@
-
+
@@ -14,8 +14,28 @@
-
Books
+ class="absolute shadow-sm z-50 bg-white rounded-b-lg p-4 w-64 top-[28px] flex flex-col content-left text-left">
+
Products
+
+
+ Bugflow
+
+
+
Books
Ultimate Guide To APIs & SPAs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Building Multi-Platform Browser Extensions
+
Open-Source Projects
-
-
-
-
+
+
+
+
Spin
diff --git a/docs/components/content/About.vue b/docs/components/content/About.vue
new file mode 100644
index 00000000..10de3083
--- /dev/null
+++ b/docs/components/content/About.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/components/content/CodeGroup.vue b/docs/components/content/CodeGroup.vue
index d6ec31ec..1f677603 100644
--- a/docs/components/content/CodeGroup.vue
+++ b/docs/components/content/CodeGroup.vue
@@ -24,7 +24,7 @@
:label="label"/>
-
+
diff --git a/docs/components/content/CodePanel.vue b/docs/components/content/CodePanel.vue
index 93059b5b..3367487a 100644
--- a/docs/components/content/CodePanel.vue
+++ b/docs/components/content/CodePanel.vue
@@ -1,5 +1,5 @@
-
+
{{ label }}
@@ -8,7 +8,7 @@
diff --git a/docs/components/content/Features.vue b/docs/components/content/Features.vue
index 98b8ac08..e33df059 100644
--- a/docs/components/content/Features.vue
+++ b/docs/components/content/Features.vue
@@ -13,7 +13,7 @@
High Performance
-
These images perform faster than the official PHP images.
+
Get the easiest experience for fine tuning performance.
@@ -21,19 +21,19 @@
Environment variables make customizations a breeze.
-
-
Built on Ubuntu 22.04
-
Work in a familiar and powerful operating system environment.
+
+
Native CloudFlare Support
+
Get real IP addresses from visitors from trusted proxies.
-
-
Built with OndÅej PHP
-
All packages are sourced from the highly reliable OndÅej PHP repo.
+
+
Based on official PHP
+
Upgrade from the official PHP docker images with confidence.
-
NGINX + PHP-FPM
-
We offer NGINX + PHP-FPM support out of the box.
+
NGINX Unit
+
Ditch FPM for a modern way of running PHP. Designed for containers from the ground up.
@@ -42,8 +42,8 @@
-
Built with S6 Overlay
-
An extremely intelligent and powerful method to running PHP.
+
FPM + S6 Overlay
+
Our FPM-Apache & FPM-NGINX images use this intelligent init system.
\ No newline at end of file
diff --git a/docs/components/content/LandingSignup.vue b/docs/components/content/LandingSignup.vue
new file mode 100644
index 00000000..b3cea8fc
--- /dev/null
+++ b/docs/components/content/LandingSignup.vue
@@ -0,0 +1,41 @@
+
+
+
+
đ We're building in public
+
Follow along and get updates delivered right to your inbox.
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/components/content/MarketingGrid.vue b/docs/components/content/MarketingGrid.vue
index ca643b11..3a4c2fd8 100644
--- a/docs/components/content/MarketingGrid.vue
+++ b/docs/components/content/MarketingGrid.vue
@@ -1,7 +1,7 @@
- These are very different from other PHP Docker Images.
+ These images give a lot more than other PHP Docker Images.
@@ -18,7 +18,7 @@
High Performance
-
These images perform faster than the official PHP images.
+
Get the easiest experience for fine tuning performance.
@@ -26,19 +26,19 @@
Environment variables make customizations a breeze.
-
-
Built on Ubuntu 22.04
-
Work in a familiar and powerful operating system environment.
+
+
Native CloudFlare Support
+
Get real IP addresses from visitors from trusted proxies.
-
-
Built with OndÅej PHP
-
All packages are sourced from the highly reliable OndÅej PHP repo.
+
+
Based on official PHP
+
Upgrade from the official PHP docker images with confidence.
-
NGINX + PHP-FPM
-
We offer NGINX + PHP-FPM support out of the box.
+
NGINX Unit
+
Ditch FPM for a modern way of running PHP. Designed for containers from the ground up.
@@ -47,8 +47,8 @@
-
Built with S6 Overlay
-
An extremely intelligent and powerful method to running PHP.
+
FPM + S6 Overlay
+
Our FPM-Apache & FPM-NGINX images use this intelligent init system.
diff --git a/docs/components/content/MarketingHeader.vue b/docs/components/content/MarketingHeader.vue
index 86e6b40d..62c10cf2 100644
--- a/docs/components/content/MarketingHeader.vue
+++ b/docs/components/content/MarketingHeader.vue
@@ -27,7 +27,7 @@
+ class="flex items-center font-inter font-bold text-slate-300 text-sm rounded py-[6px] px-2 hover:text-slate-400 xl:text-lg">
@@ -40,7 +40,7 @@
+ class="flex items-center font-inter font-bold text-slate-300 text-sm rounded py-[6px] px-2 hover:text-slate-400 xl:text-lg">
@@ -53,7 +53,7 @@
+ class="flex items-center font-inter font-bold text-slate-300 text-sm rounded py-[6px] px-2 hover:text-slate-400 xl:text-lg">
diff --git a/docs/components/content/MarketingHero.vue b/docs/components/content/MarketingHero.vue
index b0be7f4d..542a909e 100644
--- a/docs/components/content/MarketingHero.vue
+++ b/docs/components/content/MarketingHero.vue
@@ -1,10 +1,10 @@
- Production-ready PHP environments in seconds.
+ Supercharge your PHP experience, in seconds.
-
Stop the headache from debugging. Get production-ready PHP Docker Images that help you replicate your application, no matter the environment.
+
Built upon the official PHP images, our production-ready serversideup/php images take your Docker PHP experience to the next level. Enjoy variable-first configurations, nginx-unit variation, native CloudFlare support, and more.
diff --git a/docs/components/content/VideoEmbed.vue b/docs/components/content/VideoEmbed.vue
new file mode 100644
index 00000000..06e27620
--- /dev/null
+++ b/docs/components/content/VideoEmbed.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/content/docs/1.index.md b/docs/content/docs/1.index.md
index 3ad94308..e1fa7b97 100644
--- a/docs/content/docs/1.index.md
+++ b/docs/content/docs/1.index.md
@@ -1,5 +1,5 @@
---
-description: 'PHP Docker Images by Server Side Up are an alternate approach to the official Docker images provided by PHP. Compared to the defaults provided by the official PHP Docker images, the serversideup/php Docker images are optimized for more real-world and production use cases.'
+description: 'serversideup/php is an alternate approach to the official Docker images provided by PHP. Compared to the defaults provided by the official PHP Docker images, the serversideup/php Docker images are optimized for more real-world and production use cases and an easier developer experience.'
head.title: 'Introduction - Docker Images - Server Side Up'
layout: docs
---
@@ -8,11 +8,11 @@ layout: docs
-## What's "PHP Docker Images"?
+## What's "serversideup/php"?
::badges
::
-PHP Docker Images by Server Side Up (`serversideup/php`) are an alternate approach to the official Docker images provided by PHP. Compared to the defaults provided by the official PHP Docker images, the `serversideup/php` Docker images are optimized for more real-world and production use cases.
+**serversideup/php** is an alternate approach to the official Docker images provided by PHP. Compared to the defaults provided by the official PHP Docker images, the **serversideup/php** Docker images are optimized for more real-world and production use cases and an easier developer experience.
## These images are very different from other PHP Docker images
::features
diff --git a/docs/content/docs/2.getting-started/1.these-images-vs-others.md b/docs/content/docs/2.getting-started/1.these-images-vs-others.md
index 2c83dcf4..303f4740 100644
--- a/docs/content/docs/2.getting-started/1.these-images-vs-others.md
+++ b/docs/content/docs/2.getting-started/1.these-images-vs-others.md
@@ -8,94 +8,34 @@ layout: docs
| | **Official PHP Images** |**serversideup/php** |
|-------------------------|-------------------------|---------------------|
-| Run latest version of PHP with Docker | â
| â
|
-| PHP Compilation | PHP Source Code | [OndÅej SurÃŊ PPA](https://launchpad.net/~ondrej/+archive/ubuntu/php/+packages) |
-Base Operating System | Debian, Alpine | Ubuntu 22.04 |
-Init System | Basic, built-in with OS | [S6-Overlay](https://github.com/just-containers/s6-overlay) |
+| Base Operating System | Debian, Alpine | Debian, Alpine |
+| PHP Compilation | PHP Source Code | PHP Source Code (based on official PHP images) |
+| Run PHP, pinned to the minor version | â
| â
|
+| Multi-arch support | â
| â
|
+| Init System | Docker CMD | Docker CMD or [S6-Overlay](https://github.com/just-containers/s6-overlay) |
+| Published Registry| DockerHub | [DockerHub](https://hub.docker.com/r/serversideup/php), [GitHub Packages](https://github.com/serversideup/docker-php/pkgs/container/php) |
+| Variable-first configuration | â | â
|
+| Includes `composer` | â | â
|
+| Includes [`install-php-extensions`](https://github.com/mlocati/docker-php-extension-installer) | â | â
|
| Production-Ready by default| â | â
|
| Built-in security optimizations | â | â
|
-Optimized for Laravel & WordPress| â | â
|
-NGINX + FPM variation| â | â
|
-Native health checks | â | â
|
+| Optimized for Laravel & WordPress| â | â
|
+| NGINX + FPM variation| â | â
|
+| NGINX Unit variation| â | â
|
+| Native health checks | â | â
|
-## What's S6 Overlay?
-[S6 Overlay](https://github.com/just-containers/s6-overlay) is a process supervisor designed for containerization from the ground up. It's a modern alternative to [Supervisor (aka Supervisord)](https://supervisord.org/).
+## Variable-first Configuration
+Our design philosophy is built all around simplicity. The process of customizing the behavior of PHP is as simple as setting an environment variable. We took every common configuration option and set it up so you can change these values in a simple method, defaulting every single option to production-ready values.
-S6 Overlay is a perfect match for running PHP because it usually requires running multiple processes together.
+See our [environment variable specifications](/docs/reference/environment-variable-specification) for more information.
-## Why does PHP need multiple processes?
-Serving a PHP application can be broken down into two different components:
-1. The PHP Application Itself
-2. The static files that go with it (JavaScript, images, etc)
+## Optimized for Laravel & WordPress
+We did the hard work of customizing the official PHP image and giving you everything to get started with running PHP's most popular frameworks in seconds. We also hardened the images to help protect your PHP application from common attacks.
-There are ways to have these components served together with Apache modules like "mod_php". As time moved on, we found this to be very resource inefficient.
+## Production-ready
+We believe images should be ready for production and able to live in the open and wild Internet. We took our years of experience and tweaked these images to be performant and secure as possible. Having these values published online allows others to review, contribute, and improve the images -- giving you the best security and performance possible.
-Running "mod_php" with Apache meant that even when a JavaScript file needs to be loaded, Apache would load PHP to serve that file. This caused a lot of unnecessary memory and CPU usage for files that didn't need PHP to be served.
+## What is "S6 Overlay?"
+[S6 Overlay](https://github.com/just-containers/s6-overlay) is a process supervisor designed for containerization from the ground up. It's a modern alternative to [Supervisor (aka Supervisord)](https://supervisord.org/). We only use this in our `serversideup/php:*-fpm-apache` and `serversideup/php:*-fpm-nginx` images, as they require two processes to run a service.
-### PHP-FPM
-PHP-FPM was the answer to make this serving a PHP application more efficient. This allowed PHP apps to be served with a lot less memory and CPU overhead.
-
-Although this method was more efficient, it meant we still need something to serve our static content. This is where we turned to "reverse proxies".
-
-### Reverse proxy
-Reverse proxies are servers that route traffic based on the request. To make things more confusing, you can have a web server be a reverse proxy and a web server at the same time (this is how we run NGINX). You can even configure Apache to run as a web server and a reverse proxy too (we run our `php:*-fpm-apache` images like this).
-
-
-
-In the example above, you can see the web request coming in from the top. NGINX is our first stop where it inspects the request.
-
-#### Static Files
-If the request is for a static file (jpeg, js, png, etc), NGINX will also serve that file for us without loading PHP-FPM. This makes the request very fast and efficient.
-
-#### PHP Files
-If the request ends in `.php`, then it will send the request over to PHP-FPM. PHP-FPM will then execute the PHP file and return a response to the original client, all passed through NGINX.
-
-## Shouldn't containers only have one process?
-In a perfect world, that would be ideal -- but this isn't always realistic. You can see in the example above we need two things running:
-1. NGINX: To serve static files
-1. PHP-FPM: To serve PHP application
-
-If you want to replicate your application without the added complexity of multiple physical servers, etc -- you need something like S6 Overlay to properly bring up the processes and ensure your application service health is accurately reported.
-
-[S6 Overlay's philosophy](https://github.com/just-containers/s6-overlay#the-docker-way) is a perfect match when it comes to running PHP:
-
-- A container should do ***one thing*** (which may contain multiple processes). When that one thing stops, the container should also stop.
-
-## The advantages of S6 Overlay
-When we configure PHP to run with the S6 Overlay system, we get a number of advantages:
-
-- â
S6 Overlay was designed from the ground up to run within containers
-- â
We get explicit control to run small scripts or configurations before/after the main processes start
-- â
We get a better confidence on answering "Is my container actually healthy?"
-
-## S6 Overlay vs. Supervisor
-Many people flock to Supervisor, which was a very popular option before containerization. Here's some examples why you may want to trade Supervisor for S6 Overlay:
-
-### How Supervisor reports container health
-
-
-When you bring up Supervisord within a container, it will be assigned `PID 1`. Then Supervisor will bring up child processes with it.
-
-During a failure, Supervisor can be configured to restart the child process to attempt recovery, but the container orchestrator thinks the container is still healthy because `supervisord` is occupying `PID 1` which is still healthy.
-
-**đ This design can lead to inaccurate container health statuses during a failure.**
-
-### How S6 Overlay reports container health
-
-S6 Overlay was designed to be run in containers from the ground up. S6 Overlay can also attempt recovery, but it is more accurate on determining container health compared to Supervisor.
-
-**đ By design, S6 Overlay can accurately detect a failure and exit (which is what we want when our app fails).**
-
-## Customizing the initialization process
-
-Since S6 Overlay was designed around the idea of containerization, there are also a number of other advantages to properly time your customizations during container startup.
-
-S6 Overlay has a number of options to [write our own service script](https://github.com/just-containers/s6-overlay/tree/master#writing-a-service-script) and properly time everything.
-
-In the example above, you can see we have a `runas-user` script which helps us customize and set custom UIDs and GIDs for our file permissions. At the same time, `laravel-automations` executes to see if there are any automated migrations to run.
-
-Both scripts must finish successfully before S6 Overlay starts our main `php-fpm` process, which has both scripts listed as a dependency.
-
-As you can see this structure can be very powerful in making your own customizations. This is great for giving you full control of how you'd like your application to behave.
-
-[Read how to make customizations â](/docs/guide/customizing-the-image)
\ No newline at end of file
+[Learn more about S6 Overlay â](/docs/guide/using-s6-overlay)
\ No newline at end of file
diff --git a/docs/content/docs/2.getting-started/2.installation.md b/docs/content/docs/2.getting-started/2.installation.md
index 74a2a5fd..3df12a8b 100644
--- a/docs/content/docs/2.getting-started/2.installation.md
+++ b/docs/content/docs/2.getting-started/2.installation.md
@@ -10,51 +10,102 @@ layout: docs
::
::lead-p
-All images are hosted on [DockerHub](https://hub.docker.com/r/serversideup/php) for free.
+All images are hosted on [DockerHub](https://hub.docker.com/r/serversideup/php) and [GitHub Packages](https://github.com/serversideup/docker-php/pkgs/container/php) for free. Containers default to running Debian, but Alpine images are also available.
::
-## Image Variations
+## Our most popular images
+All images are intelligently tagged with the PHP version and variation. This allows you to easily select the right image for your use case.
+
+If you do not specify a variation, it will default to `cli` and the latest supported Debian release for that variation.
+
+Our most popular tags include:
| âī¸ Variation | đ Version |
| ------------ | ---------- |
-| cli | [](https://hub.docker.com/r/serversideup/php/tags?name=8.2-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.1-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.0-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=7.4-cli&page=1&ordering=-name) |
-| fpm | [](https://hub.docker.com/r/serversideup/php/tags?name=8.2-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.1-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.0-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=7.4-fpm&page=1&ordering=-name) |
-| fpm-apache | [](https://hub.docker.com/r/serversideup/php/tags?name=8.2-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.1-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.0-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=7.4-fpm-apache&page=1&ordering=-name) |
-| fpm-nginx | [](https://hub.docker.com/r/serversideup/php/tags?name=8.2-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.1-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.0-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=7.4-fpm-nginx&page=1&ordering=-name) |
+| cli | [](https://hub.docker.com/r/serversideup/php/tags?name=8.3-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.2-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.1-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.0-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=7.4-cli&page=1&ordering=-name) |
+| fpm | [](https://hub.docker.com/r/serversideup/php/tags?name=8.3-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.2-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.1-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.0-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=7.4-fpm&page=1&ordering=-name) |
+| fpm-apache | [](https://hub.docker.com/r/serversideup/php/tags?name=8.3-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.2-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.1-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.0-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=7.4-fpm-apache&page=1&ordering=-name) |
+| fpm-nginx | [](https://hub.docker.com/r/serversideup/php/tags?name=8.3-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.2-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.1-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.0-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=7.4-fpm-nginx&page=1&ordering=-name) |
+| unit | [](https://hub.docker.com/r/serversideup/php/tags?name=8.3-unit&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.2-unit&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.1-unit&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=8.0-unit&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/tags?name=7.4-unit&page=1&ordering=-name) |
## Selecting the right variation
There are 4 main variations.
### CLI
-If you need to run a quick command with `composer` or use PHP to run a CLI program only, this might be a great option for you.
+If you need to run a quick command with something like `composer` or use PHP to run a CLI program only, this might be a great option for you.
### FPM
The `fpm` variation is great for people who need to run a PHP "backend" if they already have a proxy serving static content. If you're using FPM only, that means you're probably at a larger scale.
### FPM-Apache
-The `fpm-apache` variation is meant for users who want to run something like WordPress with Docker. Apache is configured to be a "reverse proxy", which will serve any static content with Apache and serve any PHP requests with PHP-FPM.
+The `fpm-apache` variation is meant for users who want to run something like WordPress with Docker. Apache is configured to be a "reverse proxy", which will serve any static content with Apache and serve any PHP requests with PHP-FPM. Since there are two processes required to run this variation, we use [S6 Overlay](/docs/guide/using-s6-overlay) to ensure the container health is accurate.
+
+[Learn more about using Docker with WordPress â](/docs/wordpress/wordpress-optimizations)
### FPM-NGINX
-The `fpm-nginx` variation is great for people who want to run Laravel applications or similar. This allows you to serve static content quickly with NGINX but also pass PHP requests to PHP-FPM. This variation is great place to start if you're trying to containerize your application easily.
+The `fpm-nginx` variation is great for people who want to run Laravel applications or similar. This allows you to serve static content quickly with NGINX but also pass PHP requests to PHP-FPM. Similar to PHP-Apache, there are two proccess required to run this variation. We use S6 Overlay to ensure the container health is accurate.
+
+[Learn more about S6 Overlay â](/docs/guide/using-s6-overlay)
+
+### Unit
+The `unit` variation is for NGINX Unit, which is a modern approach to delivering containerized web applications. Instead of relying on the complexities of two processes running NGINX + PHP-FPM, Unit replaces both the NGINX Web Server and PHP-FPM to run everything under one process. Unit is open source and maintained by the NGINX Unit team.
+
+[Learn more about Unit â](https://unit.nginx.org/)
+
+## Selecting the version of PHP
+Selecting the best version of PHP is highly dependent on your use case. In a perfect world, running the latest version of PHP will give you the latest and greatest, but it all depends on the libraries that your application uses.
+
+For example, if you're running a WordPress site with a ton of different plugins, they may be using libraries that do not yet support the latest version of PHP. Be sure to evaluate your dependencies and test your application before deploying to production.
+
+All versions + variations are tagged by:
+- Major Version (example: `8` will give you the latest 8.x version)
+- Minor Version (example: `8.3` will give you the latest 8.3.x version)
+- Patch Version (example: `8.3.2` will alway stay at the 8.3.2 version)
+
+If you use `latest`, you will always get the latest stable version of the CLI variation of PHP running the latest version of Debian. For the best stability in production environments, you may want to pin to a specific patch version (example: `8.3.2`).
+
+::code-panel
+---
+label: The Full Image Tag Standard
+---
+```bash
+{{registry-url}}/serversideup/php:{{release-prefix}}-{{php-version}}-{{variation-name}}-{{operating-system}}
+```
+::
+
+### Few examples
-## How images are tagged
::code-panel
---
-label: Image tag standard
+label: Latest version of 8.3.x running FPM + NGINX from Github Packages
---
```bash
-serversideup/php:{{php-version}}-{{variation-name}}
+ghcr.io/serversideup/php:8.3-fpm-nginx
```
::
::code-panel
---
-label: For example...Selecting PHP 8.1 with FPM + NGINX
+label: 8.1.16 running FPM + Apache on Alpine from DockerHub
---
```bash
-serversideup/php:8.1-fpm-nginx
+serversideup/php:8.1.16-fpm-apache-alpine
```
::
+::code-panel
+---
+label: Beta version (of this repository, not PHP) running PHP CLI 8.x
+---
+```bash
+serversideup/php:beta-8
+```
+::
+
+## Viewing all available images & tags
+All our images are available on DockerHub and GitHub Packages (ghcr.io). You can use their built-in search functions to browse through our entire collection of Docker Images:
+- [View on Docker Hub â](https://hub.docker.com/r/serversideup/php)
+- [View on GitHub Packages â](https://github.com/serversideup/docker-php/pkgs/container/php)
+
## Downloading an image
In the simplest form of using the image, you can simply pull it down.
@@ -63,7 +114,7 @@ In the simplest form of using the image, you can simply pull it down.
label: Pull an image with Docker
---
```bash
-docker pull serversideup/php:8.1-fpm-nginx
+docker pull serversideup/php:8.3-fpm-nginx
```
::
@@ -74,7 +125,7 @@ If you'd like to explore the image a little bit more, you can run `bash` on the
label: Explore the image with Bash
---
```bash
-docker run --rm --name php -it serversideup/php:8.1-fpm-nginx bash
+docker run --rm --name php -it serversideup/php:8.3-fpm-nginx bash
```
::
diff --git a/docs/content/docs/2.getting-started/3.default-configurations.md b/docs/content/docs/2.getting-started/3.default-configurations.md
new file mode 100644
index 00000000..fbd4b8fc
--- /dev/null
+++ b/docs/content/docs/2.getting-started/3.default-configurations.md
@@ -0,0 +1,66 @@
+---
+head.title: 'Installation - Docker PHP - Server Side Up'
+description: 'Learn how to get started with serversideup/php Docker Images.'
+layout: docs
+---
+
+# Default Configurations
+::lead-p
+`serversideup/php` is configured for real-world deployments right out of the box. This saves you many hours so you can launch faster than ever.
+::
+
+## Production-ready and optimized for Laravel & WordPress
+All values are defaulted to improve security and performance. We also spent the time to carefully review official documentation and include packages that are required specifically for Laravel and WordPress.
+
+## Default Environment Variables
+We allow the ability to customize the behavior of PHP with environment variables. Be sure to review our production-ready default values on our [environment variable specification](/docs/reference/environment-variable-specification) page.
+
+## Default PHP Extensions
+The following extensions are installed by default:
+
+| **Extension** | **Description** | **Why we included it** |
+|---------------|-----------------|------------------------|
+| [pcntl](https://www.php.net/manual/en/intro.pcntl.php) | Process Control support in PHP implements the Unix style of process creation, program execution, signal handling and process termination. | This is required for [Laravel queues and Laravel Horizon](https://laravel.com/docs/10.x/queues#timeout)|
+| [pdo_mysql](https://www.php.net/manual/en/ref.pdo-mysql.php) | The MySQL PDO extension allows you to connect to MySQL databases. | MySQL and MariaDB databases are very popular. |
+| [pdo_pgsql](https://www.php.net/manual/en/ref.pdo-pgsql.php) | The PostgreSQL PDO extension allows you to connect to PostgreSQL databases. | PostgreSQL databases are very popular. |
+| [redis](https://www.php.net/manual/en/book.redis.php) | The Redis extension allows you to connect to Redis databases. | Redis is very popular for caching and it's also required for [Laravel Horizon](https://laravel.com/docs/10.x/horizon). Our tests concluded adding this package only added 2MB to the image size. |
+| [zip](https://www.php.net/manual/en/book.zip.php) | The Zip extension allows you to create and extract zip files. | We included this for the popularity of apps working with ZIP files. This package is also required if you're working with attachments on [Laravel Dusk](https://laravel.com/docs/10.x/dusk#attaching-files). |
+
+The official PHP images are already providing the following extensions:
+- ctype
+- curl
+- dom
+- fileinfo
+- filter
+- hash
+- mbstirng
+- openssl
+- pcre
+- session
+- tokenizer
+- xml
+
+## Default Operating System Packages
+The following packages are installed by default:
+
+| **Package** | **Description** | **Image variations** | **Why we included it** |
+|-------------|-----------------|----------------------|------------------------|
+| `fcgi` (Debian) `libfcgi-bin` (Alpine) | FastCGI is a protocol for interfacing interactive programs with a web server. | *-fpm-nginx *-fpm-apache | This is required for the webserver to interface with PHP-FPM |
+| `gettext` (Debian) `gettext-base` (Alpine) | GNU gettext is a framework for translating user interfaces. | *-fpm-nginx *-fpm-apache | This is required for the `envsubst` command. We use this command to process templates on container initialization. |
+| `shadow` | Shadow is required for the `usermod` command. | *-alpine | This is required to change the UID and GID of the `www-data` user in `docker-php-serversideup-set-id`. |
+
+## Default Entrypoint Scripts
+We created an entrypoint script that scans the `entrypoint.d` directory for other shell scripts to execute before the main container process starts. All scripts are executed in alphabetical order so you can have full control over what script execution order.
+
+We also provide a few default scripts to help you get started.
+
+| **Script Name** | **Description** | **Image variations** |
+|------------|-----------------|----------------------|
+| `0-container-info.sh` | Shows basic execution information, such as Docker User, UID, GID, etc. | all |
+| `1-debug-mode.sh` | Sets PHP to debug mode if `LOG_LEVEL = "debug"` | all |
+| `10-init-unit.sh` | Processes Unit templates, configures SSL (if enabled), and prepares NGINX Unit for launch | unit |
+| `10-init-webserver-config.sh` | Processes web server configuration templates, configures SSL (if enabled), and prepares web server for launch | *-nginx *-apache |
+| `50-laravel-automations.sh` | If `AUTORUN_ENABLED` is set to true, and a Laravel installation is detected, the following commands will automatically execute on container start: - `php artisan config:cache` - `php artisan route:cache` - `php artisan view:cache` - `php artisan event:cache` - `php artisan migrate --force --isolated` | all |
+
+## Disabling Default Entrypoint Scripts
+If you want full control to customize your image, all default entrypoint scripts can be disabled by setting `DISABLE_DEFAULT_CONFIG` to `true`.
\ No newline at end of file
diff --git a/docs/content/docs/2.getting-started/3.upgrade-guide.md b/docs/content/docs/2.getting-started/3.upgrade-guide.md
index 3f444123..220da510 100644
--- a/docs/content/docs/2.getting-started/3.upgrade-guide.md
+++ b/docs/content/docs/2.getting-started/3.upgrade-guide.md
@@ -5,71 +5,31 @@ layout: docs
---
# Upgrading
-There are two methods for choosing how you'd like to manage upgrades.
+If you do not select a specific patch version, then you will receive automatic PHP updates.
-1. Automatic updates
-1. Locking into a release
+For example, you can select your version based on the different version numbers:
+- Major Version (example: `8` will give you the latest 8.x version)
+- Minor Version (example: `8.3` will give you the latest 8.3.x version)
+- Patch Version (example: `8.3.2` will alway stay at the 8.3.2 version)
-Before we dive into these two options, let's talk about the release process.
+If you use `latest`, you will always get the latest stable version of the CLI variation of PHP. For the best stability in production environments, you may want to pin to a specific patch version (example: `8.3.2`).
## Release process
All source code is merged into the `main` branch, which automatically build our "beta" images.
After testing the images internally and from other community members, we will [publish a release on GitHub](https://github.com/serversideup/docker-php/releases) with a detailed changelog.
-## Automatic Updates
-If you choose an image following our guide on [how images are tagged](/docs/getting-started/installation#how-images-are-tagged), then these images will receive automatic updates.
-
-::code-panel
----
-label: This tag format will receive automatic updates
----
-```bash
-serversideup/php:{{php-version}}-{{variation-name}}
-```
-::
-
-Every Tuesday at 0800 UTC our images will rebuild giving you the latest dependency updates.
-
-This is great for automated security, but if you're making a lot of customizations we *do not* recommend you using automated updates.
-
-Instead, you may want to consider locking into a tagged version.
-
-## Locking into a release
-If you're making a lot of customizations or have a disciplined dependency management process, it is advised that you lock into a version and upgrade following your own change process.
-
-To do this, you just need to add the version number at the end.
-
-::code-panel
----
-label: This will lock your version
----
-```bash
-serversideup/php:{{php-version}}-{{variation-name}}-v{{version-number}}
-```
-::
-
-**These images are built once and will never receive any automatic updates.**
-
-::code-panel
----
-label: For example... this would lock into our `v2.1.0` release
----
-```bash
-serversideup/php:8.2-fpm-apache-v2.1.0
-```
-::
+## Updating the Docker images on your own
+If you You and simply run `apt-get update && apt-get upgrade` within your own image, but still want the image to receive other operating system updates, you will need to run the following commands on your build.
-You can take care of the dependency updates on your own and upgrade under your own discretion.
+Any updates that you apply have a risk of breaking other things inside the container. Be sure to have a good testing process in place before applying updates to your production environment.
-## Updating the Docker images on your own
-You and simply run `apt-get update && apt-get upgrade` within your own image
::code-panel
---
label: Example Dockerfile with manual updates
---
-```Dockerfile
-FROM serversideup/php:8.2-fpm-nginx-v2.1.0
+```txt
+FROM serversideup/php:8.3.2-fpm-nginx
RUN apt-get update \
&& apt-get upgrade -y \
@@ -78,7 +38,6 @@ RUN apt-get update \
```
::
-You would just add this to the top of your custom Dockerfile and it would install all package updates for you on demand.
## Subscribe to repository updates
Regardless if you are choosing to use automatic updates or manual updates, it is highly advised to subscribe to our releases. You can do this through the "Watch" button on our [GitHub](https://github.com/serversideup/docker-php).
diff --git a/docs/content/docs/2.getting-started/5.changelog.md b/docs/content/docs/2.getting-started/5.changelog.md
index 83e17223..afa243d3 100644
--- a/docs/content/docs/2.getting-started/5.changelog.md
+++ b/docs/content/docs/2.getting-started/5.changelog.md
@@ -5,7 +5,7 @@ layout: docs
---
# Changelog
-[All our changes are documented and published on our GitHub â](https://github.com/serversideup/docker-php/releases)
+All our changes are documented and published on our GitHub. [See our release notes on GitHub â](https://github.com/serversideup/docker-php/releases)
### Choosing a version
-You may want to review [our guide on selecting the right image](/docs/guide/choosing-the-right-image) to determine which version and image tag is best for you.
\ No newline at end of file
+You may want to review [our guide on selecting the right image](/docs/getting-started/installation#selecting-the-right-variation) to determine which version and image tag is best for you.
\ No newline at end of file
diff --git a/docs/content/docs/2.getting-started/6.about.md b/docs/content/docs/2.getting-started/6.about.md
index 7e0b6d70..a96e512d 100644
--- a/docs/content/docs/2.getting-started/6.about.md
+++ b/docs/content/docs/2.getting-started/6.about.md
@@ -5,15 +5,51 @@ layout: docs
---
# About this project
-We're taking the extra effort to open source as much as we can. Not only could this potentially help someone learn a little bit of Docker, but it makes it a *heck of a lot* easier for us to work with you on new open source ideas.
+We're taking the extra effort to open source as much as we can. Not only could this potentially help someone learn a little bit of Docker, but it makes it a *heck of a lot* easier for us to work with other people on our other open source projects.
-## Project credits & inspiration
+## About Us
+We're [Dan](https://twitter.com/danpastori) and [Jay](https://twitter.com/jaydrogers) - a two person team with a passion for open source products. We created [Server Side Up](https://serversideup.net) to help share what we learn.
+
+::about
+::
+
+### Find us at:
+
+* **đ [Blog](https://serversideup.net)** - Get the latest guides and free courses on all things web/mobile development.
+* **đ [Community](https://community.serversideup.net)** - Get friendly help from our community members.
+* **đ¤ĩââī¸ [Get Professional Help](https://serversideup.net/professional-support)** - Get video + screen-sharing support from the core contributors.
+* **đģ [GitHub](https://github.com/serversideup)** - Check out our other open source projects.
+* **đĢ [Newsletter](https://serversideup.net/subscribe)** - Skip the algorithms and get quality content right to your inbox.
+* **đĨ [Twitter](https://twitter.com/serversideup)** - You can also follow [Dan](https://twitter.com/danpastori) and [Jay](https://twitter.com/jaydrogers).
+* **â¤ī¸ [Sponsor Us](https://github.com/sponsors/serversideup)** - Please consider sponsoring us so we can create more helpful resources.
+
+## Our products
+If you appreciate this project, be sure to check out our other projects.
+
+### đ Books
+- **[The Ultimate Guide to Building APIs & SPAs](https://serversideup.net/ultimate-guide-to-building-apis-and-spas-with-laravel-and-nuxt3/)**: Build web & mobile apps from the same codebase.
+- **[Building Multi-Platform Browser Extensions](https://serversideup.net/building-multi-platform-browser-extensions/)**: Ship extensions to all browsers from the same codebase.
+
+### đ ī¸ Software-as-a-Service
+- **[Bugflow](https://bugflow.io/)**: Get visual bug reports directly in GitHub, GitLab, and more.
+- **[SelfHost Pro](https://selfhostpro.com/)**: Connect Stripe or Lemonsqueezy to a private docker registry for self-hosted apps.
+
+### đ Open Source
+- **[AmplitudeJS](https://521dimensions.com/open-source/amplitudejs)**: Open-source HTML5 & JavaScript Web Audio Library.
+- **[Spin](https://serversideup.net/open-source/spin/)**: Laravel Sail alternative for running Docker from development â production.
+- **[Financial Freedom](https://github.com/serversideup/financial-freedom)**: Open source alternative to Mint, YNAB, & Monarch Money.
+
+## Special thanks
+This project wouldn't be possible without the help of some amazing people. We're grateful for their support and contributions. We wanted to give them a special shoutout here (in no particular order).
### [Chris Fidao](https://github.com/fideloper)
-Majority of our knowledge came from Chris' course, [Shipping Docker](https://serversforhackers.com/shipping-docker). If you have yet to discover his content, you will be very satisfied with every course he has to offer. He's a great human being and excellent educator.
+Majority of our knowledge came from Chris' course, [Shipping Docker](https://serversforhackers.com/shipping-docker). If you have yet to discover his content, you will be very satisfied with every course he has to offer. He's a great human being and excellent educator. Chris has continuously provided quality feedback that has deeply inspired the direction of this project.
+
+### [Joel Clermont](https://github.com/joelclermont/)
+Joel is one of the friendliest people that you'll ever meet. When he's not podcasting on his own show, [No Compromises](https://show.nocompromises.io/), he's busy helping other people in the PHP community. Joel's deep experience with PHP is rare to find, and we're grateful that we were able to pick his brain to bring you the best PHP Docker experience possible.
-### [PHPDocker.io](https://github.com/phpdocker-io/base-images)
-This team has an excellent repository and millions of pulls per month. We really like how they structured their code.
+### [Patricio](https://github.com/ijpatricio)
+If there's a new framework or tool in the web development world, Patricio probably has content for it on his [YouTube Channel](https://www.youtube.com/@PatricioOnCode). Patricio is a great resource for all things web development. Frontend, backend, DevOps -- it doesn't matter. Patricio graciously shared his wide spectrum of experiences with us and is a huge supporter of this project.
### [linuxserver.io](https://www.linuxserver.io/)
-These guys are absolute aces when it comes to Docker development. They are a great resource for tons of open source Docker images.
\ No newline at end of file
+These guys are absolute aces when it comes to Docker development. They are a great resource for tons of open source Docker images. Check out their work, especially if you're a homelabber.
\ No newline at end of file
diff --git a/docs/content/docs/2.getting-started/7.contributing.md b/docs/content/docs/2.getting-started/7.contributing.md
index bdec10ba..3801dbdd 100644
--- a/docs/content/docs/2.getting-started/7.contributing.md
+++ b/docs/content/docs/2.getting-started/7.contributing.md
@@ -5,11 +5,7 @@ layout: docs
---
# Contributing
-Thanks for your interest in contributing to this project!
-
-As stated in the README, there are a lot of down-stream dependencies on these images, so please understand that it can make it complicated on merging your pull request.
-
-We'd love to have your help, but it might be best to explain your intentions first before contributing.
+Thanks for your interest in contributing to this project! Please use read this entire guide before submitting a pull request.
## Project dependencies
You must have these installed on your system.
@@ -20,29 +16,74 @@ You must have these installed on your system.
1. Github Actions will automatically build and deploy the images
## Running things locally
+To run a build, simply run `./scripts/dev.sh` (with Docker Desktop running). This will show you a help menu with all the available options.
+
+::code-panel
+---
+label: "Example: Building a Unit image running PHP 8.2.12 on Debian Bookworm"
+---
+```bash
+bash scripts/dev.sh --variation unit --version 8.2.12 --os bookworm
+```
+::
-To run a build, simply run `./dev.sh` (with Docker Desktop Running). This will automatically build the beta images on your local machine. If you want to only build a specific version, you pass it a version you want to build (example: `./dev.sh 8.1`)
+This will build `serversideup/php:8.2.12-unit-bookworm` locally on your machine for testing and inspection.
-#### Viewing the images
-After running the build, you should be able to run `docker images` to see all available images on your machine. Everything built with `./dev.sh` will be tagged `serversideup/php:beta-*`.
+### Published Beta Images
+We also have beta images that are published from the [`release/v3.0`](https://github.com/serversideup/docker-php/tree/release/v3.0) branch (or the "main" branch once v3.0 is released).
-### Beta Images
+#### Debian Variations
| âī¸ Variation | đ Version |
| ------------ | ---------- |
-| cli | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-cli&page=1&ordering=-name) |
-| fpm | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-fpm&page=1&ordering=-name) |
-| fpm-apache | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-fpm-apache&page=1&ordering=-name) |
-| fpm-nginx | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-fpm-nginx&page=1&ordering=-name) |
+| cli | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.3-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-cli&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-cli&page=1&ordering=-name) |
+| fpm | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.3-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-fpm&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-fpm&page=1&ordering=-name) |
+| fpm-apache | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.3-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-fpm-apache&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-fpm-apache&page=1&ordering=-name) |
+| fpm-nginx | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.3-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-fpm-nginx&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-fpm-nginx&page=1&ordering=-name) |
+| unit | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.3-unit&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-unit&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-unit&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-unit&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-unit&page=1&ordering=-name) |
+#### Alpine Variations
+To see the size difference between Debian and Alpine, here is a list of our Alpine versions:
+
+| âī¸ Variation | đ Version |
+| ------------ | ---------- |
+| cli | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.3-cli-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-cli-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-cli-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-cli-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-cli-alpine&page=1&ordering=-name) |
+| fpm | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.3-fpm-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-fpm-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-fpm-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-fpm-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-fpm-alpine&page=1&ordering=-name) |
+| fpm-apache | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.3-fpm-apache-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-fpm-apache-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-fpm-apache-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-fpm-apache-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-fpm-apache-alpine&page=1&ordering=-name) |
+| fpm-nginx | [](https://hub.docker.com/r/serversideup/php/?name=beta-8.3-fpm-nginx-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.2-fpm-nginx-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.1-fpm-nginx-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-8.0-fpm-nginx-alpine&page=1&ordering=-name) [](https://hub.docker.com/r/serversideup/php/?name=beta-7.4-fpm-nginx-alpine&page=1&ordering=-name) |
+| unit | â ī¸ Unit does not have an Alpine version. [See the known issue â](https://github.com/serversideup/docker-php/issues/233) |
#### Running a test web server:
-This is helpful for testing things out:
+Sometimes you need to just run a test web server locally to see if your changes work. Below is a good example on how to quickly do this.
::code-panel
---
-label: Run a simple container for testing
+label: "Example: Run a simple container for testing"
---
```bash
-docker run --rm -v $(pwd):/var/www/html -p 80:80 -p 443:443 serversideup/php:beta-8.2-fpm-nginx
+docker run --rm -v $(pwd):/var/www/html -p 80:80 -p 443:443 serversideup/php:beta-8.3-fpm-nginx
```
-::
\ No newline at end of file
+::
+
+## How PHP Versions are selected for distribution
+We use the official PHP versions as our base image. To identify which versions should be built, we use a file called `scripts/conf/php-versions-base-config.yml` to explicitly select what versions should be built and any special rules/settings for each version (like base OS, default versions, etc).
+
+We then use a `scripts/get-php-versions.sh` script to download the [latest active releases from PHP](https://www.php.net/releases/active.php) and merge them into a final file called `scripts/conf/php-versions.yml`.
+
+The `php-versions.yml` file will include all final versions for tagging and building.
+
+We generate our tags with a file called `scripts/assemble-docker-tags.sh` which handles all the advanced logic of compiling our tags together.
+
+All the scripts above are designed to run locally and in GitHub Actions. Feel free to execute these scripts to see the help menus and how they work.
+
+## GitHub Actions
+We use GitHub Actions exclusively to publish all of our releases. If the image exists from DockerHub or GitHub Packages, it will never be published from a local machine.
+
+See `.github/workflows/action_publish-beta-images.yml` for an example of how we publish our beta images.
+
+## Helping out
+If you're really eager to help out, here are a few places to get started:
+- Help answer questions on [our GitHub Discussions](https://github.com/serversideup/docker-php/discussions) and [our Discord](https://serversideup.net/discord)
+- Chime in on [issues labeled "Help Wanted"](https://github.com/serversideup/docker-php/issues?q=is%3Aissue+is%3Aopen+label%3A%22%F0%9F%99%8F+Help+Wanted%22)
+- [Open a feature request](https://github.com/serversideup/docker-php/discussions/66) and tell us how we can improve
+- Run performance tests and share your results
+- Say good things and tag us on X (formerly Twitter): [@serversideup](https://x.com/serversideup), [@danpastori](https://x.com/danpastori), [@jaydrogers](https://x.com/jaydrogers)
\ No newline at end of file
diff --git a/docs/content/docs/3.guide/1.choosing-the-right-image.md b/docs/content/docs/3.guide/1.choosing-the-right-image.md
deleted file mode 100644
index 7a12de53..00000000
--- a/docs/content/docs/3.guide/1.choosing-the-right-image.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-head.title: 'Choosing the right image - Docker PHP - Server Side Up'
-description: 'Learn the differences between each image variation and how to select the right one.'
-layout: docs
----
-
-# Choosing the right image
-We offer many variations, so it can be overwhelming when choosing an image to use.
-
-## Selecting a PHP Version
-PHP is constantly evolving. Every release is making PHP faster and more secure. It's usually best to be on the latest version to take advantage of the security and performance features. [Check PHP's official "Supported Versions" site](https://www.php.net/supported-versions.php) to get the latest information.
-
-Choosing the PHP version highly depends on your code's compatibility for the latest features. Be sure to have automated integration tests to help build your confidence when upgrading versions of PHP.
-
-## CLI
-Our [CLI variation](https://hub.docker.com/r/serversideup/php/tags?page=1&name=cli) has the components of PHP Command Line Interface only.
-
-Great to use for:
-* Installing composer packages locally
-* You need a lightweight PHP CLI instance for a quick job
-
-## FPM
-Our [FPM variation](https://hub.docker.com/r/serversideup/php/tags?page=1&name=fpm) has the components of PHP FastCGI Process Manager (FPM) only.
-
-Great to use for:
-* Larger scale apps who have a web server or load balancer already
-
-## FPM-Apache
-Our [FPM-Apache variation](https://hub.docker.com/r/serversideup/php/tags?page=1&name=fpm-apache) has the components of PHP FastCGI Process Manager (FPM) and Apache 2.4.
-
-Great to use for:
-* WordPress Websites
-* PHP Applications that require Apache components to function
-
-## FPM-NGINX
-Our [FPM-NGINX variation](https://hub.docker.com/r/serversideup/php/tags?page=1&name=fpm-nginx) has the components of PHP FastCGI Process Manager (FPM) and NGINX.
-
-Great to use for:
-* Laravel Applications
-* Simple PHP apps that want the web server and PHP-FPM server packaged into a single image
-
-## Viewing all available images
-[All our images are available on Docker Hub â](https://hub.docker.com/r/serversideup/php)
\ No newline at end of file
diff --git a/docs/content/docs/3.guide/1.migrating-from-official-php-images.md b/docs/content/docs/3.guide/1.migrating-from-official-php-images.md
new file mode 100644
index 00000000..d9cf7f5f
--- /dev/null
+++ b/docs/content/docs/3.guide/1.migrating-from-official-php-images.md
@@ -0,0 +1,28 @@
+---
+head.title: 'Migrating from official PHP Docker images - Docker PHP - Server Side Up'
+description: 'Learn how easy it is to move from the official PHP docker images to serversideup/php.'
+layout: docs
+---
+# Migrating from the official PHP images
+::lead-p
+`serversideup/php` is based on the official PHP images, so you can be confident in changing the base image for your application. Simply prepend `serversideup/` to the image name and you're ready to go. đ
+::
+
+## Changing the base image
+We follow the same naming convention as the official PHP images, so you can easily switch to our images by changing the base image in your `Dockerfile` or `docker-compose.yml` file.
+
+For example: If you're running `php:8.3-cli-alpine`, you can simply change it to `serversideup/php:8.3-cli-alpine` and you're ready to go. It's that easy!
+
+## Before making the change
+We encourage you to get familiar with our [default configurations](/docs/getting-started/default-configurations) and [environment variable specifications](/docs/reference/environment-variable-specification) before making the switch. We've improved the developer experience in a number of ways, so be sure you're evaluating how certain customizations are provided by default and that you're not duplicating conflicting customizations.
+
+The best place to get this information is with the following pages:
+- [Default Configurations](/docs/getting-started/default-configurations)
+- [Environment Variable Specifications](/docs/reference/environment-variable-specification)
+
+## Older versions of PHP
+If you do run into a situation where an image tag is not found, it's likely because we may need to add that tag to our system. This is more common in older versions of PHP. We support [active versions of PHP](https://www.php.net/supported-versions.php), but also provide images for 7.4 and 8.0 for those who need it. We *strongly encourage* you to run a supported version of PHP. We only offer these older versions to help you containerize and migrate your application to a newer version of PHP.
+
+If you are missing an image tag, you can [open a Discussion on GitHub](https://github.com/serversideup/docker-php/discussions/new?category=general) and we'll evaluate if we can get that added for you.
+
+To learn more how we tag our images, see our [installation guide](/docs/getting-started/installation).
\ No newline at end of file
diff --git a/docs/content/docs/3.guide/2.changing-common-php-settings.md b/docs/content/docs/3.guide/2.changing-common-php-settings.md
new file mode 100644
index 00000000..5a3870e4
--- /dev/null
+++ b/docs/content/docs/3.guide/2.changing-common-php-settings.md
@@ -0,0 +1,58 @@
+---
+head.title: 'Changing common PHP settings - Docker PHP - Server Side Up'
+description: 'Learn how easy it is to configure common PHP settings with serversideup/php.'
+layout: docs
+---
+
+# Changing common PHP settings
+::lead-p
+Instead of going through the effort of writing custom scripts or mounting files to change PHP settings, have the power to change common settings with the simplicity of an environment variable.
+::
+
+## Common Examples
+All our environment variables are documented and can be found in our [environment variable specification](/docs/reference/environment-variable-specification) documentation.
+
+Here are a few examples on how you can change common PHP settings.
+
+::code-panel
+---
+label: "Docker Compose: Changing allowed upload size"
+---
+```yaml
+version: '3'
+services:
+ php:
+ image: serversideup/php:8.2.12-unit-bookworm
+ environment:
+ PHP_POST_MAX_SIZE: "500M"
+ PHP_UPLOAD_MAX_FILE_SIZE: "500M"
+ SSL_MODE: "mixed"
+ ports:
+ - 80:80
+ - 443:443
+ volumes:
+ - .:/var/www/html/
+```
+::
+
+::code-panel
+---
+label: "Docker CLI: Setting the PHP timezone to New York"
+---
+```bash
+docker run -d \
+ -p 80:80 \
+ -v $(pwd):/var/www/html \
+ -e PHP_DATE_TIMEZONE="America/New_York" \
+ serversideup/php:8.2.12-fpm-nginx-bookworm
+```
+::
+
+## Setting your own php.ini
+
+::note
+We're still working on documenting this section. Thanks for your patience. [Open a discussion on GitHub](https://github.com/serversideup/docker-php/discussions/new?category=general) if you'd like to see this added sooner.
+::
+
+## Validating changes
+It's always best to validate your changes by running `php -i` via the command line or using [`phpinfo()`](https://www.php.net/manual/en/function.phpinfo.php).
\ No newline at end of file
diff --git a/docs/content/docs/3.guide/2.customizing-the-image.md b/docs/content/docs/3.guide/2.customizing-the-image.md
deleted file mode 100644
index 82bc00c0..00000000
--- a/docs/content/docs/3.guide/2.customizing-the-image.md
+++ /dev/null
@@ -1,145 +0,0 @@
----
-head.title: 'Customizing the image - Docker PHP - Server Side Up'
-description: 'Learn how to customize the image and make it yours.'
-layout: docs
----
-
-# Customizing the image
-There are a few ways that you can customize the Docker PHP images.
-
-### Installing additional PHP extensions
-Let's say that we have a basic Docker compose image working in development:
-
-::code-panel
----
-label: docker-compose.yml
----
-```yaml
-version: '3.7'
-services:
- php:
- image: serversideup/php:8.0-fpm-nginx
- volumes:
- - .:/var/www/html/:cached
-```
-::
-
-Now let's say we want to add the **PHP ImageMagick** extension. To do this, we will use the [docker compose build](https://docs.docker.com/compose/compose-file/compose-file-v3/#build) option in our YAML file.
-
-This means we would need to change our file above to look like:
-
-::code-panel
----
-label: Updated docker-compose.yml file
----
-```yaml
-version: '3.7'
-services:
- php:
- build:
- context: .
- dockerfile: Dockerfile
- volumes:
- - .:/var/www/html/:cached
-```
-::
-
-Notice the `services.php.build` options. We set a `.` to look for a dockerfile called `Dockerfile` within the same directory as our `docker-compose.yml` file.
-
-For extra clarity, my project directory would look like this:
-
-::code-panel
----
-label: Project File Structure
----
-```txt
-.
-âââ Dockerfile
-âââ docker-compose.yml
-âââ public
- âââ index.php
-```
-::
-
-
-The Dockerfile is where all the magic will happen. This is where we pull the Server Side Up image as a dependency, then run standard Ubuntu commands to add the extension that we need.
-
-::code-panel
----
-label: Dockerfile
----
-```Dockerfile
-# Set our base image
-FROM serversideup/php:8.0-fpm-nginx
-
-# Install PHP Imagemagick using regular Ubuntu commands
-RUN apt-get update \
- && apt-get install -y --no-install-recommends php8.0-imagick \
- && apt-get clean \
- && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
-```
-::
-
-
-The next time you run `docker compose up`, Docker will build and cache the image for you automatically.
-
-You can verify the CLI option installed correctly by echoing out the installed modules. Run this command in a new window **while your containers are running via Docker Compose**:
-
-
-
-::code-panel
----
-label: Check loaded modules
----
-```sh
-docker compose exec php php -m
-```
-::
-
-To check that PHP-FPM loaded everything properly, use the [phpinfo()](https://www.php.net/manual/en/function.phpinfo.php) functionally.
-
-#### â ī¸ Important note about caching
-* You'll notice Docker likes to cache image builds (which is great for most functions)
-* If you make changes to your *Dockerfile*, you may need to include `--build` with your Docker compose command ([read more here](https://docs.docker.com/compose/reference/up/))
-
-If you want to rebuild, then you would run this:
-::code-panel
----
-label: Rebuild on Docker Compose Initialization
----
-```sh
-docker compose up --build
-```
-::
-
-#### How do I know which package name to use?
-Refer to the official instructions of the extension that you are trying to install. We use Ondrej's PHP repository, so chances are you might be able to find in in here: https://launchpad.net/~ondrej/+archive/ubuntu/php/+packages
-
-Make sure to use the same version number as well. For example... If you are using `8.0` and want to install the **php-imagick** package, use the name `php8.0-imagick` during install (see my examples above).
-
-### Production SSL Configurations
-By default, we generate a self-signed certificate for simple local development. For production use, we recommend using as a proxy to your actual container.
-
-You have a few options for using SSL in production. **These configurations are only supported in the `php-apache` and `php-nginx` configurations.**
-
-| Value of `$SSL_MODE` | Description |
-| --- | --- |
-| `off` | This will disable any SSL management and will use HTTP only. Direct all your container traffic to port 80.|
-| `mixed` | This will support HTTP and HTTPS connections. You can send traffic to port 80 or 443. |
-| `full` (default) | This will provide "end-to-end encryption" to your web server. Any HTTP traffic will be redirected to HTTPS. |
-
-#### Using your own certificates
-If you use `mixed` or `full` for your "SSL_MODE", we will check for certificate pairs at the following locations:
-
-1. /etc/ssl/web/ssl.crt
-1. /etc/ssl/web/ssl.key
-
-Simply use [Docker Volumes](https://docs.docker.com/storage/volumes/) and mount the `/etc/ssl/web` folder with these two files in that directory.
-
-If we do not find a certificate pair, we will generate a self-signed certificate pair for you.
-
-### The easiest way to get a trusted certificate
-1. Use a proxy that supports Let's Encrypt (like [Traefik](https://traefik.io/) or [Caddy](https://caddyserver.com/))
-1. Make sure you allow your proxy to direct traffic encrypted with self-signed certificates (if you're proxying to the container with a self-signed certificate)
-
-This is what we do and it's really nice to use the automatic Let's Encrypt SSL management with these products.
\ No newline at end of file
diff --git a/docs/content/docs/3.guide/3.installing-additional-php-extensions.md b/docs/content/docs/3.guide/3.installing-additional-php-extensions.md
new file mode 100644
index 00000000..7a0c5abd
--- /dev/null
+++ b/docs/content/docs/3.guide/3.installing-additional-php-extensions.md
@@ -0,0 +1,121 @@
+---
+head.title: 'Installing additional PHP extensions - Docker PHP - Server Side Up'
+description: 'Learn how to add any PHP extension that you need for your application.'
+layout: docs
+---
+
+# How to install additional PHP extensions
+We provide a number of PHP packages by default, but there will be times where you'll need to add additional PHP extensions in order to support a certain PHP library in your application. By default, we've included a popular tool called [`install-php-extensions`](https://github.com/mlocati/docker-php-extension-installer) that allows you to install almost any PHP module that you'll need.
+
+Installing extensions is easy. All you need to do is find the extension you'd like to install on the [docker-php-extension installer README](https://github.com/mlocati/docker-php-extension-installer#supported-php-extensions). Once you have the name of the extensions, you'll need to add it to the `Dockerfile` in your project.
+
+::code-panel
+---
+label: "Example: Installing the \"intl\" extension"
+---
+```txt
+FROM serversideup/php:8.2.12-fpm-nginx-bookworm
+
+RUN install-php-extensions intl
+```
+::
+
+It's really that simple. The `install-php-extensions` tool will automatically install the operating system packages that are required for the PHP extension to work and add the extension to PHP.
+
+For more details on this script, we encourage you to check out the GitHub repository for this project.
+
+[View the "docker-php-extension-installer" Project on GitHub â](https://github.com/mlocati/docker-php-extension-installer)
+
+## Docker Compose
+If you're using Docker Compose, you'll want to make sure that you're not calling our image directly with the `image:` key. Instead, you'll want to use the `build:` key and point to a `Dockerfile` in your project.
+
+::code-panel
+---
+label: Original docker-compose.yml file
+---
+```yaml
+version: '3.7'
+services:
+ php:
+ image: serversideup/php:8.2.12-fpm-nginx-bookworm
+ volumes:
+ - .:/var/www/html/:cached
+```
+::
+
+::code-panel
+---
+label: "Updated docker-compose.yml"
+---
+```yaml
+version: '3.7'
+services:
+ php:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ volumes:
+ - .:/var/www/html/:cached
+```
+::
+
+::code-panel
+---
+label: "New File: Dockerfile"
+---
+```txt
+FROM serversideup/php:8.2.12-fpm-nginx-bookworm
+
+RUN install-php-extensions imagick
+```
+::
+
+Notice the `services.php.build` options. We set a `.` to look for a dockerfile called `Dockerfile` within the same directory as our `docker-compose.yml` file. If your project is large, you may also want to include [`.dockerignore`](https://docs.docker.com/engine/reference/builder/#dockerignore-file) to ignore files that you do not want to include in your image.
+
+For extra clarity, my project directory would look like this:
+
+::code-panel
+---
+label: Project File Structure
+---
+```txt
+.
+âââ Dockerfile
+âââ docker-compose.yml
+âââ public
+ âââ index.php
+```
+::
+
+The Dockerfile is where all the magic will happen. This is where we pull the Server Side Up image as a dependency, then run standard shell commands to add the extension that we need.
+
+The next time you run `docker compose up`, Docker will build and cache the image for you automatically.
+
+You can verify the CLI option installed correctly by using `php -i` in CLI or `phpinfo()` in a PHP file.
+
+#### â ī¸ Important note about caching
+* You'll notice Docker likes to cache image builds (which is great for most functions)
+* If you make changes to your *Dockerfile*, you may need to include `--build` with your Docker compose command ([read more here](https://docs.docker.com/compose/reference/up/))
+
+If you want to rebuild, then you would run this:
+::code-panel
+---
+label: Rebuild on Docker Compose Initialization
+---
+```sh
+docker compose up --build
+```
+::
+
+## Common PHP extensions that you might need
+We compiled a list of extensions for you to reference.
+
+### intl
+[intl](https://www.php.net/manual/en/intro.intl.php) is a PHP module that provides internationalization functions. You may want to install this module if you're using Laravel, specifically if you are validating emails with "DNS" or "spoof" validation.
+
+Our tests showed this module will add about 40 MB of space to the Docker image, so we decided to not include it by default.
+
+[Learn more about the "intl" requirement for Laravel â](https://laravel.com/docs/10.x/validation#rule-email)
+
+### Don't see the extension you need?
+If you're having trouble, [open a discussion on GitHub â](https://github.com/serversideup/docker-php/discussions/new?category=q-a)
\ No newline at end of file
diff --git a/docs/content/docs/3.guide/4.adding-your-own-start-up-scripts.md b/docs/content/docs/3.guide/4.adding-your-own-start-up-scripts.md
new file mode 100644
index 00000000..1922a86d
--- /dev/null
+++ b/docs/content/docs/3.guide/4.adding-your-own-start-up-scripts.md
@@ -0,0 +1,157 @@
+---
+head.title: 'Adding your own start up scripts - Docker PHP - Server Side Up'
+description: 'Learn how to use our entrypoint.d directory to customize your container start up experience.'
+layout: docs
+---
+
+# Adding your own start up scripts
+::lead-p
+We provide a few [default scripts](/docs/getting-started/default-configurations#default-entrypoint-scripts) to get you going, but sometimes you want to just add your own. We've made it easy to do that with our `entrypoint.d` directory.
+::
+
+## Entrypoint Script Requirements
+::note
+Before you write your entry point script, be aware of the following requirements:
+
+Your script should:
+- Be executable (755 permissions)
+- Located in the `/etc/entrypoint.d` directory
+- Have the file extension ending in `.sh`
+::
+We recommend writing your script in `/bin/sh` for the best compatibility between Alpine and Debian. If you choose to use `/bin/bash`, your script will only be able to run on Debian-based images.
+
+## Choose your execution order
+Since [we provide default entrypoint scripts](/docs/getting-started/default-configurations#default-entrypoint-scripts), you may want to choose the order in which your scripts are executed. We've made it easy to do that by prefixing your script with a number. The lower the number, the earlier it will be executed.
+
+::note
+If you want to disable our entrypoint scripts, you can set `DISABLE_DEFAULT_CONFIG` to `true` in your environment variables.
+::
+
+## Example: Create a custom entrypoint script
+In this example, let's create a `99-my-script.sh` so it executes after all the other default scripts.
+
+First, let's take a look at our project structure:
+
+::code-panel
+---
+label: "Project Structure"
+---
+```txt
+.
+âââ Dockerfile
+âââ docker-compose.yml
+âââ entrypoint.d
+â âââ 99-my-script.sh
+âââ public
+ âââ index.php
+```
+::
+Let's take a look at the script that we want to run. We can keep this simple for now.
+
+::code-panel
+---
+label: "99-my-script.sh"
+---
+```bash
+#!/bin/sh
+echo "đ Hello, world!"
+```
+::
+
+Now, let's take a look at our `Dockerfile`:
+
+::code-panel
+---
+label: "Dockerfile"
+---
+```dockerfile
+FROM serversideup/php:8.3-unit
+
+COPY --chmod=755 ./entrypoint.d/ /etc/entrypoint.d/
+```
+::
+
+In the above file, we're copying our `entrypoint.d` directory to `/etc/entrypoint.d/` in the container. We're also setting the permissions to `755` so our scripts are executable.
+
+Finally, let's take a look at our `docker-compose.yml` file:
+
+::code-panel
+---
+label: "docker-compose.yml"
+---
+```yaml
+version: '3'
+services:
+ php:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ ports:
+ - 80:80
+ volumes:
+ - .:/var/www/html
+```
+::
+
+In the above file, we're building our image using the `Dockerfile` in the current directory. We're also mounting our current directory to `/var/www/html` in the container.
+
+## Running our example
+When we run `docker compose up`, we should see the following output:
+
+::code-panel
+---
+label: "Output of \"docker compose up\""
+---
+```txt
+example-project | init-unit: Stopping Unit daemon after initial configuration...
+example-project | 2023/12/05 19:52:37 [notice] 29#29 process 33 exited with code 0
+example-project | init-unit: Waiting for control socket to be removed...
+example-project | 2023/12/05 19:52:37 [notice] 29#29 process 34 exited with code 0
+example-project |
+example-project | init-unit: Unit initial configuration complete; ready for start up...
+example-project |
+example-project | đ Hello, world!
+example-project | 2023/12/05 19:52:38 [info] 1#1 unit 1.31.1 started
+example-project | 2023/12/05 19:52:38 [info] 65#65 discovery started
+example-project | 2023/12/05 19:52:38 [notice] 65#65 module: php 8.3.0 "/usr/lib/unit/modules/php.unit.so"
+example-project | 2023/12/05 19:52:38 [info] 1#1 controller started
+example-project | 2023/12/05 19:52:38 [notice] 1#1 process 65 exited with code 0
+example-project | 2023/12/05 19:52:38 [info] 67#67 router started
+example-project | 2023/12/05 19:52:38 [info] 67#67 OpenSSL 3.0.11 19 Sep 2023, 300000b0
+```
+::
+
+You can see our `đ Hello, world!` is executing *after* the initialization of `10-init-unit.sh`.
+
+## Additional Steps For FPM-Apache & FPM-NGINX (S6 Overlay based images)
+If the image you're working with is using S6 Overlay (`fpm-nginx` and `fpm-apache`), you'll need to take additional steps to get your scripts to execute.
+
+### Background
+S6 Overlay uses a set of directories to execute scripts at different stages of the container's life cycle. You can read more about it in [S6 Overlay's documentation](https://github.com/just-containers/s6-overlay).
+
+### Our Solution
+Instead of reading through the complexities of S6 Overlay, we wrote a script called `docker-php-serversideup-s6-init` that will automatically configure your script located in `/etc/entrypoint.d` to execute correctly with S6 Overlay.
+
+### `docker-php-serversideup-s6-init` Usage
+The only thing you need to do is call `docker-php-serversideup-s6-init` after your script is copied. Here's an example:
+
+::note
+Depending on your usecase, you may want to set `S6_CMD_WAIT_FOR_SERVICES` to `1` in your environment variables. This will make sure your script doesn't execute until all the services are ready. Learn more about this in [S6 Overlay's documentation](https://github.com/just-containers/s6-overlay).
+::
+
+::code-panel
+---
+label: "Dockerfile"
+---
+```dockerfile
+FROM serversideup/php:8.3-fpm-nginx
+
+ENV S6_CMD_WAIT_FOR_SERVICES=1
+
+COPY --chmod=755 ./entrypoint.d/ /etc/entrypoint.d/
+
+RUN docker-php-serversideup-s6-init
+```
+::
+
+The above `Dockerfile` will copy scripts from our `entrypoint.d` directory to `/etc/entrypoint.d/` and then run `docker-php-serversideup-s6-init`, which will then take any scripts in `/etc/entrypoint.d/` and configure them to execute correctly with S6 Overlay.
\ No newline at end of file
diff --git a/docs/content/docs/3.guide/5.configuring-ssl.md b/docs/content/docs/3.guide/5.configuring-ssl.md
new file mode 100644
index 00000000..2abf8ba5
--- /dev/null
+++ b/docs/content/docs/3.guide/5.configuring-ssl.md
@@ -0,0 +1,101 @@
+---
+head.title: 'Configuring SSL - Docker PHP - Server Side Up'
+description: 'Learn how to use SSL with the serversideup/php images.'
+layout: docs
+---
+
+# Configuring SSL
+SSL is disabled by default but can be turned on by setting `SSL_MODE`:
+
+- `off` (default): HTTP only.
+- `mixed`: HTTP and HTTPS.
+- `on`: HTTPS only. HTTP requests will be redirected to HTTPS.
+
+## Self-signed Certificate Example
+If you set `SSL_MODE` to `mixed` or `on`, a self-signed certificate will be generated by default.
+
+::code-panel
+---
+label: Set SSL mode to "mixed" (HTTP + HTTPS)
+---
+```yaml
+version: '3'
+services:
+ php:
+ image: serversideup/php:8.3-fpm-nginx
+ ports:
+ - 80:80
+ - 443:443
+ environment:
+ SSL_MODE: "mixed"
+ volumes:
+ - .:/var/www/html
+```
+::
+
+The above will generate a self-signed certificate and configure NGINX to listen on both HTTP (Port 80) and HTTPS (Port 443).
+
+## Providing Your Own Certificate
+In order to add your own certificate, you will need to mount the certificate files to the container. The following files are required:
+
+::code-panel
+---
+label: Providing your own certificate pair
+---
+```yaml
+version: '3'
+services:
+ php:
+ image: serversideup/php:8.3-fpm-nginx
+ ports:
+ - 80:80
+ - 443:443
+ environment:
+ SSL_MODE: "mixed"
+ SSL_PRIVATE_KEY_FILE: "/etc/ssl/private/test-key.pem"
+ SSL_CERTIFICATE_FILE: "/etc/ssl/private/test.pem"
+ volumes:
+ - ./app:/var/www/html
+ - ./certs/:/etc/ssl/private/
+```
+::
+
+::note
+Ensure your private key file is set to the permissions `600` (read/write for owner only). If you don't set the permissions correctly, you will run into errors with loading an insecure private key file.
+::
+
+The above example provides the private and public key pair with `SSL_PRIVATE_KEY_FILE` and `SSL_CERTIFICATE_FILE` environment variables. The files are mounted to the container with the `volumes` directive.
+
+To give you a clearer picture of the project structure, this is what my folder looks like:
+
+::code-panel
+---
+label: Providing your own certificate pair
+---
+```text
+.
+âââ app
+â âââ public
+â âââ index.php
+âââ certs
+â âââ test-key.pem
+â âââ test.pem
+âââ docker-compose.yml
+```
+::
+
+You can see the `docker-compose.yml` file is in the parent directory. The `app` directory is dedicated for all application files, where the `certs` directory is dedicated for all SSL certificates.
+
+The separation of these two directories is important. It would not be a good practice to mount your certificate files in the `/var/www/html` directory on a production machine.
+
+::note
+For a signed certificate, you must acquire one from a trusted certificate authority (like [ssls.com](https://www.ssls.com/)).
+::
+
+### Additional options for NGINX Unit
+If you're using NGINX Unit, you also have the option of setting `UNIT_CERTIFICATE_NAME` (default: `self-signed-web-bundle`). This is the name of the certificate bundle that will be used by NGINX Unit. You can read more about this in the [NGINX Unit documentation](https://unit.nginx.org/configuration/#ssl-tls-configuration).
+
+## Using Let's Encrypt
+If you'd like to use Let's Encrypt (what we use), it's best to use a reverse proxy like [Traefik](https://traefik.io/traefik/) or [Caddy](https://caddyserver.com/).
+
+Providing examples for those are out of the scope of this project, but we may consider adding examples in other projects in the future.
\ No newline at end of file
diff --git a/docs/content/docs/3.guide/6.using-s6-overlay.md b/docs/content/docs/3.guide/6.using-s6-overlay.md
new file mode 100644
index 00000000..eab39f1e
--- /dev/null
+++ b/docs/content/docs/3.guide/6.using-s6-overlay.md
@@ -0,0 +1,96 @@
+---
+head.title: 'Using S6 Overlay - Docker PHP - Server Side Up'
+description: 'Learn about S6 Overlay and how it is used in this project.'
+layout: docs
+---
+
+## What's S6 Overlay?
+[S6 Overlay](https://github.com/just-containers/s6-overlay) is a process supervisor designed for containerization from the ground up. It's a modern alternative to [Supervisor (aka Supervisord)](https://supervisord.org/).
+
+S6 Overlay is a perfect match for running PHP because it usually requires running multiple processes together.
+
+## What images do you use S6 Overlay with?
+We only use S6 Overlay for images that need two processes to run a service. This includes:
+- `serversideup/php:*-fpm-apache`
+- `serversideup/php:*-fpm-nginx`
+
+## Why does PHP need multiple processes?
+Serving a PHP application can be broken down into two different components:
+1. The PHP Application Itself
+2. The static files that go with it (JavaScript, images, etc)
+
+There are ways to have these components served together with Apache modules like "mod_php". As time moved on, we found this to be very resource inefficient.
+
+Running "mod_php" with Apache meant that even when a JavaScript file needs to be loaded, Apache would load PHP to serve that file. This caused a lot of unnecessary memory and CPU usage for files that didn't need PHP to be served.
+
+### PHP-FPM
+PHP-FPM was the answer to make this serving a PHP application more efficient. This allowed PHP apps to be served with a lot less memory and CPU overhead.
+
+Although this method was more efficient, it meant we still need something to serve our static content. This is where we turned to "reverse proxies".
+
+### Reverse proxy
+Reverse proxies are servers that route traffic based on the request. To make things more confusing, you can have a web server be a reverse proxy and a web server at the same time (this is how we run NGINX). You can even configure Apache to run as a web server and a reverse proxy too (we run our `php:*-fpm-apache` images like this).
+
+
+
+In the example above, you can see the web request coming in from the top. NGINX is our first stop where it inspects the request.
+
+#### Static Files
+If the request is for a static file (jpeg, js, png, etc), NGINX will also serve that file for us without loading PHP-FPM. This makes the request very fast and efficient.
+
+#### PHP Files
+If the request ends in `.php`, then it will send the request over to PHP-FPM. PHP-FPM will then execute the PHP file and return a response to the original client, all passed through NGINX.
+
+## Shouldn't containers only have one process?
+In a perfect world, that would be ideal -- but this isn't always realistic. You can see in the example above we need two things running:
+1. NGINX: To serve static files
+1. PHP-FPM: To serve PHP application
+
+If you want to replicate your application without the added complexity of multiple physical servers, etc -- you need something like S6 Overlay to properly bring up the processes and ensure your application service health is accurately reported.
+
+[S6 Overlay's philosophy](https://github.com/just-containers/s6-overlay#the-docker-way) is a perfect match when it comes to running PHP:
+
+- A container should do ***one thing*** (which may contain multiple processes). When that one thing stops, the container should also stop.
+
+## The advantages of S6 Overlay
+When we configure PHP to run with the S6 Overlay system, we get a number of advantages:
+
+- â
S6 Overlay was designed from the ground up to run within containers
+- â
We get explicit control to run small scripts or configurations before/after the main processes start
+- â
We get a better confidence on answering "Is my container actually healthy?"
+
+## This disadvantage of S6 Overlay
+
+- â S6 Overlay may not be compatible with all PaaS providers, depending on how they run their containers ([see this comment from the S6 Overlay creator](https://github.com/just-containers/s6-overlay/issues/535#issuecomment-1597680218))
+
+## S6 Overlay vs. Supervisor
+Many people flock to Supervisor, which was a very popular option before containerization. Here's some examples why you may want to trade Supervisor for S6 Overlay:
+
+### How Supervisor reports container health
+
+
+When you bring up Supervisord within a container, it will be assigned `PID 1`. Then Supervisor will bring up child processes with it.
+
+During a failure, Supervisor can be configured to restart the child process to attempt recovery, but the container orchestrator thinks the container is still healthy because `supervisord` is occupying `PID 1` which is still healthy.
+
+**đ This design can lead to inaccurate container health statuses during a failure.**
+
+### How S6 Overlay reports container health
+
+S6 Overlay was designed to be run in containers from the ground up. S6 Overlay can also attempt recovery, but it is more accurate on determining container health compared to Supervisor.
+
+**đ By design, S6 Overlay can accurately detect a failure and exit (which is what we want when our app fails).**
+
+## Customizing the initialization process
+
+Since S6 Overlay was designed around the idea of containerization, there are also a number of other advantages to properly time your customizations during container startup.
+
+S6 Overlay has a number of options to [write our own service script](https://github.com/just-containers/s6-overlay/tree/master#writing-a-service-script) and properly time everything.
+
+In the example above, you can see we have a `runas-user` script which helps us customize and set custom UIDs and GIDs for our file permissions. At the same time, `laravel-automations` executes to see if there are any automated migrations to run.
+
+Both scripts must finish successfully before S6 Overlay starts our main `php-fpm` process, which has both scripts listed as a dependency.
+
+As you can see this structure can be very powerful in making your own customizations. This is great for giving you full control of how you'd like your application to behave.
+
+[Read how to make customizations â](/docs/guide/changing-common-php-settings/)
\ No newline at end of file
diff --git a/docs/content/docs/3.guide/7.migrating-from-v2-to-v3.md b/docs/content/docs/3.guide/7.migrating-from-v2-to-v3.md
new file mode 100644
index 00000000..ce01f421
--- /dev/null
+++ b/docs/content/docs/3.guide/7.migrating-from-v2-to-v3.md
@@ -0,0 +1,57 @@
+---
+head.title: 'Migrating from v2 to v3 - Server Side Up'
+description: 'Learn how to migrate from serversideup/php v2 images to v3.'
+layout: docs
+---
+
+# Migrating from v2 to v3
+::lead-p
+If you're moving from v2 to v3, there are a number of changes you should be aware of. We've tried to keep these to a minimum, but some of these changes were necessary to make the project more maintainable and easier to use.
+::
+
+::note
+This guide is a work in progress during the beta. We believe we have all the major changes documented, but please [let us know](https://github.com/serversideup/docker-php/discussions/new?category=general) if you find anything that is missing.
+::
+
+## đ New Features
+We've been busy overhauling our PHP Docker Images to make them more production-ready and easier to use. Here are some of the new features we've added:
+- **Based on official PHP Images** - We're now building an improved developer experience on top of the official PHP Docker images.
+- **PHP 8.3 support** - We're now shipping the latest and greatest.
+- **Pin to the exact minor version** - Pin your app to the exact minor version of PHP that you want to use. This means you can pin to `8.2.12` instead of `8.2`.
+- **Easier start up script customization** - We now have a folder called `/etc/entrypoint.d` that allows you to easily customize your container with scripts. Just put them in numerical order and we'll execute any shell script you want. No S6 Overlay knowledge required.
+- **Expanded Laravel Automations** - We added automations to run `config:cache`, `route:cache`, `view:cache`, `event:cache`, `migrate --force --isolated`, and `storage:link`
+- **NGINX Unit Support** - We're offering NGINX Unit as a variation as an alternative to PHP-FPM. This allows you to run PHP applications without the need for a webserver like NGINX or Apache to run with PHP-FPM.
+- **Available on GitHub Packages** - We're now publishing our images to GitHub Packages. This means you can use our images without needing to authenticate with Docker Hub.
+
+## â ī¸ Breaking changes
+The following changes are considered to be "breaking changes" and will require you to make changes to your application.
+
+### Ubuntu is no longer used as a base image
+We now use Debian or Alpine as our base OS (because we're using the official PHP images as a base). This is a huge change, but we're confident this will be the best direction moving forward.
+
+### `ppa:ondrej/php` is no longer used
+Since we're using PHP.net as the "official source of truth" for getting our PHP versions, this means we're also dropping support for the `ppa:ondrej/php` repostory. If you're using things like `apt-get install php-redis` you will need to change your method of installing PHP extensions.
+
+[Learn how to install your own PHP extension â](/docs/guide/installing-additional-php-extensions)
+
+### `webuser` is no longer being used
+::note
+This is still an area that we're exploring. Please chime in on the discussion if you have any thoughts.
+
+[See the discussion â](https://github.com/serversideup/docker-php/issues/253)
+::
+
+We used to add a user called `webuser` with the UID of `9999`, but in the current beta we're not. This is an area that we're still going to explore during the beta, so please chime in on the discussion if you have any thoughts.
+
+### S6 Overlay is only used in `*-fpm-apache` and `*-fpm-nginx` images
+Due to compatibility issues, we only use S6 Overlay in our `*-fpm-apache` and `*-fpm-nginx` images. If you were using S6 Overlay for our other variations (cli, fpm, etc), you will need to migrate your scripts to use the new `/etc/entrypoint.d` folder.
+
+### `SSL_MODE` is now set to `off` by default (HTTP only)
+Running end-to-end SSL by default created more problems than good. By default, we're now shipping HTTP-only by default with the option for people to turn this on.
+
+### `AUTORUN_ENABLED` is now set to `false` by default.
+Having this set to "true" by default also created more problems than good. If you want to use any of the Laravel Automation Scripts, be sure to set this to `true`.
+
+### Variable deprecations
+- `WEB_APP_DIRECTORY` has now been renamed to `APP_BASE_DIR`
+- `DEBUG_OUTPUT` has been removed for in favor of `LOG_LEVEL=debug`
\ No newline at end of file
diff --git a/docs/content/docs/4.laravel/2.laravel-task-scheduler.md b/docs/content/docs/4.laravel/2.laravel-task-scheduler.md
index ed7fdb46..4051d077 100644
--- a/docs/content/docs/4.laravel/2.laravel-task-scheduler.md
+++ b/docs/content/docs/4.laravel/2.laravel-task-scheduler.md
@@ -28,7 +28,7 @@ services:
php:
image: my/laravel-app
environment:
- PHP_POOL_NAME: "my-app_php"
+ PHP_FPM_POOL_NAME: "my-app_php"
task:
image: my/laravel-app
@@ -36,7 +36,7 @@ services:
# Declare command in list manner for environment variable expansion
command: ["su", "webuser", "-c", "php artisan schedule:work"]
environment:
- PHP_POOL_NAME: "my-app_task"
+ PHP_FPM_POOL_NAME: "my-app_task"
```
::
diff --git a/docs/content/docs/4.laravel/3.laravel-queue.md b/docs/content/docs/4.laravel/3.laravel-queue.md
index 83afa7dd..72ed2713 100644
--- a/docs/content/docs/4.laravel/3.laravel-queue.md
+++ b/docs/content/docs/4.laravel/3.laravel-queue.md
@@ -30,7 +30,7 @@ services:
php:
image: my/laravel-app
environment:
- PHP_POOL_NAME: "my-app_php"
+ PHP_FPM_POOL_NAME: "my-app_php"
queue:
image: my/laravel-app
@@ -38,6 +38,6 @@ services:
# Declare command in list manner for environment variable expansion
command: ["su", "webuser", "-c", "php artisan queue:work --tries=3"]
environment:
- PHP_POOL_NAME: "my-app_queue"
+ PHP_FPM_POOL_NAME: "my-app_queue"
```
::
\ No newline at end of file
diff --git a/docs/content/docs/4.laravel/4.laravel-horizon.md b/docs/content/docs/4.laravel/4.laravel-horizon.md
index 3a80302a..fbdefdd0 100644
--- a/docs/content/docs/4.laravel/4.laravel-horizon.md
+++ b/docs/content/docs/4.laravel/4.laravel-horizon.md
@@ -32,7 +32,7 @@ services:
php:
image: my/laravel-app
environment:
- PHP_POOL_NAME: "my-app_php"
+ PHP_FPM_POOL_NAME: "my-app_php"
redis:
image: redis:6
@@ -44,6 +44,6 @@ services:
# Declare command in list manner for environment variable expansion
command: ["su", "webuser", "-c", "php artisan horizon"]
environment:
- PHP_POOL_NAME: "my-app_horizon"
+ PHP_FPM_POOL_NAME: "my-app_horizon"
```
::
\ No newline at end of file
diff --git a/docs/content/docs/6.reference/1.environment-variable-specification.md b/docs/content/docs/6.reference/1.environment-variable-specification.md
index 3a134100..0db22e45 100644
--- a/docs/content/docs/6.reference/1.environment-variable-specification.md
+++ b/docs/content/docs/6.reference/1.environment-variable-specification.md
@@ -7,36 +7,64 @@ layout: docs
# Environment Variable Specifications
We like to customize our images on a per app basis using environment variables. Look below to see what variables are available and what their defaults are. You can easily override them in your own docker environments ([see Docker's documentation](https://docs.docker.com/compose/environment-variables/#set-environment-variables-in-containers)).
+**Variable Name**|**Description**|**Used in variation**
+:-----:|:-----:|:-----:
+`APP_BASE_DIR` *Default: "/var/www/html"*|Change this only if you mount your application to a different directory within the container.|all
+`AUTORUN_ENABLED` *Default: "false"*|Enable or disable all automations. It's advised to set this to `false` in certain CI environments (especially during a composer install). If this is set to `false`, all `AUTORUN_*` behaviors will also be disabled.| all
+`AUTORUN_LARAVEL_CONFIG_CACHE` *â ī¸ Depends on: `AUTORUN_ENABLED`* *Default: "true"*|Automatically run "php artisan config:cache" on container start| all
+`AUTORUN_LARAVEL_EVENT_CACHE` *â ī¸ Depends on: `AUTORUN_ENABLED`* *Default: "true"*|Automatically run "php artisan event:cache" on container start| all
+`AUTORUN_LARAVEL_MIGRATION` *â ī¸ Depends on: `AUTORUN_ENABLED`* *Default: "true"*|Requires Laravel v9.38.0 or higher. Automatically run "php artisan migrate --force --isolated" on container start.| all
+`AUTORUN_LARAVEL_MIGRATION_TIMEOUT` *â ī¸ Depends on: `AUTORUN_ENABLED`* *Default: "30"*|The number of seconds to wait for the database to come online before attempting `php artisan migrate`.| all
+`AUTORUN_LARAVEL_ROUTE_CACHE` *â ī¸ Depends on: `AUTORUN_ENABLED`* *Default: "true"*|Automatically run "php artisan route:cache" on container start| all
+`AUTORUN_LARAVEL_STORAGE_LINK` *â ī¸ Depends on: `AUTORUN_ENABLED`* *Default: "true"*|Automatically run "php artisan storage:link" on container start| all
+`AUTORUN_LARAVEL_VIEW_CACHE` *â ī¸ Depends on: `AUTORUN_ENABLED`* *Default: "true"*|Automatically run "php artisan view:cache" on container start| all
+`COMPOSER_ALLOW_SUPERUSER` *Default: "1"*|Disable warning about running as super-user|all
+`COMPOSER_HOME` *Default: "/composer"*|The COMPOSER_HOME variable allows you to change the Composer home directory. This is a hidden, global (per-user on the machine) directory that is shared between all projects.|all
+`COMPOSER_MAX_PARALLEL_HTTP` *Default: "24"*|Set to an integer to configure how many files can be downloaded in parallel. Composer ships with 12 by default and must be between 1 and 50. If your proxy has issues with concurrency maybe you want to lower this. Increasing it should generally not result in performance gains.|all
+`DISABLE_DEFAULT_CONFIG` *Default: "false"*|Get full customization of the image and disable all default configurations and automations.| all
+`LOG_LEVEL` *Default: "warn"*|Set your container output different verbosity levels: debug, info, off |all
+`NGINX_SERVER_TOKENS` *Default: "off"*|Display NGINX version in responses. (Official Docs )|fpm-nginx
+`NGINX_USER` *Default: "nginx"*|Set which user should run NGINX. (Official Docs )|fpm-nginx
+`NGINX_WEBROOT` *Default: "`$APP_BASE_DIR`/public"*|Sets the root directory for requests. (Official Docs )|fpm-nginx
+`PHP_DATE_TIMEZONE` *Default: "UTC"*|Control your timezone. (Official Docs )|all
+`PHP_DISPLAY_ERRORS` *Default: Off*|Show PHP errors on screen. (Official docs )|all
+`PHP_DISPLAY_STARTUP_ERRORS` *Default: Off*|Even when display_errors is on, errors that occur during PHP's startup sequence are not displayed. (Official docs )| all
+`PHP_ERROR_LOG` *Default: "/dev/stderr"*|Name of the file where script errors should be logged. . (Official docs )|all
+`PHP_ERROR_REPORTING` *Default: "22527"*|Set PHP error reporting level. Must be a number. Use this tool for help. (Official docs )|all
+`PHP_FPM_PM_CONTROL` *Defaults: fpm: dynamic fpm-apache: ondemand fpm-nginx: ondemand*|Choose how the process manager will control the number of child processes. (Official docs )|fpm*
+`PHP_FPM_PM_MAX_CHILDREN` *Default: "20"*|The number of child processes to be created when pm is set to static and the maximum number of child processes to be created when pm is set to dynamic. (Official docs )|fpm*
+`PHP_FPM_PM_MAX_SPARE_SERVERS` *Default: "3"*|The desired maximum number of idle server processes. Used only when pm is set to dynamic. (Official docs )|fpm*
+`PHP_FPM_PM_MIN_SPARE_SERVERS` *Default: "1"*|The desired minimum number of idle server processes. Used only when pm is set to dynamic. (Official docs )|fpm*
+`PHP_FPM_PM_START_SERVERS` *Default: "2"*|The number of child processes created on startup. Used only when pm is set to dynamic. (Official docs )|fpm*
+`PHP_FPM_POOL_NAME` *Default: "www"*|Set the name of your PHP-FPM pool (helpful when running multiple sites on a single server).|fpm*
+`PHP_MAX_EXECUTION_TIME` *Default: "99"*|Set the maximum time in seconds a script is allowed to run before it is terminated by the parser. (Official docs )|all
+`PHP_MAX_INPUT_TIME` *Default: "-1"*|This sets the maximum time in seconds a script is allowed to parse input data, like POST and GET. Timing begins at the moment PHP is invoked at the server and ends when execution begins. The default setting is -1, which means that max_execution_time is used instead. Set to 0 to allow unlimited time. This directive is hardcoded to -1 for the CLI SAPI by PHP. (Official docs )|all
+`PHP_MEMORY_LIMIT` *Default: "256M"*|Set the maximum amount of memory in bytes that a script is allowed to allocate. (Official docs )|all
+`PHP_OPEN_BASEDIR` *Default: "None"* |Limit the files that can be accessed by PHP to the specified directory-tree, including the file itself. `open_basedir` is just an extra safety net, that is in no way comprehensive, and can therefore not be relied upon when security is needed. (Official docs )| all
+`PHP_POST_MAX_SIZE` *Default: "100M"*|Sets max size of post data allowed. (Official docs )|all
+`PHP_SESSION_COOKIE_SECURE` *Default: 1 (true)*|Specifies whether cookies should only be sent over secure connections. (Official docs )|all
+`PHP_UPLOAD_MAX_FILE_SIZE` *Default: "100M"*|The maximum size of an uploaded file. (Official docs )|all
+`S6_BEHAVIOUR_IF_STAGE2_FAILS` *Default: "2" (stop the container)*|Determines what the container should do if one of the service scripts fails (Official docs )|fpm-nginx, fpm-apache
+`S6_CMD_WAIT_FOR_SERVICES_MAXTIME` *Default: "0"*|The maximum time (in milliseconds) the services could take to bring up before proceeding to CMD executing (Official docs )|fpm-nginx, fpm-apache
+`S6_VERBOSITY` *Default: "1"*|Set the verbosity of "S6 Overlay" (the init system these images are based on). The default is "1" (print warnings and errors). The scale goes from 1 to 5, but the output will quickly become very noisy. If you're having issues, start here. You can also customize many other variables. (Official docs )|fpm-nginx, fpm-apache
+`SSL_CERTIFICATE_FILE` *Default: "/etc/ssl/private/self-signed-web.crt"*|Path to public certificate file for HTTPS. You must provide this file otherwise a self-signed key pair will be generated for you.|fpm-nginx, fpm-apache
+`SSL_MODE` *Default: "off"*|Configure how you would like to handle SSL. This can be "off" (HTTP only), "mixed" (HTTP + HTTPS), or "full" (HTTPS only). If you use HTTP, you may need to also change `PHP_SESSION_COOKIE_SECURE`.|fpm-nginx, fpm-apache, unit
+`SSL_PRIVATE_KEY_FILE` *Default: "/etc/ssl/private/self-signed-web.key"*|Path to private key file for HTTPS. You must provide this file otherwise a self-signed key pair will be generated for you.|fpm-nginx, fpm-apache
+`UNIT_CERTIFICATE_NAME` *Default: "self-signed-web-bundle"*| Name of your certificate bundle. This is used to configure HTTPS. (Official Docs )| unit
+`UNIT_CONFIG_DIRECTORY` *Default: "/etc/unit/config.d"*|Path to the Unit configuration directory. Any *.json, *.js, and *.pem files will be loaded into Unit on initialization.| unit
+`UNIT_CONFIG_FILE` *Default: "/etc/unit/config.d/config.json"*|Path to the Unit configuration file. One will be generated automatically by default. (Official Docs )| unit
+`UNIT_WEBROOT` *Default: "`$APP_BASE_DIR`/public"*|Base directory of the appâs file structure. All URI paths are relative to it. (Official Docs )| unit
-
-
+# Variables that have yet to be added in the beta
+::note
+This section is reserved for the maintainers as we're working on migrating old docs over to the new image format. Any variable listed below **will not** work in the current `beta` release.
+::
**Variable Name**|**Description**|**Used in variation**
:-----:|:-----:|:-----:
`PUID` *Default: 9999*|User ID the webserver and PHP should run as.|all
`PGID` *Default: 9999*|Group ID the webserver and PHP should run as.|all
-`WEBUSER_HOME` *Default: /var/www/html*|BETA: You can change the home of the web user if needed.|all (except *-nginx)
-`PHP_DATE_TIMEZONE` *Default: "UTC"*|Control your timezone. (Official Docs )|fpm, fpm-nginx, fpm-apache
-`PHP_DISPLAY_ERRORS` *Default: Off*|Show PHP errors on screen. (Official docs )|fpm, fpm-nginx, fpm-apache
-`PHP_DISPLAY_STARTUP_ERRORS` *Default: Off*|Even when display_errors is on, errors that occur during PHP's startup sequence are not displayed. (Official docs )| fpm, fpm-nginx, fpm-apache
-`PHP_ERROR_REPORTING` *Default: "22527"*|Set PHP error reporting level. Must be a number. Use this tool for help. (Official docs )|fpm, fpm-nginx, fpm-apache
-`PHP_MAX_EXECUTION_TIME` *Default: "99"*|Set the maximum time in seconds a script is allowed to run before it is terminated by the parser. (Official docs )|fpm, fpm-nginx, fpm-apache
-`PHP_MEMORY_LIMIT` *Default: "256M"*|Set the maximum amount of memory in bytes that a script is allowed to allocate. (Official docs )|fpm, fpm-nginx, fpm-apache
-`PHP_OPEN_BASEDIR` *Default:$WEBUSER_HOME:/dev/stdout:/tmp*|Limit the files that can be accessed by PHP to the specified directory-tree, including the file itself.|fpm, fpm-nginx, fpm-apache
-`PHP_PM_CONTROL` *Defaults: fpm: dynamic fpm-apache: ondemand fpm-nginx: ondemand*|Choose how the process manager will control the number of child processes. (Official docs )|fpm, fpm-nginx, fpm-apache
-`PHP_PM_MAX_CHILDREN` *Default: "20"*|The number of child processes to be created when pm is set to static and the maximum number of child processes to be created when pm is set to dynamic. (Official docs )|fpm, fpm-nginx, fpm-apache
-`PHP_PM_MAX_SPARE_SERVERS` *Default: "3"*|The desired maximum number of idle server processes. Used only when pm is set to dynamic. (Official docs )|fpm, fpm-nginx, fpm-apache
-`PHP_SESSION_COOKIE_SECURE` *Default: 1 (true)*|Specifies whether cookies should only be sent over secure connections. (Official docs )|fpm, fpm-nginx, fpm-apache
-`PHP_PM_MIN_SPARE_SERVERS` *Default: "1"*|The desired minimum number of idle server processes. Used only when pm is set to dynamic. (Official docs )|fpm, fpm-nginx, fpm-apache
-`PHP_PM_START_SERVERS` *Default: "2"*|The number of child processes created on startup. Used only when pm is set to dynamic. (Official docs )|fpm, fpm-nginx, fpm-apache
-`PHP_POOL_NAME` *Default: "www"*|Set the name of your PHP-FPM pool (helpful when running multiple sites on a single server).|fpm, fpm-nginx, fpm-apache
-`PHP_POST_MAX_SIZE` *Default: "100M"*|Sets max size of post data allowed. (Official docs )|fpm, fpm-nginx, fpm-apache
-`PHP_UPLOAD_MAX_FILE_SIZE` *Default: "100M"*|The maximum size of an uploaded file. (Official docs )|fpm, fpm-nginx, fpm-apache
-`AUTORUN_ENABLED` *Default: "true"*|Enable or disable all autoruns. It's advised to set this to `false` in certain CI environments (especially during a composer install)|fpm, fpm-nginx, fpm-apache
-`AUTORUN_LARAVEL_STORAGE_LINK` *Default: "true"*|Automatically run "php artisan storage:link" on container start|fpm, fpm-nginx, fpm-apache
-`AUTORUN_LARAVEL_MIGRATION` *Default: "false"*|Requires Laravel v9.38.0 or higher. Automatically run "php artisan migrate --force --isolated" on container start.|fpm, fpm-nginx, fpm-apache
-`MSMTP_RELAY_SERVER_HOSTNAME` *Default: "mailhog" đ¨ IMPORTANT: Change this value if you want emails to work. (we set it to Mailhog so our staging sites do not send emails out)*|Server that should relay emails for MSMTP. (Official docs )|fpm-nginx, fpm-apache
+`MSMTP_RELAY_SERVER_HOSTNAME` *Default: "mailhog" đ¨ IMPORTANT: Change this value if you want emails to work. (we set it to Mailhog so our staging sites do not send emails out)*|Server that should relay emails for MSMTP. (Official docs )|fpm-nginx, fpm-apache
`MSMTP_RELAY_SERVER_PORT` *Default: "1025" (default port for Mailhog)*|Port the SMTP server is listening on. (Official docs )|fpm-nginx, fpm-apache
-`DEBUG_OUTPUT` *Default: (undefined, false)*|Set this variable to `true` if you want to put PHP and your web server in debug mode.|fpm-nginx, fpm-apache
`APACHE_DOCUMENT_ROOT` *Default: "/var/www/html"*|Sets the directory from which Apache will serve files. (Official docs )|fpm-apache
`APACHE_MAX_CONNECTIONS_PER_CHILD` *Default: "0"*|Sets the limit on the number of connections that an individual child server process will handle.(Official docs )|fpm-apache
`APACHE_MAX_REQUEST_WORKERS` *Default: "150"*|Sets the limit on the number of simultaneous requests that will be served. (Official docs )|fpm-apache
@@ -46,9 +74,4 @@ We like to customize our images on a per app basis using environment variables.
`APACHE_RUN_USER` *Default: "webuser"*|Set the username of what Apache should run as.|fpm-apache
`APACHE_START_SERVERS` *Default: "2"*|Sets the number of child server processes created on startup.(Official docs )|fpm-apache
`APACHE_THREAD_LIMIT` *Default: "64"*|Set the maximum configured value for ThreadsPerChild for the lifetime of the Apache httpd process. (Official docs )|fpm-apache
-`APACHE_THREADS_PER_CHILD` *Default: "25"*|This directive sets the number of threads created by each child process. (Official docs )|fpm-apache
-`COMPOSER_ALLOW_SUPERUSER` *Default: "1"*|Disable warning about running as super-user|all
-`COMPOSER_HOME` *Default: "/composer"*|The COMPOSER_HOME var allows you to change the Composer home directory. This is a hidden, global (per-user on the machine) directory that is shared between all projects.|all
-`COMPOSER_MAX_PARALLEL_HTTP` *Default: "24"*|Set to an integer to configure how many files can be downloaded in parallel. This defaults to 12 and must be between 1 and 50. If your proxy has issues with concurrency maybe you want to lower this. Increasing it should generally not result in performance gains.|all
-`S6_VERBOSITY` *Default: "1"*|Set the verbosity of "S6 Overlay" (the init system these images are based on). The default is "1" (print warnings and errors). The scale goes from 1 to 5, but the output will quickly become very noisy. If you're having issues, start here. You can also customize many other variables. (Official docs )|all
-`SSL_MODE` *Default: "full"*|Configure how you would like to handle SSL. This can be "off" (HTTP only), "mixed" (HTTP + HTTPS), or "full" (HTTPS only). If you use HTTP, you may need to also change `PHP_SESSION_COOKIE_SECURE`.|fpm-nginx, fpm-apache
\ No newline at end of file
+`APACHE_THREADS_PER_CHILD` *Default: "25"*|This directive sets the number of threads created by each child process. (Official docs )|fpm-apache
\ No newline at end of file
diff --git a/docs/content/docs/6.reference/2.command-reference.md b/docs/content/docs/6.reference/2.command-reference.md
new file mode 100644
index 00000000..10acf015
--- /dev/null
+++ b/docs/content/docs/6.reference/2.command-reference.md
@@ -0,0 +1,14 @@
+---
+head.title: 'Command reference - Docker PHP - Server Side Up'
+description: 'Learn about all the commands available within the serversideup/php image to improve your developer experience.'
+layout: docs
+---
+
+### serversideup/php commands
+::note
+**This page is a work in progress.** We will be adding more commands and documentation soon.
+::
+We have a few commands available to help you with your development experience. These commands are available in the `serversideup/php` image.
+
+### Official PHP Docker Commands
+We will document the official PHP Docker commands here for reference. These commands are available in the `serversideup/php` image.
\ No newline at end of file
diff --git a/docs/content/index.md b/docs/content/index.md
index f7378b11..889cc11e 100644
--- a/docs/content/index.md
+++ b/docs/content/index.md
@@ -16,5 +16,8 @@ layout: marketing
::marketing-testimonials
::
+::landing-signup
+::
+
::marketing-follow-along
::
\ No newline at end of file
diff --git a/docs/layouts/docs.vue b/docs/layouts/docs.vue
index 3e769a62..29631aaa 100644
--- a/docs/layouts/docs.vue
+++ b/docs/layouts/docs.vue
@@ -4,11 +4,11 @@
-
-
-
-
-
+
+
+
+
+
@@ -40,6 +40,12 @@
\ No newline at end of file
diff --git a/docs/layouts/marketing.vue b/docs/layouts/marketing.vue
index c8059f59..55fb50b1 100644
--- a/docs/layouts/marketing.vue
+++ b/docs/layouts/marketing.vue
@@ -4,11 +4,11 @@
-
-
-
-
-
+
+
+
+
+
@@ -33,7 +33,12 @@ useHead({
bodyAttrs: {
class: 'antialiased'
},
- title: 'PHP Docker Images - Server Side Up'
+ title: 'PHP Docker Images (serversideup/php) - Server Side Up',
+ script: [
+ {
+ src: 'https://f.convertkit.com/ckjs/ck.5.js'
+ }
+ ]
})
const route = useRoute();
@@ -44,14 +49,14 @@ useSeoMeta({
ogUrl: domain+basePath+route.path,
ogType: 'website',
ogSiteName: 'Server Side Up - Docker PHP',
+ ogTitle: 'Server Side Up - Docker PHP',
+ ogDescription: 'Supercharge your PHP experience, in seconds. Built upon the official PHP images, our production-ready serversideup/php images take your Docker PHP experience to the next level. Enjoy variable-first configurations, nginx-unit variation, native CloudFlare support, and more.',
ogImage: domain+basePath+'/images/social-image.jpg',
ogImageWidth: 1200,
- ogImageHeight: 627,
- ogImageType: 'image/png',
- ogDescription: 'Stop the headache from debugging. Get production-ready PHP Docker Images that help you replicate your application, no matter the environment.',
- ogTitle: 'Server Side Up - Docker PHP',
+ ogImageHeight: 630,
+ ogImageType: 'image/jpg',
twitterCard: 'summary_large_image',
- twitterDescription: 'Stop the headache from debugging. Get production-ready PHP Docker Images that help you replicate your application, no matter the environment.',
+ twitterDescription: 'Supercharge your PHP experience, in seconds. Built upon the official PHP images, our production-ready serversideup/php images take your Docker PHP experience to the next level. Enjoy variable-first configurations, nginx-unit variation, native CloudFlare support, and more.',
twitterImage: domain+basePath+'/images/social-image.jpg',
twitterSite: '@serversideup',
twitterTitle: 'Server Side Up - Docker PHP'
diff --git a/docs/nuxt.config.ts b/docs/nuxt.config.ts
index dd600cd9..586e86df 100644
--- a/docs/nuxt.config.ts
+++ b/docs/nuxt.config.ts
@@ -3,10 +3,10 @@ import tailwindTypography from '@tailwindcss/typography'
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
modules: [
+ 'nuxt-og-image',
'@nuxtjs/algolia',
'@nuxtjs/color-mode',
'@nuxt/content',
- '@nuxt/image-edge',
'@nuxtjs/plausible',
'@nuxtjs/tailwindcss',
'@vueuse/nuxt'
@@ -33,7 +33,6 @@ export default defineNuxtConfig({
},
highlight: {
- // OR
theme: {
// Default theme (same as single string)
default: 'github-dark',
@@ -41,8 +40,15 @@ export default defineNuxtConfig({
dark: 'github-dark',
// Theme used if `html.sepia`
sepia: 'monokai'
- }
- }
+ },
+
+ preload: [
+ 'dockerfile',
+ 'php'
+ ]
+ },
+
+
},
colorMode: {
@@ -55,17 +61,25 @@ export default defineNuxtConfig({
}
},
+ ogImage: {
+ componentDirs: ['~/components/Global/OgImage'],
+ },
+
plausible: {
apiHost: 'https://a.521dimensions.com'
},
runtimeConfig: {
public: {
- basePath: process.env.NUXT_APP_BASE_URL,
+ basePath: process.env.NUXT_APP_BASE_URL || '/',
domain: process.env.TOP_LEVEL_DOMAIN
}
},
+ site: {
+ url: process.env.BASE_PATH,
+ },
+
tailwindcss: {
config: {
plugins: [tailwindTypography]
diff --git a/docs/package.json b/docs/package.json
index 4a248b64..daff32c7 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -9,21 +9,23 @@
},
"devDependencies": {
"@headlessui/vue": "^1.7.8",
- "@nuxt/content": "^2.4.1",
- "@nuxt/image-edge": "^1.0.0-27907872.f4dd19d",
+ "@nuxt/content": "^2.9.0",
"@nuxtjs/color-mode": "^3.2.0",
"@nuxtjs/plausible": "^0.2.0",
- "@nuxtjs/tailwindcss": "^6.3.0",
+ "@nuxtjs/tailwindcss": "^6.9.4",
"@tailwindcss/typography": "^0.5.9",
- "@vueuse/core": "^9.12.0",
- "@vueuse/nuxt": "^9.12.0",
- "nuxt": "^3.1.0",
+ "@vueuse/core": "^10.6.1",
+ "@vueuse/nuxt": "^10.6.1",
+ "nuxt": "^3.8.1",
+ "nuxt-og-image": "^2.2.4",
+ "nuxt-site-config": "^1.6.6",
+ "nuxt-site-config-kit": "^1.6.6",
"sitemap": "^7.1.1",
"surge": "^0.23.1"
},
"dependencies": {
"@docsearch/css": "^3.3.3",
"@docsearch/js": "^3.3.3",
- "@nuxtjs/algolia": "^1.5.0"
+ "@nuxtjs/algolia": "^1.10.1"
}
}
diff --git a/docs/public/images/icons/cloudflare-square.svg b/docs/public/images/icons/cloudflare-square.svg
new file mode 100644
index 00000000..7b7b7e6c
--- /dev/null
+++ b/docs/public/images/icons/cloudflare-square.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/docs/public/images/icons/php-square.svg b/docs/public/images/icons/php-square.svg
new file mode 100644
index 00000000..f3df18d7
--- /dev/null
+++ b/docs/public/images/icons/php-square.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/docs/public/images/icons/ubuntu-square.svg b/docs/public/images/icons/ubuntu-square.svg
deleted file mode 100644
index 9e946cd2..00000000
--- a/docs/public/images/icons/ubuntu-square.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/docs/public/images/logos/og-logo.png b/docs/public/images/logos/og-logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..07560c116066f96fa4fe58a2c84ec25d44e78829
GIT binary patch
literal 5098
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
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
diff --git a/docs/public/images/logos/x-logo.svg b/docs/public/images/logos/x-logo.svg
new file mode 100644
index 00000000..437e2bfd
--- /dev/null
+++ b/docs/public/images/logos/x-logo.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/docs/public/images/social-image.jpg b/docs/public/images/social-image.jpg
index bb3ad184039229090c986b58d7004966c10b9815..9ad70ff90fafb180541913a1dc6db92d2b1e9912 100644
GIT binary patch
literal 229668
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