├── docs ├── .nvmrc ├── .npmrc ├── .gitignore ├── tsconfig.json ├── composables │ └── states.ts ├── public │ └── images │ │ ├── social-image.jpg │ │ ├── docs │ │ ├── watch-repo.png │ │ └── permissions-privileged.png │ │ ├── favicon │ │ ├── favicon.ico │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── mstile-150x150.png │ │ ├── apple-touch-icon.png │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── browserconfig.xml │ │ ├── site.webmanifest │ │ └── safari-pinned-tab.svg │ │ ├── logos │ │ ├── og-logo.png │ │ ├── og-ssu-logo.png │ │ ├── x-logo.svg │ │ ├── nomad.svg │ │ ├── ruby.svg │ │ ├── python.svg │ │ ├── twitter-slate.svg │ │ ├── twitter-white.svg │ │ ├── github-white.svg │ │ ├── github-slate.svg │ │ ├── node.svg │ │ ├── php.svg │ │ ├── discord-white.svg │ │ ├── discord-slate.svg │ │ ├── amplitude.svg │ │ └── go.svg │ │ ├── placeholder-hero-video.png │ │ ├── testimonials │ │ ├── ziga-zajc.png │ │ ├── chris-fidao.png │ │ └── johan-janssens.png │ │ ├── placeholder-optimized-video.png │ │ └── icons │ │ ├── search-icon.svg │ │ ├── heartbeat-square.svg │ │ ├── heart.svg │ │ ├── heart-square.svg │ │ ├── community-icon.svg │ │ ├── lightning-square.svg │ │ ├── docs-icon.svg │ │ ├── rocket-square.svg │ │ ├── shield-square.svg │ │ ├── stars-square.svg │ │ ├── logging-square.svg │ │ ├── cloudflare-square.svg │ │ ├── php-square.svg │ │ └── nginx-square.svg ├── components │ ├── content │ │ ├── NotProse.vue │ │ ├── LeadP.vue │ │ ├── Row.vue │ │ ├── Properties.vue │ │ ├── Column.vue │ │ ├── InfoIcon.vue │ │ ├── Note.vue │ │ ├── Guide.vue │ │ ├── HeartIcon.vue │ │ ├── VideoEmbed.vue │ │ ├── AppHeading3.vue │ │ ├── AppHeading4.vue │ │ ├── Code │ │ │ ├── ClipboardIcon.vue │ │ │ ├── PanelHeader.vue │ │ │ └── CopyButton.vue │ │ ├── Property.vue │ │ ├── Badges.vue │ │ ├── MarketingOptimized.vue │ │ ├── DocsIcon.vue │ │ ├── MarketingHero.vue │ │ ├── AppHeading2.vue │ │ ├── Guides.vue │ │ ├── CodePanel.vue │ │ ├── Resources │ │ │ ├── ResourceIcon.vue │ │ │ ├── Resource.vue │ │ │ └── Pattern.vue │ │ ├── GitHubIcon.vue │ │ ├── DiscordIcon.vue │ │ ├── GridPattern.vue │ │ ├── HeroPattern.vue │ │ ├── About.vue │ │ ├── MarketingDevToProd.vue │ │ ├── AppButton.vue │ │ ├── AppLink.vue │ │ ├── Resources.vue │ │ ├── Libraries.vue │ │ └── MarketingTestimonials.vue │ ├── Icons │ │ ├── Moon.vue │ │ ├── Search.vue │ │ ├── Anchor.vue │ │ ├── Sun.vue │ │ ├── Check.vue │ │ ├── Resource.vue │ │ ├── CheckIcon.vue │ │ ├── Arrow.vue │ │ ├── EnvelopeIcon.vue │ │ ├── ChatBubbleIcon.vue │ │ ├── Social │ │ │ ├── Twitter.vue │ │ │ ├── GitHub.vue │ │ │ └── Discord.vue │ │ ├── ClipboardIcon.vue │ │ ├── UserIcon.vue │ │ └── UsersIcon.vue │ ├── Docs │ │ ├── TopLevelNavItem.vue │ │ ├── Eyebrow.vue │ │ ├── ModeToggle.vue │ │ ├── Search.vue │ │ ├── PageLink.vue │ │ ├── Footer.vue │ │ ├── Anchor.vue │ │ ├── SmallPrint.vue │ │ ├── Tag.vue │ │ ├── Logo.vue │ │ ├── Navigation.vue │ │ ├── NavigationGroup.vue │ │ └── Header.vue │ └── DocumentDrivenNotFound.vue ├── .env.example ├── server │ ├── api │ │ └── search.json.get.ts │ └── routes │ │ └── sitemap.xml.ts ├── assets │ └── css │ │ ├── tailwind.css │ │ ├── docsearch.css │ │ ├── hamburger.css │ │ └── animations.css ├── content │ ├── index.md │ └── docs │ │ ├── 2.getting-started │ │ ├── 5.changelog.md │ │ ├── 4.choosing-a-host.md │ │ └── 3.upgrade-guide.md │ │ ├── 1.index.md │ │ ├── 4.laravel │ │ ├── 3.laravel-queue.md │ │ ├── 4.laravel-horizon.md │ │ ├── 1.laravel-automations.md │ │ └── 2.laravel-task-scheduler.md │ │ ├── 3.guide │ │ └── 1.migrating-from-official-php-images.md │ │ └── 5.customizing-the-image │ │ └── 1.changing-common-php-settings.md ├── middleware │ └── directory.ts ├── package.json ├── README.md ├── tailwind.config.js ├── nuxt.config.ts └── layouts │ ├── marketing.vue │ └── docs.vue ├── .dockerignore ├── src ├── s6 │ ├── etc │ │ └── s6-overlay │ │ │ └── s6-rc.d │ │ │ ├── php-fpm │ │ │ ├── type │ │ │ ├── notification-fd │ │ │ ├── dependencies │ │ │ ├── data │ │ │ │ └── check │ │ │ └── run │ │ │ └── user │ │ │ └── contents.d │ │ │ └── php-fpm │ └── usr │ │ └── local │ │ └── bin │ │ ├── docker-php-serversideup-s6-install │ │ └── docker-php-serversideup-s6-init ├── variations │ ├── fpm-apache │ │ └── etc │ │ │ ├── s6-overlay │ │ │ └── s6-rc.d │ │ │ │ ├── apache2 │ │ │ │ ├── type │ │ │ │ ├── notification-fd │ │ │ │ ├── dependencies │ │ │ │ ├── run │ │ │ │ └── data │ │ │ │ │ └── check │ │ │ │ └── user │ │ │ │ └── contents.d │ │ │ │ └── apache2 │ │ │ └── apache2 │ │ │ ├── sites-available │ │ │ ├── ssl-off.conf │ │ │ ├── ssl-mixed.conf │ │ │ └── ssl-full.conf │ │ │ ├── ports.conf │ │ │ ├── mods-available │ │ │ └── mpm_event.conf │ │ │ ├── conf-available │ │ │ ├── remoteip.conf │ │ │ ├── serversideup.conf │ │ │ └── security.conf │ │ │ └── vhost-templates │ │ │ ├── http.conf │ │ │ └── https.conf │ ├── fpm-nginx │ │ └── etc │ │ │ ├── s6-overlay │ │ │ └── s6-rc.d │ │ │ │ ├── nginx │ │ │ │ ├── type │ │ │ │ ├── dependencies │ │ │ │ ├── notification-fd │ │ │ │ ├── run │ │ │ │ └── data │ │ │ │ │ └── check │ │ │ │ └── user │ │ │ │ └── contents.d │ │ │ │ └── nginx │ │ │ └── nginx │ │ │ ├── sites-available │ │ │ ├── ssl-off │ │ │ ├── ssl-mixed │ │ │ └── ssl-full │ │ │ ├── nginx.conf.template │ │ │ ├── server-opts.d │ │ │ ├── security.conf │ │ │ ├── performance.conf │ │ │ └── remoteip.conf │ │ │ └── site-opts.d │ │ │ ├── http.conf.template │ │ │ └── https.conf.template │ ├── unit │ │ └── etc │ │ │ └── unit │ │ │ └── config.d │ │ │ └── ssl-off.json.template │ └── cli │ │ └── Dockerfile ├── common │ ├── usr │ │ └── local │ │ │ ├── etc │ │ │ └── php │ │ │ │ └── conf.d │ │ │ │ └── zzz-serversideup-docker-php-debug.ini │ │ │ └── bin │ │ │ ├── docker-php-serversideup-install-php-ext-installer │ │ │ ├── docker-php-serversideup-dep-install-alpine │ │ │ ├── docker-php-serversideup-dep-install-debian │ │ │ ├── docker-php-serversideup-entrypoint │ │ │ └── docker-php-serversideup-set-id │ └── etc │ │ └── entrypoint.d │ │ ├── 0-container-info.sh │ │ └── 1-debug-mode.sh └── php-fpm.d │ └── usr │ └── local │ └── etc │ └── php-fpm.d │ └── zzz-docker-php-serversideup-fpm-debug.conf ├── .github ├── img │ └── header.png ├── workflows │ ├── action_publish-images-beta.yml │ ├── action_publish-images-production.yml │ ├── action_publish-images-dev-main.yml │ ├── action_publish-images-prs.yml │ └── scheduled-task_update-sponsors.yml └── ISSUE_TEMPLATE │ ├── config.yml │ └── bug.yml ├── .gitignore ├── CONTRIBUTING.md ├── SECURITY.md └── scripts └── conf └── php-versions-base-config.yml /docs/.nvmrc: -------------------------------------------------------------------------------- 1 | 20 -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store -------------------------------------------------------------------------------- /src/s6/etc/s6-overlay/s6-rc.d/php-fpm/type: -------------------------------------------------------------------------------- 1 | longrun -------------------------------------------------------------------------------- /src/s6/etc/s6-overlay/s6-rc.d/user/contents.d/php-fpm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/s6/etc/s6-overlay/s6-rc.d/php-fpm/notification-fd: -------------------------------------------------------------------------------- 1 | 3 -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/s6-overlay/s6-rc.d/apache2/type: -------------------------------------------------------------------------------- 1 | longrun -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/type: -------------------------------------------------------------------------------- 1 | longrun -------------------------------------------------------------------------------- /docs/.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | strict-peer-dependencies=false 3 | -------------------------------------------------------------------------------- /src/s6/etc/s6-overlay/s6-rc.d/php-fpm/dependencies: -------------------------------------------------------------------------------- 1 | 50-laravel-automations -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/s6-overlay/s6-rc.d/apache2/notification-fd: -------------------------------------------------------------------------------- 1 | 3 -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/s6-overlay/s6-rc.d/user/contents.d/apache2: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/dependencies: -------------------------------------------------------------------------------- 1 | php-fpm -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/notification-fd: -------------------------------------------------------------------------------- 1 | 3 -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/s6-overlay/s6-rc.d/user/contents.d/nginx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/s6-overlay/s6-rc.d/apache2/dependencies: -------------------------------------------------------------------------------- 1 | php-fpm -------------------------------------------------------------------------------- /src/s6/etc/s6-overlay/s6-rc.d/php-fpm/data/check: -------------------------------------------------------------------------------- 1 | #!/command/with-contenv sh 2 | php-fpm-healthcheck -------------------------------------------------------------------------------- /.github/img/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/.github/img/header.png -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log* 3 | .nuxt 4 | .nitro 5 | .cache 6 | .output 7 | .env 8 | dist 9 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json" 4 | } 5 | -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/run: -------------------------------------------------------------------------------- 1 | #!/command/execlineb -P 2 | with-contenv 3 | s6-notifyoncheck 4 | nginx -------------------------------------------------------------------------------- /docs/composables/states.ts: -------------------------------------------------------------------------------- 1 | export const usePreferredProgrammingLanguage = () => useState('programming-language', () => '') -------------------------------------------------------------------------------- /docs/public/images/social-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/social-image.jpg -------------------------------------------------------------------------------- /docs/public/images/docs/watch-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/docs/watch-repo.png -------------------------------------------------------------------------------- /docs/public/images/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/favicon/favicon.ico -------------------------------------------------------------------------------- /docs/public/images/logos/og-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/logos/og-logo.png -------------------------------------------------------------------------------- /docs/public/images/logos/og-ssu-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/logos/og-ssu-logo.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ensure node files do not appear 2 | package-lock.json 3 | package.json 4 | yarn.lock 5 | node_modules 6 | php-versions.yml 7 | *.tmp -------------------------------------------------------------------------------- /src/s6/etc/s6-overlay/s6-rc.d/php-fpm/run: -------------------------------------------------------------------------------- 1 | #!/command/execlineb -P 2 | with-contenv 3 | s6-notifyoncheck -d 4 | /usr/local/sbin/php-fpm --nodaemonize -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guide 2 | See our Contribution Guide: https://serversideup.net/open-source/docker-php/docs/getting-started/contributing -------------------------------------------------------------------------------- /docs/components/content/NotProse.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/public/images/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /docs/public/images/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /docs/public/images/favicon/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/favicon/mstile-150x150.png -------------------------------------------------------------------------------- /docs/public/images/placeholder-hero-video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/placeholder-hero-video.png -------------------------------------------------------------------------------- /docs/public/images/testimonials/ziga-zajc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/testimonials/ziga-zajc.png -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/nginx/sites-available/ssl-off: -------------------------------------------------------------------------------- 1 | # HTTP configuration 2 | # 3 | server { 4 | include /etc/nginx/site-opts.d/http.conf; 5 | } -------------------------------------------------------------------------------- /docs/public/images/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/public/images/testimonials/chris-fidao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/testimonials/chris-fidao.png -------------------------------------------------------------------------------- /docs/.env.example: -------------------------------------------------------------------------------- 1 | NUXT_APP_BASE_URL=/open-source/docker-php 2 | TOP_LEVEL_DOMAIN=http://localhost:3000 3 | BASE_PATH=http://localhost:3000/open-source/docker-php -------------------------------------------------------------------------------- /docs/public/images/docs/permissions-privileged.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/docs/permissions-privileged.png -------------------------------------------------------------------------------- /docs/public/images/placeholder-optimized-video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/placeholder-optimized-video.png -------------------------------------------------------------------------------- /docs/public/images/testimonials/johan-janssens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/testimonials/johan-janssens.png -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/apache2/sites-available/ssl-off.conf: -------------------------------------------------------------------------------- 1 | 2 | Include /etc/apache2/vhost-templates/http.conf 3 | -------------------------------------------------------------------------------- /docs/public/images/favicon/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/favicon/android-chrome-192x192.png -------------------------------------------------------------------------------- /docs/public/images/favicon/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkGhostHunter/docker-php/main/docs/public/images/favicon/android-chrome-512x512.png -------------------------------------------------------------------------------- /docs/components/content/LeadP.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/apache2/ports.conf: -------------------------------------------------------------------------------- 1 | Listen 8080 2 | 3 | 4 | Listen 8443 5 | 6 | 7 | 8 | Listen 8443 9 | -------------------------------------------------------------------------------- /docs/components/content/Row.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/Icons/Moon.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/s6-overlay/s6-rc.d/apache2/run: -------------------------------------------------------------------------------- 1 | #!/command/execlineb -P 2 | with-contenv 3 | 4 | # Set healthcheck sleep delay to 20ms, because you know... Apache 5 | s6-notifyoncheck -s 20 6 | /usr/sbin/apache2ctl -DFOREGROUND -------------------------------------------------------------------------------- /docs/server/api/search.json.get.ts: -------------------------------------------------------------------------------- 1 | import { serverQueryContent } from '#content/server' 2 | 3 | export default eventHandler((event) => { 4 | return serverQueryContent(event).where({ _type: 'markdown', navigation: { $ne: false } }).find() 5 | }) -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/apache2/sites-available/ssl-mixed.conf: -------------------------------------------------------------------------------- 1 | 2 | Include /etc/apache2/vhost-templates/http.conf 3 | 4 | 5 | 6 | Include /etc/apache2/vhost-templates/https.conf 7 | -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/nginx/sites-available/ssl-mixed: -------------------------------------------------------------------------------- 1 | # HTTP configuration 2 | # 3 | server { 4 | include /etc/nginx/site-opts.d/http.conf; 5 | } 6 | 7 | # HTTPS configuration 8 | # 9 | server { 10 | include /etc/nginx/site-opts.d/https.conf; 11 | } -------------------------------------------------------------------------------- /docs/components/content/Properties.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/assets/css/tailwind.css: -------------------------------------------------------------------------------- 1 | @import "animations.css"; 2 | @import "hamburger.css"; 3 | @import "docsearch.css"; 4 | @import 'tailwindcss/base'; 5 | @import 'tailwindcss/components'; 6 | @import 'tailwindcss/utilities'; 7 | ::-webkit-scrollbar { 8 | width: 0px; 9 | height: 0px; 10 | } -------------------------------------------------------------------------------- /docs/components/Icons/Search.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/content/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: marketing 3 | --- 4 | ::marketing-hero 5 | :: 6 | 7 | ::marketing-grid 8 | :: 9 | 10 | ::marketing-optimized 11 | :: 12 | 13 | ::marketing-dev-to-prod 14 | :: 15 | 16 | ::marketing-testimonials 17 | :: 18 | 19 | ::landing-signup 20 | :: 21 | 22 | ::marketing-follow-along 23 | :: -------------------------------------------------------------------------------- /docs/public/images/favicon/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #da532c 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/components/Icons/Anchor.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/common/usr/local/etc/php/conf.d/zzz-serversideup-docker-php-debug.ini: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ; This is an intentionally empty file. It is used as a placeholder 3 | ; for setting proper file permissions when DEBUG mode is enabled. 4 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 5 | -------------------------------------------------------------------------------- /src/php-fpm.d/usr/local/etc/php-fpm.d/zzz-docker-php-serversideup-fpm-debug.conf: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ; This is an intentionally empty file. It is used as a placeholder 3 | ; for setting proper file permissions when DEBUG mode is enabled. 4 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 5 | -------------------------------------------------------------------------------- /docs/components/Docs/TopLevelNavItem.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 13 | -------------------------------------------------------------------------------- /docs/components/Icons/Sun.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/content/Column.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /docs/public/images/icons/search-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/public/images/icons/heartbeat-square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/components/Icons/Check.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/content/InfoIcon.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/public/images/logos/x-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/components/Icons/Resource.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /docs/components/content/Note.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/workflows/action_publish-images-beta.yml: -------------------------------------------------------------------------------- 1 | name: Docker Publish (Beta Images) 2 | 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [prereleased] 7 | schedule: 8 | - cron: '25 8 * * 1' 9 | 10 | jobs: 11 | build-beta-images: 12 | uses: ./.github/workflows/service_docker-build-and-publish.yml 13 | with: 14 | registry-repositories: "docker.io/serversideup/php,ghcr.io/serversideup/php" 15 | tag-prefix: "beta" 16 | release-type: "testing" 17 | secrets: inherit -------------------------------------------------------------------------------- /docs/components/Docs/Eyebrow.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /docs/components/Icons/CheckIcon.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | -------------------------------------------------------------------------------- /docs/components/Icons/Arrow.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | -------------------------------------------------------------------------------- /docs/public/images/icons/heart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/public/images/favicon/site.webmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "short_name": "", 4 | "icons": [ 5 | { 6 | "src": "/android-chrome-192x192.png", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | }, 10 | { 11 | "src": "/android-chrome-512x512.png", 12 | "sizes": "512x512", 13 | "type": "image/png" 14 | } 15 | ], 16 | "theme_color": "#ffffff", 17 | "background_color": "#ffffff", 18 | "display": "standalone" 19 | } 20 | -------------------------------------------------------------------------------- /.github/workflows/action_publish-images-production.yml: -------------------------------------------------------------------------------- 1 | name: Docker Publish (Production Images) 2 | 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [released] 7 | # Commenting out until 3.x is launched 8 | # schedule: 9 | # - cron: '0 8 * * 2' 10 | 11 | jobs: 12 | build-production-images: 13 | uses: ./.github/workflows/service_docker-build-and-publish.yml 14 | with: 15 | registry-repositories: "docker.io/serversideup/php,ghcr.io/serversideup/php" 16 | tag-prefix: '' 17 | release-type: "latest" 18 | secrets: inherit -------------------------------------------------------------------------------- /docs/components/Icons/EnvelopeIcon.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/content/Guide.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | -------------------------------------------------------------------------------- /docs/public/images/logos/nomad.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/components/content/HeartIcon.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/public/images/logos/ruby.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | The following versions of PHP are being actively updated: 5 | 6 | | PHP Version | Supported | 7 | | ------- | ------------------ | 8 | | 8.2 | :white_check_mark: | 9 | | 8.1 | :white_check_mark: | 10 | | 8.0 | :white_check_mark: | 11 | | 7.4 | :white_check_mark: | 12 | | 7.3 | :x: | 13 | 14 | ## Reporting a Vulnerability 15 | 16 | If you have a vulnerability to report, please follow [our responsible disclosure policy](https://www.notion.so/Responsible-Disclosure-Policy-421a6a3be1714d388ebbadba7eebbdc8). 17 | -------------------------------------------------------------------------------- /docs/components/content/VideoEmbed.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /docs/components/content/AppHeading3.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /docs/components/content/AppHeading4.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /docs/content/docs/2.getting-started/5.changelog.md: -------------------------------------------------------------------------------- 1 | --- 2 | head.title: 'Changelog - Docker PHP - Server Side Up' 3 | description: 'See the latest releases and changes for the PHP Docker Image project.' 4 | layout: docs 5 | --- 6 | 7 | # Changelog 8 | All our changes are documented and published on our GitHub. [See our release notes on GitHub →](https://github.com/serversideup/docker-php/releases) 9 | 10 | ### Choosing a version 11 | 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. -------------------------------------------------------------------------------- /docs/components/Icons/ChatBubbleIcon.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | -------------------------------------------------------------------------------- /docs/components/content/Code/ClipboardIcon.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/public/images/icons/heart-square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: ❓ Support Question 4 | url: https://github.com/serversideup/docker-php/discussions 5 | about: Get friendly support from the community in Discussions. 6 | 7 | - name: ✨ Request a feature 8 | url: https://github.com/serversideup/docker-php/discussions/66 9 | about: Learn how to request a new feature. 10 | 11 | - name: 🤵 Get Professional Support & Customizations 12 | url: https://serversideup.net/professional-support 13 | about: Skip the line and get priority support directly from the creators of Server Side Up. 14 | -------------------------------------------------------------------------------- /docs/components/Icons/Social/Twitter.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/public/images/icons/community-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/s6-overlay/s6-rc.d/nginx/data/check: -------------------------------------------------------------------------------- 1 | #!/command/with-contenv sh 2 | curl_options="--fail --location --insecure --silent --show-error --output /dev/null" 3 | healthcheck_url="http://localhost:8080${HEALTHCHECK_PATH}" 4 | 5 | is_online() { 6 | curl $curl_options "$healthcheck_url" 7 | } 8 | 9 | if is_online; then 10 | echo "✅ NGINX + PHP-FPM is running correctly." 11 | exit 0 12 | else 13 | echo "❌ There seems to be a failure in checking the NGINX + PHP-FPM." 14 | status_code=$(curl $curl_options -w "%{http_code}" "$healthcheck_url") 15 | echo "HTTP Status Code: $status_code" 16 | exit 1 17 | fi 18 | -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/s6-overlay/s6-rc.d/apache2/data/check: -------------------------------------------------------------------------------- 1 | #!/command/with-contenv sh 2 | curl_options="--fail --location --insecure --silent --show-error --output /dev/null" 3 | healthcheck_url="http://localhost:8080${HEALTHCHECK_PATH}" 4 | 5 | is_online() { 6 | curl $curl_options "$healthcheck_url" 7 | } 8 | 9 | if is_online; then 10 | echo "✅ Apache + PHP-FPM is running correctly." 11 | exit 0 12 | else 13 | echo "❌ There seems to be a failure in checking the Apache + PHP-FPM." 14 | status_code=$(curl $curl_options -w "%{http_code}" "$healthcheck_url") 15 | echo "HTTP Status Code: $status_code" 16 | exit 1 17 | fi 18 | -------------------------------------------------------------------------------- /docs/components/Docs/ModeToggle.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | -------------------------------------------------------------------------------- /docs/components/Icons/ClipboardIcon.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/server/routes/sitemap.xml.ts: -------------------------------------------------------------------------------- 1 | import { serverQueryContent } from '#content/server' 2 | import { SitemapStream, streamToPromise } from 'sitemap' 3 | export default defineEventHandler(async (event) => { 4 | // Fetch all documents 5 | const docs = await serverQueryContent(event).find() 6 | const sitemap = new SitemapStream({ 7 | hostname: 'https://serversideup.net' 8 | }) 9 | 10 | for (const doc of docs) { 11 | sitemap.write({ 12 | url: '/open-source/docker-php'+doc._path, 13 | changefreq: 'monthly' 14 | }) 15 | } 16 | 17 | 18 | sitemap.end() 19 | return streamToPromise(sitemap) 20 | }) -------------------------------------------------------------------------------- /.github/workflows/action_publish-images-dev-main.yml: -------------------------------------------------------------------------------- 1 | name: Docker Publish (Dev "Main" Images) 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - main 8 | paths: 9 | - src/** 10 | - .github/workflows/action_publish-images-** 11 | - .github/workflows/service_docker-** 12 | - scripts/** 13 | 14 | jobs: 15 | build-dev-images: 16 | uses: ./.github/workflows/service_docker-build-and-publish.yml 17 | with: 18 | registry-repositories: "docker.io/serversideup/php-dev" # Set to our development repository 19 | tag-prefix: '' 20 | release-type: latest 21 | authenticate_with_ghcr: false 22 | secrets: inherit -------------------------------------------------------------------------------- /docs/middleware/directory.ts: -------------------------------------------------------------------------------- 1 | export default defineNuxtRouteMiddleware(( to, from ) => { 2 | let redirectPath = to.path.endsWith('/') ? to.path.slice(0, -1) : to.path; 3 | 4 | switch( redirectPath ){ 5 | case '/docs/getting-started': 6 | return navigateTo( redirectPath+'/these-images-vs-others', { replace: true } ); 7 | break; 8 | case '/docs/guide': 9 | return navigateTo( redirectPath+'/choosing-the-right-image', { replace: true } ); 10 | break; 11 | case '/docs/reference': 12 | return navigateTo( redirectPath+'/environment-variable-specification', { replace: true } ); 13 | break; 14 | } 15 | }) -------------------------------------------------------------------------------- /docs/public/images/icons/lightning-square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/components/Docs/Search.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | -------------------------------------------------------------------------------- /docs/components/content/Code/PanelHeader.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | -------------------------------------------------------------------------------- /docs/components/content/Property.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | -------------------------------------------------------------------------------- /docs/components/Docs/PageLink.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | -------------------------------------------------------------------------------- /docs/components/content/Badges.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/content/MarketingOptimized.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | -------------------------------------------------------------------------------- /docs/components/Docs/Footer.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | -------------------------------------------------------------------------------- /docs/public/images/icons/docs-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.github/workflows/action_publish-images-prs.yml: -------------------------------------------------------------------------------- 1 | name: Docker Publish (PR Images) 2 | 3 | on: 4 | workflow_dispatch: 5 | pull_request: 6 | types: [opened, synchronize, reopened] 7 | paths: 8 | - src/** 9 | - .github/workflows/action_publish-images-** 10 | - .github/workflows/service_docker-** 11 | - scripts/** 12 | 13 | jobs: 14 | build-dev-images: 15 | if: ${{ github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork }} 16 | uses: ./.github/workflows/service_docker-build-and-publish.yml 17 | with: 18 | registry-repositories: "docker.io/serversideup/php-dev" # Set to our development repository 19 | tag-prefix: "${{ github.event.pull_request.number }}" 20 | release-type: testing 21 | authenticate_with_ghcr: false 22 | secrets: inherit -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "build": "nuxt build", 5 | "dev": "nuxt dev", 6 | "generate": "nuxt generate", 7 | "preview": "nuxt preview", 8 | "postinstall": "nuxt prepare" 9 | }, 10 | "devDependencies": { 11 | "@headlessui/vue": "^1.7.8", 12 | "@nuxtjs/color-mode": "^3.2.0", 13 | "@nuxtjs/plausible": "^0.2.0", 14 | "@nuxtjs/tailwindcss": "^6.11.3", 15 | "@tailwindcss/typography": "^0.5.9", 16 | "@vueuse/core": "^10.7.2", 17 | "@vueuse/nuxt": "^10.7.2", 18 | "nuxt-og-image": "^2.2.4", 19 | "nuxt-site-config": "^1.6.6", 20 | "nuxt-site-config-kit": "^1.6.6", 21 | "sitemap": "^7.1.1", 22 | "surge": "^0.23.1" 23 | }, 24 | "dependencies": { 25 | "@heroicons/vue": "^2.1.3", 26 | "@nuxt/content": "^2.12.1", 27 | "nuxt": "^3.11.2" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/nginx/nginx.conf.template: -------------------------------------------------------------------------------- 1 | worker_processes auto; 2 | 3 | error_log /dev/stderr $LOG_OUTPUT_LEVEL; 4 | pid /var/run/nginx.pid; 5 | daemon off; 6 | 7 | 8 | events { 9 | worker_connections 1024; 10 | } 11 | 12 | 13 | http { 14 | include /etc/nginx/mime.types; 15 | default_type application/octet-stream; 16 | server_tokens $NGINX_SERVER_TOKENS; 17 | 18 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 19 | '$status $body_bytes_sent "$http_referer" ' 20 | '"$http_user_agent" "$http_x_forwarded_for"'; 21 | 22 | access_log /dev/stdout main; 23 | 24 | sendfile on; 25 | #tcp_nopush on; 26 | 27 | keepalive_timeout 65; 28 | 29 | #gzip on; 30 | 31 | include /etc/nginx/conf.d/*.conf; 32 | } 33 | -------------------------------------------------------------------------------- /docs/components/content/DocsIcon.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/nginx/server-opts.d/security.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Security Headers 3 | # 4 | 5 | # Prevent IFRAME spoofing attacks 6 | add_header X-Frame-Options "SAMEORIGIN" always; 7 | 8 | # Prevent MIME attacks 9 | add_header X-Content-Type-Options "nosniff" always; 10 | 11 | # Prevent Referrer URL from being leaked 12 | add_header Referrer-Policy "no-referrer-when-downgrade" always; 13 | 14 | # Configure Content Security Policy 15 | # UPDATE - September 2020: Commenting this out until we grasp better security requirements 16 | #add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; 17 | 18 | # Enable HSTS 19 | add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; 20 | 21 | # Prevent access to . files (the well-known directory) 22 | location ~ /\.(?!well-known) { 23 | deny all; 24 | } -------------------------------------------------------------------------------- /docs/components/Docs/Anchor.vue: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /docs/public/images/logos/python.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/components/Icons/UserIcon.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/Icons/UsersIcon.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/components/content/MarketingHero.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | -------------------------------------------------------------------------------- /docs/public/images/icons/rocket-square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/components/Icons/Social/GitHub.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/apache2/mods-available/mpm_event.conf: -------------------------------------------------------------------------------- 1 | # event MPM 2 | # StartServers: initial number of server processes to start 3 | # MinSpareThreads: minimum number of worker threads which are kept spare 4 | # MaxSpareThreads: maximum number of worker threads which are kept spare 5 | # ThreadsPerChild: constant number of worker threads in each server process 6 | # MaxRequestWorkers: maximum number of worker threads 7 | # MaxConnectionsPerChild: maximum number of requests a server process serves 8 | 9 | StartServers ${APACHE_START_SERVERS} 10 | MinSpareThreads ${APACHE_MIN_SPARE_THREADS} 11 | MaxSpareThreads ${APACHE_MAX_SPARE_THREADS} 12 | ThreadLimit ${APACHE_THREAD_LIMIT} 13 | ThreadsPerChild ${APACHE_THREADS_PER_CHILD} 14 | MaxRequestWorkers ${APACHE_MAX_REQUEST_WORKERS} 15 | MaxConnectionsPerChild ${APACHE_MAX_CONNECTIONS_PER_CHILD} 16 | 17 | 18 | # vim: syntax=apache ts=4 sw=4 sts=4 sr noet 19 | -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/nginx/sites-available/ssl-full: -------------------------------------------------------------------------------- 1 | # HTTP Redirect configuration 2 | # 3 | server { 4 | listen 8080 default_server; 5 | listen [::]:8080 default_server; 6 | 7 | server_name _; 8 | 9 | location / { 10 | set $redirect_to_local_https 0; 11 | 12 | # Check for IPv4 and IPv6 localhost addresses 13 | if ($remote_addr ~ ^127\.0\.0\.1$) { 14 | access_log off; 15 | set $redirect_to_local_https 1; 16 | } 17 | if ($remote_addr ~ ^::1$) { 18 | access_log off; 19 | set $redirect_to_local_https 1; 20 | } 21 | 22 | if ($redirect_to_local_https) { 23 | access_log off; 24 | return 301 https://localhost:8443$request_uri; 25 | } 26 | 27 | return 301 https://$host$request_uri; 28 | } 29 | } 30 | 31 | # HTTPS configuration 32 | # 33 | server { 34 | include /etc/nginx/site-opts.d/https.conf; 35 | } 36 | -------------------------------------------------------------------------------- /docs/public/images/logos/twitter-slate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/public/images/logos/twitter-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/components/DocumentDrivenNotFound.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /docs/components/content/AppHeading2.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/apache2/sites-available/ssl-full.conf: -------------------------------------------------------------------------------- 1 | 2 | # Configure ServerAdmin and ServerName 3 | ServerName localhost 4 | ServerAdmin webmaster@localhost 5 | 6 | # Set CloudFlare Real IP 7 | RemoteIPHeader CF-Connecting-IP 8 | 9 | # Turn on rewrite engine 10 | RewriteEngine On 11 | 12 | # Redirect traffic from localhost to https://localhost:8443 13 | RewriteCond %{SERVER_NAME} =localhost 14 | RewriteRule ^ https://%{SERVER_NAME}:8443%{REQUEST_URI} [END,NE,R=permanent] 15 | 16 | # Redirect all other traffic to https://host:443 17 | RewriteCond %{SERVER_NAME} !=localhost 18 | RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L] 19 | 20 | # Configure Log Settings 21 | LogFormat "%l %u %t %v %a \"%r\" %>s %b" comonvhost 22 | ErrorLog /dev/stderr 23 | TransferLog /dev/stdout 24 | LogLevel ${LOG_OUTPUT_LEVEL} 25 | 26 | 27 | 28 | 29 | Include /etc/apache2/vhost-templates/https.conf 30 | -------------------------------------------------------------------------------- /docs/public/images/icons/shield-square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Documentation & Static Site, generated with Nuxt Content 2 | This is a documentation site built on top of Nuxt Content (v3). 3 | 4 | # Docs location 5 | All docs are located in the [./content](./content/docs) folder if you're just looking for the docs in plain text. 6 | 7 | ## Setup 8 | 9 | Ensure you're in the right directory. 10 | 11 | ```bash 12 | cd docs/ 13 | ``` 14 | 15 | Copy over the environment variable example file. 16 | 17 | ```bash 18 | cp .env.example .env 19 | ``` 20 | 21 | Make sure to install the dependencies: 22 | 23 | ```bash 24 | yarn install 25 | ``` 26 | 27 | ## Development Server 28 | 29 | Start the development server on http://localhost:3000 30 | 31 | ```bash 32 | yarn dev 33 | ``` 34 | 35 | ## Production 36 | 37 | Build the application for production: 38 | 39 | ```bash 40 | yarn build 41 | ``` 42 | 43 | Locally preview production build: 44 | 45 | ```bash 46 | yarn preview 47 | ``` 48 | 49 | Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. 50 | -------------------------------------------------------------------------------- /src/common/usr/local/bin/docker-php-serversideup-install-php-ext-installer: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -oe 3 | 4 | ################################################### 5 | # Usage: docker-php-serversideup-install-php-ext-installer [version] 6 | ################################################### 7 | # This script installs the "install-php-extensions" script from 8 | # https://github.com/mlocati/docker-php-extension-installer 9 | script_name="docker-php-serversideup-install-php-ext-installer" 10 | 11 | ############ 12 | # Environment variables 13 | ############ 14 | PHP_EXT_INSTALLER_VERSION="2.2.19" 15 | 16 | ############ 17 | # Main 18 | ############ 19 | if [ -n "$1" ]; then 20 | PHP_EXT_INSTALLER_VERSION="$1" 21 | fi 22 | 23 | curl -sSLf -o /usr/local/bin/install-php-extensions \ 24 | "https://github.com/mlocati/docker-php-extension-installer/releases/download/$PHP_EXT_INSTALLER_VERSION/install-php-extensions" 25 | chmod +x /usr/local/bin/install-php-extensions 26 | 27 | echo "$script_name: ⚡️ Installed $PHP_EXT_INSTALLER_VERSION of \"install-php-extensions\"" -------------------------------------------------------------------------------- /docs/public/images/icons/stars-square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/apache2/conf-available/remoteip.conf: -------------------------------------------------------------------------------- 1 | RemoteIPHeader CF-Connecting-IP 2 | RemoteIPTrustedProxy 173.245.48.0/20 3 | RemoteIPTrustedProxy 103.21.244.0/22 4 | RemoteIPTrustedProxy 103.22.200.0/22 5 | RemoteIPTrustedProxy 103.31.4.0/22 6 | RemoteIPTrustedProxy 141.101.64.0/18 7 | RemoteIPTrustedProxy 108.162.192.0/18 8 | RemoteIPTrustedProxy 190.93.240.0/20 9 | RemoteIPTrustedProxy 188.114.96.0/20 10 | RemoteIPTrustedProxy 197.234.240.0/22 11 | RemoteIPTrustedProxy 198.41.128.0/17 12 | RemoteIPTrustedProxy 162.158.0.0/15 13 | RemoteIPTrustedProxy 172.64.0.0/13 14 | RemoteIPTrustedProxy 131.0.72.0/22 15 | RemoteIPTrustedProxy 104.16.0.0/13 16 | RemoteIPTrustedProxy 104.24.0.0/14 17 | RemoteIPTrustedProxy 2400:cb00::/32 18 | RemoteIPTrustedProxy 2606:4700::/32 19 | RemoteIPTrustedProxy 2803:f800::/32 20 | RemoteIPTrustedProxy 2405:b500::/32 21 | RemoteIPTrustedProxy 2405:8100::/32 22 | RemoteIPTrustedProxy 2a06:98c0::/29 23 | RemoteIPTrustedProxy 2c0f:f248::/32 24 | RemoteIPTrustedProxy 10.0.0.0/8 25 | RemoteIPTrustedProxy 172.16.0.0/12 26 | RemoteIPTrustedProxy 192.168.0.0/16 -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/nginx/server-opts.d/performance.conf: -------------------------------------------------------------------------------- 1 | # favicon.ico 2 | location = /favicon.ico { 3 | log_not_found off; 4 | access_log off; 5 | } 6 | 7 | # robots.txt 8 | location = /robots.txt { 9 | log_not_found off; 10 | access_log off; 11 | } 12 | 13 | # assets, media 14 | location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ { 15 | expires 7d; 16 | access_log off; 17 | log_not_found off; 18 | # Pass to PHP to ensure PHP apps can handle routes that end in these filetypes 19 | try_files $uri /index.php?$query_string; 20 | } 21 | 22 | # svg, fonts 23 | location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ { 24 | add_header Access-Control-Allow-Origin "*"; 25 | expires 7d; 26 | access_log off; 27 | } 28 | 29 | # gzip 30 | gzip on; 31 | gzip_vary on; 32 | gzip_proxied any; 33 | gzip_comp_level 6; 34 | gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml; -------------------------------------------------------------------------------- /docs/components/content/Guides.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | -------------------------------------------------------------------------------- /docs/components/content/CodePanel.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | -------------------------------------------------------------------------------- /docs/public/images/icons/logging-square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/components/content/Resources/ResourceIcon.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/nginx/server-opts.d/remoteip.conf: -------------------------------------------------------------------------------- 1 | ## 2 | # Real IP Addresses 3 | ## 4 | 5 | # Configure docker networks 6 | set_real_ip_from 10.0.0.0/8; 7 | set_real_ip_from 172.16.0.0/12; 8 | set_real_ip_from 192.168.0.0/16; 9 | 10 | # CloudFlare 11 | set_real_ip_from 173.245.48.0/20; 12 | set_real_ip_from 103.21.244.0/22; 13 | set_real_ip_from 103.22.200.0/22; 14 | set_real_ip_from 103.31.4.0/22; 15 | set_real_ip_from 141.101.64.0/18; 16 | set_real_ip_from 108.162.192.0/18; 17 | set_real_ip_from 190.93.240.0/20; 18 | set_real_ip_from 188.114.96.0/20; 19 | set_real_ip_from 197.234.240.0/22; 20 | set_real_ip_from 198.41.128.0/17; 21 | set_real_ip_from 162.158.0.0/15; 22 | set_real_ip_from 104.16.0.0/13; 23 | set_real_ip_from 104.24.0.0/14; 24 | set_real_ip_from 172.64.0.0/13; 25 | set_real_ip_from 131.0.72.0/22; 26 | set_real_ip_from 2400:cb00::/32; 27 | set_real_ip_from 2606:4700::/32; 28 | set_real_ip_from 2803:f800::/32; 29 | set_real_ip_from 2405:b500::/32; 30 | set_real_ip_from 2405:8100::/32; 31 | set_real_ip_from 2a06:98c0::/29; 32 | set_real_ip_from 2c0f:f248::/32; 33 | 34 | # Set RealIP header 35 | real_ip_header CF-Connecting-IP; 36 | real_ip_recursive on; -------------------------------------------------------------------------------- /docs/components/Icons/Social/Discord.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/public/images/logos/github-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/components/Docs/SmallPrint.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | -------------------------------------------------------------------------------- /docs/public/images/logos/github-slate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/assets/css/docsearch.css: -------------------------------------------------------------------------------- 1 | button.DocSearch-Button{ 2 | background: transparent; 3 | font-family: "Inter", sans-serif; 4 | border-radius: 4px; 5 | margin: 0px; 6 | } 7 | 8 | button.DocSearch-Button .DocSearch-Search-Icon{ 9 | margin-right: 8px; 10 | width: 20px; 11 | height: 20px; 12 | stroke-width: 2; 13 | stroke-linecap: round; 14 | stroke-linejoin: round; 15 | color: #CBD5E1; 16 | } 17 | 18 | button.DocSearch-Button .DocSearch-Button-Placeholder{ 19 | font-weight: bold; 20 | color: rgb(203, 213, 225); 21 | font-size: 0.875rem/* 14px */; 22 | line-height: 1.5rem/* 24px */; 23 | padding: 0px; 24 | display: none; 25 | } 26 | 27 | @media (min-width: 1024px) { 28 | button.DocSearch-Button .DocSearch-Button-Placeholder{ 29 | display: block; 30 | } 31 | } 32 | 33 | @media (min-width: 1280px) { 34 | button.DocSearch-Button .DocSearch-Button-Placeholder{ 35 | font-size: 1.125rem/* 18px */; 36 | line-height: 1.75rem/* 28px */; 37 | } 38 | } 39 | 40 | button.DocSearch-Button:hover, 41 | button.DocSearch-Button:active, 42 | button.DocSearch-Button:focus { 43 | background: rgb(17, 24, 39); 44 | box-shadow: none; 45 | } 46 | 47 | button.DocSearch-Button .DocSearch-Button-Keys{ 48 | display: none; 49 | } 50 | -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/nginx/site-opts.d/http.conf.template: -------------------------------------------------------------------------------- 1 | listen 8080 default_server; 2 | listen [::]:8080 default_server; 3 | 4 | root $NGINX_WEBROOT; 5 | 6 | # Set allowed "index" files 7 | index index.html index.htm index.php; 8 | 9 | server_name _; 10 | 11 | charset utf-8; 12 | 13 | # Set max upload to 2048M 14 | client_max_body_size 2048M; 15 | 16 | # Healthchecks: Set /healthcheck to be the healthcheck URL 17 | location /healthcheck { 18 | access_log off; 19 | 20 | # set max 5 seconds for healthcheck 21 | fastcgi_read_timeout 5s; 22 | 23 | include fastcgi_params; 24 | fastcgi_param SCRIPT_NAME /healthcheck; 25 | fastcgi_param SCRIPT_FILENAME /healthcheck; 26 | fastcgi_pass 127.0.0.1:9000; 27 | } 28 | 29 | # Have NGINX try searching for PHP files as well 30 | location / { 31 | try_files $uri $uri/ /index.php?$query_string; 32 | } 33 | 34 | # Pass "*.php" files to PHP-FPM 35 | location ~ \.php$ { 36 | fastcgi_pass 127.0.0.1:9000; 37 | fastcgi_index index.php; 38 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 39 | include fastcgi_params; 40 | fastcgi_buffers $NGINX_FASTCGI_BUFFERS; 41 | fastcgi_buffer_size $NGINX_FASTCGI_BUFFER_SIZE; 42 | } 43 | 44 | # additional config 45 | include /etc/nginx/server-opts.d/*.conf; -------------------------------------------------------------------------------- /docs/components/content/GitHubIcon.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/public/images/favicon/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.14, written by Peter Selinger 2001-2017 9 | 10 | 12 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /docs/components/content/DiscordIcon.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/public/images/logos/node.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /src/common/usr/local/bin/docker-php-serversideup-dep-install-alpine: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -oe 3 | 4 | ################################################### 5 | # Usage: docker-php-serversideup-dep-install-alpine [alpine-packages] 6 | ################################################### 7 | # This script installs alpine packages that are passed to it 8 | 9 | script_name="docker-php-serversideup-dep-install-alpine" 10 | 11 | ############ 12 | # Sanity checks 13 | ############ 14 | if [ -f /etc/os-release ]; then 15 | # Source the os-release file (including the $NAME variable) 16 | . /etc/os-release 17 | else 18 | echo "🛑 ERROR ($script_name): Unable to determine the OS." 19 | exit 1 20 | fi 21 | 22 | if [ "$NAME" != "Alpine Linux" ] || [ $# -eq 0 ]; then 23 | echo "ℹ️ INFO ($script_name): No arguments were passed or the OS is not Alpine Linux. Continuing..." 24 | exit 0 25 | fi 26 | 27 | ############ 28 | # Functions 29 | ############ 30 | convert_comma_delimited_to_space_separated() { 31 | echo $1 | tr ',' ' ' 32 | } 33 | 34 | ############ 35 | # Main 36 | ############ 37 | DEP_PACKAGES=$(convert_comma_delimited_to_space_separated "$@") 38 | echo "🤖 Installing: $DEP_PACKAGES" 39 | apk update 40 | apk add --no-cache $DEP_PACKAGES 41 | 42 | 43 | echo "🧼 Cleaning up installation of: $DEP_PACKAGES" 44 | rm -rf /var/cache/apk/* 45 | 46 | echo "⚡️ Completed installation of: $DEP_PACKAGES" -------------------------------------------------------------------------------- /docs/components/content/GridPattern.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 40 | -------------------------------------------------------------------------------- /docs/components/content/HeroPattern.vue: -------------------------------------------------------------------------------- 1 | 22 | 23 | 31 | -------------------------------------------------------------------------------- /docs/public/images/logos/php.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /docs/content/docs/1.index.md: -------------------------------------------------------------------------------- 1 | --- 2 | 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.' 3 | head.title: 'Introduction - Docker Images - Server Side Up' 4 | layout: docs 5 | --- 6 | 7 | # Introduction 8 | 9 | 10 | 11 | ## What's "serversideup/php"? 12 | ::badges 13 | :: 14 | 15 | **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. 16 | 17 | ## These images are very different from other PHP Docker images 18 | ::features 19 | :: 20 | 21 | [Read more about the advantages →](/docs/getting-started/these-images-vs-others) 22 | 23 | ## Why should I use these PHP Docker Images? 24 | These images are a contribution to the PHP community to help make PHP application management as simple as possible. We focus on making a quick and easy process to get your application running in minutes. 25 | 26 | [Installation →](/docs/getting-started/installation) -------------------------------------------------------------------------------- /docs/components/Docs/Tag.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | -------------------------------------------------------------------------------- /docs/components/content/Resources/Resource.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | -------------------------------------------------------------------------------- /src/common/usr/local/bin/docker-php-serversideup-dep-install-debian: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -oe 3 | 4 | ################################################### 5 | # Usage: docker-php-serversideup-dep-install-debian [debian-packages] 6 | ################################################### 7 | # This script installs debian packages that are passed to it 8 | 9 | DEBIAN_FRONTEND=noninteractive 10 | script_name="docker-php-serversideup-dep-install-debian" 11 | 12 | ############ 13 | # Sanity checks 14 | ############ 15 | if [ -f /etc/os-release ]; then 16 | # Source the os-release file (including the $NAME variable) 17 | . /etc/os-release 18 | else 19 | echo "🛑 ERROR ($script_name): Unable to determine the OS." 20 | exit 1 21 | fi 22 | 23 | if [ "$NAME" != "Debian GNU/Linux" ] || [ $# -eq 0 ]; then 24 | echo "ℹ️ INFO ($script_name): No arguments were passed or the OS is not Debian GNU/Linux. Continuing..." 25 | exit 0 26 | fi 27 | 28 | ############ 29 | # Functions 30 | ############ 31 | convert_comma_delimited_to_space_separated() { 32 | echo $1 | tr ',' ' ' 33 | } 34 | 35 | ############ 36 | # Main 37 | ############ 38 | DEP_PACKAGES=$(convert_comma_delimited_to_space_separated "$@") 39 | echo "🤖 Installing: $DEP_PACKAGES" 40 | apt-get update 41 | apt-get install -y $DEP_PACKAGES 42 | 43 | 44 | echo "🧼 Cleaning up installation of: $DEP_PACKAGES" 45 | apt-get clean 46 | rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 47 | 48 | echo "⚡️ Completed installation of: $DEP_PACKAGES" -------------------------------------------------------------------------------- /src/common/usr/local/bin/docker-php-serversideup-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then 5 | echo "🔥🔥🔥 DEBUG MODE has been set. Get ready for a ton of debug log output..." 6 | set -x 7 | fi 8 | 9 | ############################################### 10 | # Usage: docker-php-serversideup-entrypoint 11 | ############################################### 12 | # This script is used to execute scripts from "/etc/entrypoint.d" and then 13 | # execute the CMD passed in from the Dockerfile. 14 | 15 | # Execute scripts from /etc/entrypoint.d/ in numeric order 16 | find /etc/entrypoint.d/ -type f -name '*.sh' | sort -n -t- -k1 | while IFS= read -r f; do 17 | [ -e "$f" ] || continue # skip if not exists 18 | case "$f" in 19 | *.sh) . "$f" ;; 20 | *) echo "$0: Invalid extension. Ignoring $f" ;; 21 | esac 22 | done 23 | 24 | # first arg is `-f` or `--some-option` 25 | if [ "${1#-}" != "$1" ]; then 26 | set -- php "$@" 27 | fi 28 | 29 | # Some scripts may need to change the CMD based on the log level. If this file is set, execute the contents of that file instead of the Dockerfile CMD. 30 | if [ -f /tmp/docker_cmd_override ]; then 31 | docker_cmd_override=$(cat /tmp/docker_cmd_override) 32 | rm /tmp/docker_cmd_override 33 | set -- $docker_cmd_override # Perform word splitting by not quoting the commands 34 | exec "$@" 35 | else 36 | # Execute the CMD passed in from the Dockerfile 37 | exec "$@" 38 | fi -------------------------------------------------------------------------------- /docs/components/content/About.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/s6/usr/local/bin/docker-php-serversideup-s6-install: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -oue 3 | 4 | ############################################### 5 | # Usage: docker-php-serversideup-s6-install 6 | ############################################### 7 | # This script is used to install S6 Overlay. It is 8 | # intended to be used during the build process only. 9 | # Be sure to set the S6_SRC_URL, S6_SRC_DEP, and S6_DIR 10 | # environment variables before running this script. 11 | 12 | S6_VERSION=v3.2.0.0 13 | mkdir -p $S6_DIR 14 | export SYS_ARCH=$(uname -m) 15 | case "$SYS_ARCH" in 16 | aarch64 ) export S6_ARCH='aarch64' ;; 17 | arm64 ) export S6_ARCH='aarch64' ;; 18 | armhf ) export S6_ARCH='armhf' ;; 19 | arm* ) export S6_ARCH='arm' ;; 20 | i4* ) export S6_ARCH='i486' ;; 21 | i6* ) export S6_ARCH='i686' ;; 22 | s390* ) export S6_ARCH='s390x' ;; 23 | * ) export S6_ARCH='x86_64' ;; 24 | esac 25 | 26 | untar() { 27 | echo "⏬ Downloading $1" 28 | curl -L $1 -o - | tar Jxp -C $S6_DIR 29 | } 30 | 31 | echo "⬇️ Downloading s6 overlay:${S6_ARCH}-${S6_VERSION} for ${SYS_ARCH}" 32 | untar ${S6_SRC_URL}/${S6_VERSION}/s6-overlay-noarch.tar.xz 33 | untar ${S6_SRC_URL}/${S6_VERSION}/s6-overlay-${S6_ARCH}.tar.xz 34 | 35 | # Ensure "php-fpm-healthcheck" is installed 36 | echo "⬇️ Downloading php-fpm-healthcheck..." 37 | curl -o /usr/local/bin/php-fpm-healthcheck https://raw.githubusercontent.com/renatomefi/php-fpm-healthcheck/v0.5.0/php-fpm-healthcheck 38 | chmod +x /usr/local/bin/php-fpm-healthcheck -------------------------------------------------------------------------------- /docs/components/content/MarketingDevToProd.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/apache2/vhost-templates/http.conf: -------------------------------------------------------------------------------- 1 | # Configure ServerAdmin and ServerName 2 | ServerName localhost 3 | ServerAdmin webmaster@localhost 4 | 5 | # Set CloudFlare Real IP 6 | RemoteIPHeader CF-Connecting-IP 7 | 8 | # Configure main document root 9 | DocumentRoot ${APACHE_DOCUMENT_ROOT} 10 | 11 | # Set basic settings for document root. Configure correct directory indexes and disable directory browsing 12 | 13 | AllowOverride All 14 | Require all granted 15 | Options -Indexes +FollowSymLinks +MultiViews 16 | DirectoryIndex index.php index.html index.htm 17 | 18 | 19 | # Healthchecks: Set /healthcheck to be the healthcheck URL 20 | ProxyPass "/healthcheck" "fcgi://localhost:9000" 21 | ProxyPassReverse "/healthcheck" "fcgi://localhost:9000" 22 | 23 | # For any files that match PHP, pass it to PHP-FPM for processing 24 | 25 | # 2.4.10+ can proxy to unix socket 26 | ProxyFCGIBackendType GENERIC 27 | SetHandler "proxy:fcgi://localhost:9000" 28 | 29 | 30 | # Set the Proxy Timeout to be 30 minutes 31 | ProxyTimeout 1800 32 | 33 | # Set environment variable for healthcheck requests 34 | SetEnvIf Request_URI "^/healthcheck$" dontlog 35 | 36 | # CustomLog directive to conditionally log requests 37 | LogFormat "%l %u %t %v %a \"%r\" %>s %b" comonvhost 38 | CustomLog /dev/stdout comonvhost env=!dontlog 39 | 40 | # Configure Log Settings 41 | ErrorLog /dev/stderr 42 | LogLevel ${LOG_OUTPUT_LEVEL} 43 | 44 | # Disable Server Signature for increased security 45 | ServerSignature Off -------------------------------------------------------------------------------- /docs/public/images/logos/discord-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/content/docs/4.laravel/3.laravel-queue.md: -------------------------------------------------------------------------------- 1 | --- 2 | head.title: 'Laravel Queue with Docker - Docker PHP - Server Side Up' 3 | description: 'Learn how to configure a Laravel Queue with Docker.' 4 | layout: docs 5 | --- 6 | 7 | # Laravel Queue with Docker 8 | All you need to do is pass the Laravel Queue command to the container and S6 will automatically monitor it for you. 9 | 10 | ## Important concepts 11 | 1. It's usually best to run the queue as a separate container (but using the same image) 12 | 1. Notice we're using the same `my/laravel-app` image for both the PHP and Queue services. This is a common practice to keep the image consistent. 13 | 1. You can do cool things with `PHP_FPM_POOL_NAME` to separate the task from the main PHP pool. This is helpful when debugging or monitoring the task. 14 | 1. If you need to run the queue in the same container, you might want to look into [writing your own S6 Overlay script](/docs/guide/using-s6-overlay#customizing-the-initialization-process) to manage and monitor multiple processes in one container. 15 | 16 | ::code-panel 17 | --- 18 | label: Task Command 19 | --- 20 | ```sh 21 | php artisan queue:work --tries=3 22 | ``` 23 | :: 24 | 25 | ::code-panel 26 | --- 27 | label: Example & Simplified Docker Compose File 28 | --- 29 | ```yaml 30 | version: '3' 31 | services: 32 | php: 33 | image: my/laravel-app 34 | environment: 35 | PHP_FPM_POOL_NAME: "my-app_php" 36 | 37 | queue: 38 | image: my/laravel-app 39 | command: ["php", "/var/www/html/artisan", "queue:work", "--tries=3"] 40 | environment: 41 | PHP_FPM_POOL_NAME: "my-app_queue" 42 | ``` 43 | :: -------------------------------------------------------------------------------- /docs/public/images/logos/discord-slate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | name: "\U0001F41B Bug Report" 2 | description: "You found a bug in the code \U0001F914" 3 | labels: ["🧐 Bug: Needs Confirmation"] 4 | assignees: 5 | - jaydrogers 6 | body: 7 | - type: textarea 8 | attributes: 9 | label: Steps To Reproduce 10 | description: Steps to reproduce the behavior. 11 | placeholder: | 12 | 1. In this environment... 13 | 2. With this config... 14 | 3. Run '...' 15 | 4. See error... 16 | validations: 17 | required: true 18 | - type: textarea 19 | id: result 20 | attributes: 21 | label: Outcome 22 | placeholder: Tell us what went wrong 23 | value: | 24 | #### What did you expect? 25 | 26 | #### What happened instead? 27 | validations: 28 | required: true 29 | - type: textarea 30 | attributes: 31 | label: Affected Docker Images 32 | description: "Which images does this issue happen in? (for example: `serversideup/php:8.1-cli`, `serversideup/php:8.1-fpm`, etc). You can also run Run `docker inspect --format='{{json .Config.Labels}}' <>` to get additional information." 33 | validations: 34 | required: true 35 | - type: textarea 36 | attributes: 37 | label: Anything else? 38 | description: | 39 | Links? References? Docker configurations? If there's anything that you can provide to help reproduce your issue faster, please include it. The faster we can reproduce it, the faster we can fix it. 40 | 41 | Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. 42 | validations: 43 | required: false -------------------------------------------------------------------------------- /docs/content/docs/4.laravel/4.laravel-horizon.md: -------------------------------------------------------------------------------- 1 | --- 2 | head.title: 'Laravel Horizon with Docker - Docker PHP - Server Side Up' 3 | description: 'Learn how to configure Laravel Horizon with Docker.' 4 | layout: docs 5 | --- 6 | 7 | # Laravel Horizon with Docker 8 | We simply pass the command to the Docker container and let S6 Overlay monitor the process. 9 | 10 | ## Important concepts 11 | 1. In most cases, you probably want to run this as a separate container from your web container 12 | 1. Ensure that you have your `.env` configured correctly to authenticate with Redis 13 | 1. Ensure Redis is running before you attempt to connect Horizon to Redis 14 | 1. You can do cool things with `PHP_FPM_POOL_NAME` to separate the task from the main PHP pool. This is helpful when debugging or monitoring the task. 15 | 1. If you need to run horizon in the same container, you might want to look into [writing your own S6 Overlay script](/docs/guide/using-s6-overlay#customizing-the-initialization-process) to manage and monitor multiple processes in one container. 16 | 17 | ::code-panel 18 | --- 19 | label: Task Command 20 | --- 21 | ```sh 22 | php artisan horizon 23 | ``` 24 | :: 25 | 26 | ::code-panel 27 | --- 28 | label: Example Docker Compose File 29 | --- 30 | ```yaml 31 | version: '3' 32 | services: 33 | php: 34 | image: my/laravel-app 35 | environment: 36 | PHP_FPM_POOL_NAME: "my-app_php" 37 | 38 | redis: 39 | image: redis:6 40 | command: "redis-server --appendonly yes --requirepass redispassword" 41 | 42 | horizon: 43 | image: my/laravel-app 44 | command: ["php", "/var/www/html/artisan", "horizon"] 45 | environment: 46 | PHP_FPM_POOL_NAME: "my-app_horizon" 47 | ``` 48 | :: -------------------------------------------------------------------------------- /docs/components/content/Resources/Pattern.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | -------------------------------------------------------------------------------- /scripts/conf/php-versions-base-config.yml: -------------------------------------------------------------------------------- 1 | php_versions: 2 | - major: "7" 3 | minor_versions: 4 | - minor: "7.4" 5 | base_os: 6 | - name: alpine 7 | - name: bullseye 8 | default: true 9 | patch_versions: 10 | - 7.4.33 11 | - major: "8" 12 | minor_versions: 13 | - minor: "8.0" 14 | base_os: 15 | - name: alpine 16 | - name: bullseye 17 | default: true 18 | patch_versions: 19 | - 8.0.30 20 | - minor: "8.1" 21 | base_os: 22 | - name: alpine 23 | - name: bookworm 24 | default: true 25 | patch_versions: 26 | # - 8.1.28 # Pull latest from Official PHP source 27 | - minor: "8.2" 28 | base_os: 29 | - name: alpine 30 | - name: bookworm 31 | default: true 32 | patch_versions: 33 | # - 8.2.18 # Pull latest from Official PHP source 34 | - minor: "8.3" 35 | base_os: 36 | - name: alpine 37 | - name: bookworm 38 | default: true 39 | patch_versions: 40 | # - 8.3.6 # Pull latest from Official PHP source 41 | php_variations: 42 | - name: cli 43 | default: true 44 | - name: fpm 45 | - name: fpm-apache 46 | supported_os: # Open a discussion on serversideup/php if you want to see Alpine support for fpm-apache (https://github.com/serversideup/docker-php/discussions/66) 47 | - bullseye 48 | - bookworm 49 | - name: fpm-nginx 50 | - name: unit 51 | supported_os: # Alpine with Unit is not supported yet. Submit a PR if you can help (https://github.com/serversideup/docker-php/issues/233) 52 | - bullseye 53 | - bookworm -------------------------------------------------------------------------------- /docs/public/images/logos/amplitude.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | AmplitudeJS 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/variations/fpm-nginx/etc/nginx/site-opts.d/https.conf.template: -------------------------------------------------------------------------------- 1 | listen 8443 ssl default_server; 2 | listen [::]:8443 ssl default_server; 3 | http2 on; 4 | 5 | root $NGINX_WEBROOT; 6 | 7 | ssl_certificate $SSL_CERTIFICATE_FILE; 8 | ssl_certificate_key $SSL_PRIVATE_KEY_FILE; 9 | ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305; 10 | ssl_protocols TLSv1.2 TLSv1.3; 11 | 12 | # Set allowed "index" files 13 | index index.html index.htm index.php; 14 | 15 | server_name _; 16 | 17 | charset utf-8; 18 | 19 | # Set max upload to 2048M 20 | client_max_body_size 2048M; 21 | 22 | # Healthchecks: Set /healthcheck to be the healthcheck URL 23 | location /healthcheck { 24 | access_log off; 25 | 26 | # set max 5 seconds for healthcheck 27 | fastcgi_read_timeout 5s; 28 | 29 | include fastcgi_params; 30 | fastcgi_param SCRIPT_NAME /healthcheck; 31 | fastcgi_param SCRIPT_FILENAME /healthcheck; 32 | fastcgi_pass 127.0.0.1:9000; 33 | } 34 | 35 | # Have NGINX try searching for PHP files as well 36 | location / { 37 | try_files $uri $uri/ /index.php?$query_string; 38 | } 39 | 40 | # Pass "*.php" files to PHP-FPM 41 | location ~ \.php$ { 42 | fastcgi_pass 127.0.0.1:9000; 43 | fastcgi_index index.php; 44 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 45 | include fastcgi_params; 46 | fastcgi_buffers $NGINX_FASTCGI_BUFFERS; 47 | fastcgi_buffer_size $NGINX_FASTCGI_BUFFER_SIZE; 48 | } 49 | 50 | # additional config 51 | include /etc/nginx/server-opts.d/*.conf; -------------------------------------------------------------------------------- /.github/workflows/scheduled-task_update-sponsors.yml: -------------------------------------------------------------------------------- 1 | name: Generate Sponsors README 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: 30 15 * * 0-6 6 | jobs: 7 | deploy: 8 | runs-on: ubuntu-22.04 9 | steps: 10 | - name: Checkout 🛎️ 11 | uses: actions/checkout@v4 12 | 13 | - name: Generate Sponsors 💖 14 | uses: JamesIves/github-sponsors-readme-action@v1 15 | with: 16 | organization: true 17 | minimum: 4900 18 | maximum: 5100 19 | fallback: 'No bronze sponsors yet. Become a sponsor →' 20 | token: ${{ secrets.SPONSORS_README_ACTION_PERSONAL_ACCESS_TOKEN }} 21 | marker: 'bronze' 22 | template: '{{{ login }}}  ' 23 | file: 'README.md' 24 | 25 | - name: Generate Sponsors 💖 26 | uses: JamesIves/github-sponsors-readme-action@v1 27 | with: 28 | organization: true 29 | maximum: 500 30 | fallback: '

Sponsors

' 31 | token: ${{ secrets.SPONSORS_README_ACTION_PERSONAL_ACCESS_TOKEN }} 32 | marker: 'supporters' 33 | template: '{{{ login }}}  ' 34 | file: 'README.md' 35 | 36 | - name: Deploy to GitHub Pages 🚀 37 | uses: JamesIves/github-pages-deploy-action@v4 38 | with: 39 | branch: main 40 | folder: '.' -------------------------------------------------------------------------------- /docs/components/content/Code/CopyButton.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | -------------------------------------------------------------------------------- /docs/components/content/AppButton.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/apache2/vhost-templates/https.conf: -------------------------------------------------------------------------------- 1 | # Configure ServerAdmin and ServerName 2 | ServerName localhost 3 | ServerAdmin webmaster@localhost 4 | 5 | # Enable HTTP2 6 | Protocols h2 http/1.1 7 | 8 | SSLProtocol -all +TLSv1.2 +TLSv1.3 9 | 10 | # Set CloudFlare Real IP 11 | RemoteIPHeader CF-Connecting-IP 12 | 13 | # Configure main document root 14 | DocumentRoot ${APACHE_DOCUMENT_ROOT} 15 | 16 | # Set basic settings for document root. Configure correct directory indexes and disable directory browsing 17 | 18 | AllowOverride All 19 | Require all granted 20 | Options -Indexes +FollowSymLinks +MultiViews 21 | DirectoryIndex index.php index.html index.htm 22 | 23 | 24 | # Healthchecks: Set /healthcheck to be the healthcheck URL 25 | ProxyPass "/healthcheck" "fcgi://localhost:9000" 26 | ProxyPassReverse "/healthcheck" "fcgi://localhost:9000" 27 | 28 | # For any files that match PHP, pass it to PHP-FPM for processing 29 | 30 | # 2.4.10+ can proxy to unix socket 31 | ProxyFCGIBackendType GENERIC 32 | SetHandler "proxy:fcgi://localhost:9000" 33 | 34 | 35 | # Set the Proxy Timeout to be 30 minutes 36 | ProxyTimeout 1800 37 | 38 | # Set environment variable for healthcheck requests 39 | SetEnvIf Request_URI "^/healthcheck$" dontlog 40 | 41 | # CustomLog directive to conditionally log requests 42 | LogFormat "%l %u %t %v %a \"%r\" %>s %b" comonvhost 43 | CustomLog /dev/stdout comonvhost env=!dontlog 44 | 45 | # Configure Log Settings 46 | ErrorLog /dev/stderr 47 | LogLevel ${LOG_OUTPUT_LEVEL} 48 | 49 | # Disable Server Signature for increased security 50 | ServerSignature Off 51 | 52 | # SSL Settings 53 | SSLEngine on 54 | SSLCertificateFile ${SSL_CERTIFICATE_FILE} 55 | SSLCertificateKeyFile ${SSL_PRIVATE_KEY_FILE} 56 | -------------------------------------------------------------------------------- /docs/public/images/logos/go.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/common/etc/entrypoint.d/0-container-info.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ "$SHOW_WELCOME_MESSAGE" = "false" ] || [ "$LOG_OUTPUT_LEVEL" = "off" ] || [ "$DISABLE_DEFAULT_CONFIG" = "true" ]; then 3 | if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then 4 | echo "👉 $0: DISABLE_DEFAULT_CONFIG does not equal \"false\", so debug mode will NOT be automatically set." 5 | fi 6 | # Skip the rest of the script 7 | exit 0 8 | fi 9 | 10 | echo ' 11 | -------------------------------------------------------------------- 12 | ____ ____ _ _ _ _ 13 | / ___| ___ _ ____ _____ _ __ / ___|(_) __| | ___ | | | |_ __ 14 | \___ \ / _ \ __\ \ / / _ \ __| \___ \| |/ _` |/ _ \ | | | | _ \ 15 | ___) | __/ | \ V / __/ | ___) | | (_| | __/ | |_| | |_) | 16 | |____/ \___|_| \_/ \___|_| |____/|_|\__,_|\___| \___/| .__/ 17 | |_| 18 | 19 | Brought to you by serversideup.net 20 | --------------------------------------------------------------------' 21 | 22 | PHP_OPCACHE_STATUS=$(php -r 'echo ini_get("opcache.enable");') 23 | 24 | if [ "$PHP_OPCACHE_STATUS" = "1" ]; then 25 | PHP_OPCACHE_MESSAGE="✅ Enabled" 26 | else 27 | PHP_OPCACHE_MESSAGE="❌ Disabled" 28 | fi 29 | 30 | echo ' 31 | 🙌 To support Server Side Up projects visit: 32 | https://serversideup.net/sponsor 33 | 34 | ------------------------------------- 35 | ℹ️ Container Information 36 | -------------------------------------' 37 | echo " 38 | OS: $(. /etc/os-release; echo "${PRETTY_NAME}") 39 | Docker user: $(whoami) 40 | Docker uid: $(id -u) 41 | Docker gid: $(id -g) 42 | OPcache: $PHP_OPCACHE_MESSAGE 43 | " 44 | 45 | if [ "$PHP_OPCACHE_STATUS" = "0" ]; then 46 | echo "👉 [NOTICE]: Improve PHP performance by setting PHP_OPCACHE_ENABLE=1 (recommended for production)." 47 | fi -------------------------------------------------------------------------------- /docs/components/content/AppLink.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | -------------------------------------------------------------------------------- /docs/public/images/icons/cloudflare-square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/content/docs/2.getting-started/4.choosing-a-host.md: -------------------------------------------------------------------------------- 1 | --- 2 | head.title: 'Upgrade Guide - Docker PHP - Server Side Up' 3 | description: 'Learn where you can run your servers and still have control of your data.' 4 | layout: docs 5 | --- 6 | 7 | # Choosing a host 8 | We get asked where we host our infrastructure. Our biggest principle is: **your infrastructure should be able to run anywhere.** 9 | 10 | We believe privacy and control is the #1 priority when it comes to hosting infrastructure. We try to avoid the "big clouds" as much as possible because we're not comfortable that all 3 major players practice data mining of users and their products usually contain some sort of "vendor-lock". 11 | 12 | We run all our production servers on the latest LTS release of Ubuntu Server. The hosts we use are below. Some may be affiliate links that kick a few bucks at no extra cost to you, but they do not affect our recommendations at all. 13 | 14 | ### [Hetzner](https://hetzner.cloud/?ref=lhLUIrkdUPhl) 15 | **Our current favorite.** Your mind will be blown for the specs you get for the prices. They are based in Europe, but have US datacenters too. We're running full out SaaS products for $5 USD a month. 🤯 16 | 17 | ### [Vultr](https://vultr.grsm.io/create) 18 | Excellent performance and value. Lots of data center options too. 19 | 20 | ### [Digital Ocean](https://m.do.co/c/f3bad4b927ca) 21 | Lots of developer love here. Not the best performing servers, but they do have a lot of awesome products! 22 | 23 | ## Benchmarks 24 | If you're shopping for a host, [check out the benchmarks we've ran →](https://521dimensions.notion.site/Benchmark-Results-for-Self-hosted-Gitlab-Server-c6eca7c5f16d4bb8aeb989174fc58ffe) 25 | 26 | ## Can I run this on another host? 27 | Sure! It all depends what platform you want to use, but if it supports Docker images, you likely can run it. These images are designed to give you freedom no matter where you want to run them. -------------------------------------------------------------------------------- /docs/assets/css/hamburger.css: -------------------------------------------------------------------------------- 1 | #nav-icon span { 2 | display: block; 3 | position: absolute; 4 | height: 2px; 5 | width: 50%; 6 | background: #FFF; 7 | opacity: 1; 8 | -webkit-transform: rotate(0deg); 9 | -moz-transform: rotate(0deg); 10 | -o-transform: rotate(0deg); 11 | transform: rotate(0deg); 12 | -webkit-transition: .25s ease-in-out; 13 | -moz-transition: .25s ease-in-out; 14 | -o-transition: .25s ease-in-out; 15 | transition: .25s ease-in-out; 16 | } 17 | 18 | #nav-icon span:nth-child(even) { 19 | left: 50%; 20 | border-radius: 0 9px 9px 0; 21 | } 22 | 23 | #nav-icon span:nth-child(odd) { 24 | left:0px; 25 | border-radius: 9px 0 0 9px; 26 | } 27 | 28 | #nav-icon span:nth-child(1), #nav-icon span:nth-child(2) { 29 | top: 0px; 30 | } 31 | 32 | #nav-icon span:nth-child(3), #nav-icon span:nth-child(4) { 33 | top: 6px; 34 | } 35 | 36 | #nav-icon span:nth-child(5), #nav-icon span:nth-child(6) { 37 | top: 12px; 38 | } 39 | 40 | #nav-icon.open span:nth-child(1),#nav-icon.open span:nth-child(6) { 41 | -webkit-transform: rotate(45deg); 42 | -moz-transform: rotate(45deg); 43 | -o-transform: rotate(45deg); 44 | transform: rotate(45deg); 45 | } 46 | 47 | #nav-icon.open span:nth-child(2),#nav-icon.open span:nth-child(5) { 48 | -webkit-transform: rotate(-45deg); 49 | -moz-transform: rotate(-45deg); 50 | -o-transform: rotate(-45deg); 51 | transform: rotate(-45deg); 52 | } 53 | 54 | #nav-icon.open span:nth-child(1) { 55 | left: 3px; 56 | top: 3px; 57 | } 58 | 59 | #nav-icon.open span:nth-child(2) { 60 | left: calc(50%); 61 | top: 3px; 62 | } 63 | 64 | #nav-icon.open span:nth-child(3) { 65 | left: -50%; 66 | opacity: 0; 67 | } 68 | 69 | #nav-icon.open span:nth-child(4) { 70 | left: 100%; 71 | opacity: 0; 72 | } 73 | 74 | #nav-icon.open span:nth-child(5) { 75 | left: 3px; 76 | top: 10px; 77 | } 78 | 79 | #nav-icon.open span:nth-child(6) { 80 | left: calc(50%); 81 | top: 10px; 82 | } -------------------------------------------------------------------------------- /src/s6/usr/local/bin/docker-php-serversideup-s6-init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | ############################################### 5 | # Usage: docker-php-serversideup-s6-init 6 | ############################################### 7 | # This script is used to take scripts from "/etc/entrypoint.d" and move them 8 | # to the S6 Overlay structure. 9 | 10 | S6_HOME="/etc/s6-overlay" 11 | 12 | for file in /etc/entrypoint.d/*.sh; do 13 | [ -e "$file" ] || continue # Skip if no files match 14 | 15 | # Get the base name of the file 16 | base=$(basename "$file" .sh) 17 | 18 | # Proceed only if the script does not exist 19 | if [ ! -e "${S6_HOME}/scripts/${base}" ]; then 20 | # Create the service directory for that file 21 | mkdir -p "${S6_HOME}/s6-rc.d/${base}" 22 | 23 | # Set service type to "oneshot" 24 | echo "oneshot" > "${S6_HOME}/s6-rc.d/${base}/type" 25 | 26 | # Set the "up" script 27 | echo "${S6_HOME}/scripts/${base}" > "${S6_HOME}/s6-rc.d/${base}/up" 28 | 29 | # Place empty file in contents.d 30 | touch "${S6_HOME}/s6-rc.d/user/contents.d/${base}" 31 | 32 | # Ensure the ${S6_HOME}/scripts/ directory exists 33 | mkdir -p "${S6_HOME}/scripts" 34 | 35 | # Link the script in the script directory 36 | ln -s "${file}" "${S6_HOME}/scripts/${base}" 37 | 38 | # Ensure the script has the correct file header for S6 39 | sed -i '1s%^#!/bin/sh$%#!/command/with-contenv sh%' "${file}" 40 | 41 | # Find the script that should be the dependency based on alphabetical order 42 | previous_base=$(find "${S6_HOME}/s6-rc.d/" -maxdepth 1 -type d -name '[0-9]*' | \ 43 | sort | \ 44 | grep -B1 "${base}" | \ 45 | head -n 1 | \ 46 | xargs basename) 47 | 48 | # Check if the previous script is not the current script and set as dependency 49 | if [ "$previous_base" != "$base" ] && [ -n "$previous_base" ]; then 50 | echo "$previous_base" >> "${S6_HOME}/s6-rc.d/${base}/dependencies" 51 | fi 52 | 53 | # Set the previous file for the next loop 54 | previous_base="$base" 55 | fi 56 | 57 | done -------------------------------------------------------------------------------- /docs/components/content/Resources.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 67 | 68 | -------------------------------------------------------------------------------- /docs/components/Docs/Logo.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/public/images/icons/php-square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/assets/css/animations.css: -------------------------------------------------------------------------------- 1 | .slide-in-right-enter-active { 2 | -webkit-animation: slide-in-right 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both; 3 | animation: slide-in-right 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both; 4 | } 5 | 6 | .slide-in-right-leave-active { 7 | -webkit-animation: slide-in-right 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both reverse; 8 | animation: slide-in-right 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both reverse; 9 | } 10 | 11 | @-webkit-keyframes slide-in-right { 12 | 0% { 13 | -webkit-transform: translateX(1000px); 14 | transform: translateX(1000px); 15 | opacity: 0; 16 | } 17 | 100% { 18 | -webkit-transform: translateX(0); 19 | transform: translateX(0); 20 | opacity: 1; 21 | } 22 | } 23 | @keyframes slide-in-right { 24 | 0% { 25 | -webkit-transform: translateX(1000px); 26 | transform: translateX(1000px); 27 | opacity: 0; 28 | } 29 | 100% { 30 | -webkit-transform: translateX(0); 31 | transform: translateX(0); 32 | opacity: 1; 33 | } 34 | } 35 | 36 | .slide-in-top-enter-active { 37 | -webkit-animation: slide-in-top 0.25s cubic-bezier(0.250, 0.460, 0.450, 0.940) both; 38 | animation: slide-in-top 0.25s cubic-bezier(0.250, 0.460, 0.450, 0.940) both; 39 | } 40 | 41 | .slide-in-top-leave-active { 42 | -webkit-animation: slide-in-top 0.25s cubic-bezier(0.250, 0.460, 0.450, 0.940) both reverse; 43 | animation: slide-in-top 0.25s cubic-bezier(0.250, 0.460, 0.450, 0.940) both reverse; 44 | } 45 | 46 | @-webkit-keyframes slide-in-top { 47 | 0% { 48 | -webkit-transform: translateY(-1000px); 49 | transform: translateY(-1000px); 50 | opacity: 0; 51 | } 52 | 100% { 53 | -webkit-transform: translateY(0); 54 | transform: translateY(0); 55 | opacity: 1; 56 | } 57 | } 58 | @keyframes slide-in-top { 59 | 0% { 60 | -webkit-transform: translateY(-1000px); 61 | transform: translateY(-1000px); 62 | opacity: 0; 63 | } 64 | 100% { 65 | -webkit-transform: translateY(0); 66 | transform: translateY(0); 67 | opacity: 1; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /docs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | const defaultTheme = require('tailwindcss/defaultTheme') 2 | 3 | /** @type {import('tailwindcss').Config} */ 4 | module.exports = { 5 | darkMode: "class", 6 | theme: { 7 | fontSize: { 8 | '2xs': ['0.75rem', { lineHeight: '1.25rem' }], 9 | xs: ['0.8125rem', { lineHeight: '1.5rem' }], 10 | sm: ['0.875rem', { lineHeight: '1.5rem' }], 11 | base: ['1rem', { lineHeight: '1.75rem' }], 12 | lg: ['1.125rem', { lineHeight: '1.75rem' }], 13 | xl: ['1.25rem', { lineHeight: '1.75rem' }], 14 | '2xl': ['1.5rem', { lineHeight: '2rem' }], 15 | '3xl': ['1.875rem', { lineHeight: '2.25rem' }], 16 | '4xl': ['2.25rem', { lineHeight: '2.5rem' }], 17 | '5xl': ['3rem', { lineHeight: '1' }], 18 | '6xl': ['3.75rem', { lineHeight: '1' }], 19 | '7xl': ['4.5rem', { lineHeight: '1' }], 20 | '8xl': ['6rem', { lineHeight: '1' }], 21 | '9xl': ['8rem', { lineHeight: '1' }], 22 | }, 23 | typography: require('./typography'), 24 | extend: { 25 | boxShadow: { 26 | glow: '0 0 4px rgb(0 0 0 / 0.1)', 27 | }, 28 | colors: { 29 | link: '#3B82F6' 30 | }, 31 | fontFamily: { 32 | 'inter': ['Inter', 'sans-serif'] 33 | }, 34 | maxWidth: { 35 | lg: '33rem', 36 | '2xl': '40rem', 37 | '3xl': '50rem', 38 | '5xl': '66rem', 39 | }, 40 | opacity: { 41 | 1: '0.01', 42 | 2.5: '0.025', 43 | 7.5: '0.075', 44 | 15: '0.15', 45 | } 46 | } 47 | }, 48 | plugins: [], 49 | content: [ 50 | `/components/**/*.{vue,js,ts}`, 51 | `/layouts/**/*.vue`, 52 | `/pages/**/*.vue`, 53 | `/composables/**/*.{js,ts}`, 54 | `/plugins/**/*.{js,ts}`, 55 | `/App.{js,ts,vue}`, 56 | `/app.{js,ts,vue}`, 57 | `/Error.{js,ts,vue}`, 58 | `/error.{js,ts,vue}` 59 | ], 60 | } -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/apache2/conf-available/serversideup.conf: -------------------------------------------------------------------------------- 1 | # 2 | # ServerName gives the name and port that the server uses to identify itself. 3 | # This can often be determined automatically, but we recommend you specify 4 | # it explicitly to prevent problems during startup. 5 | # 6 | # If your host doesn't have a registered DNS name, enter its IP address here. 7 | ServerName localhost 8 | 9 | # 10 | # ErrorLog: The location of the error log file. 11 | # If you do not specify an ErrorLog directive within a 12 | # container, error messages relating to that virtual host will be 13 | # logged here. If you *do* define an error logfile for a 14 | # container, that host's errors will be logged there and not here. 15 | # 16 | ErrorLog /dev/stderr 17 | 18 | # 19 | # LogLevel: Control the number of messages logged to the error_log. 20 | # Possible values include: debug, info, notice, warn, error, crit, 21 | # alert, emerg. 22 | # 23 | LogLevel ${LOG_OUTPUT_LEVEL} 24 | 25 | 26 | # 27 | # The following directives define some format nicknames for use with 28 | # a CustomLog directive (see below). 29 | # 30 | LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined 31 | LogFormat "%a %l %u %t \"%r\" %>s %b" common 32 | 33 | 34 | # You need to enable mod_logio.c to use %I and %O 35 | LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio 36 | 37 | 38 | # 39 | # The location and format of the access logfile (Common Logfile Format). 40 | # If you do not define any access logfiles within a 41 | # container, they will be logged here. Contrariwise, if you *do* 42 | # define per- access logfiles, transactions will be 43 | # logged therein and *not* in this file. 44 | # 45 | #CustomLog logs/access.log common 46 | 47 | # 48 | # If you prefer a logfile with access, agent, and referer information 49 | # (Combined Logfile Format) you can use the following directive. 50 | # 51 | CustomLog "|/bin/cat" combined 52 | -------------------------------------------------------------------------------- /docs/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import tailwindTypography from '@tailwindcss/typography' 2 | 3 | // https://nuxt.com/docs/api/configuration/nuxt-config 4 | export default defineNuxtConfig({ 5 | modules: [ 6 | 'nuxt-og-image', 7 | '@nuxtjs/color-mode', 8 | '@nuxt/content', 9 | '@nuxtjs/plausible', 10 | '@nuxtjs/tailwindcss', 11 | '@vueuse/nuxt' 12 | ], 13 | 14 | content: { 15 | documentDriven: true, 16 | 17 | experimental: { 18 | search: { 19 | indexed: true 20 | } 21 | }, 22 | 23 | markdown: { 24 | tags: { 25 | h2: 'AppHeading2', 26 | h3: 'AppHeading3', 27 | h4: 'AppHeading4' 28 | } 29 | }, 30 | 31 | highlight: { 32 | theme: { 33 | // Default theme (same as single string) 34 | default: 'github-dark', 35 | // Theme used if `html.dark` 36 | dark: 'github-dark', 37 | // Theme used if `html.sepia` 38 | sepia: 'monokai' 39 | }, 40 | 41 | preload: [ 42 | 'dockerfile', 43 | 'ini', 44 | 'php' 45 | ] 46 | }, 47 | }, 48 | 49 | colorMode: { 50 | classSuffix: '' 51 | }, 52 | 53 | nitro: { 54 | prerender: { 55 | routes: [ 56 | '/sitemap.xml', 57 | '/api/search.json' 58 | ] 59 | } 60 | }, 61 | 62 | ogImage: { 63 | componentDirs: ['~/components/Global/OgImage'], 64 | }, 65 | 66 | plausible: { 67 | apiHost: 'https://a.521dimensions.com' 68 | }, 69 | 70 | runtimeConfig: { 71 | public: { 72 | basePath: process.env.NUXT_APP_BASE_URL || '/', 73 | domain: process.env.TOP_LEVEL_DOMAIN 74 | } 75 | }, 76 | 77 | site: { 78 | url: process.env.BASE_PATH, 79 | }, 80 | 81 | tailwindcss: { 82 | config: { 83 | plugins: [tailwindTypography] 84 | }, 85 | cssPath: '~/assets/css/tailwind.css', 86 | } 87 | }) 88 | -------------------------------------------------------------------------------- /docs/public/images/icons/nginx-square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/variations/unit/etc/unit/config.d/ssl-off.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "listeners": { 3 | "*:8080": { 4 | "pass": "routes", 5 | "forwarded": { 6 | "client_ip": "CF-Connecting-IP", 7 | "recursive": false, 8 | "source": [ 9 | "173.245.48.0/20", 10 | "103.21.244.0/22", 11 | "103.22.200.0/22", 12 | "103.31.4.0/22", 13 | "141.101.64.0/18", 14 | "108.162.192.0/18", 15 | "190.93.240.0/20", 16 | "188.114.96.0/20", 17 | "197.234.240.0/22", 18 | "198.41.128.0/17", 19 | "162.158.0.0/15", 20 | "104.16.0.0/13", 21 | "104.24.0.0/14", 22 | "172.64.0.0/13", 23 | "131.0.72.0/22", 24 | "2400:cb00::/32", 25 | "2606:4700::/32", 26 | "2803:f800::/32", 27 | "2405:b500::/32", 28 | "2405:8100::/32", 29 | "2a06:98c0::/29", 30 | "2c0f:f248::/32" 31 | ] 32 | } 33 | } 34 | }, 35 | "routes": [ 36 | { 37 | "match": { 38 | "uri": "/healthcheck" 39 | }, 40 | "action": { 41 | "return": 200 42 | } 43 | }, 44 | { 45 | "match": { 46 | "uri": "!/index.php" 47 | }, 48 | "action": { 49 | "share": "${UNIT_WEBROOT}$uri", 50 | "fallback": { 51 | "pass": "applications/php" 52 | } 53 | } 54 | } 55 | ], 56 | 57 | "applications": { 58 | "php": { 59 | "type": "php", 60 | "root": "${UNIT_WEBROOT}/", 61 | "script": "index.php", 62 | "processes": { 63 | "max": ${UNIT_PROCESSES_MAX}, 64 | "spare": ${UNIT_PROCESSES_SPARE}, 65 | "idle_timeout": ${UNIT_PROCESSES_IDLE_TIMEOUT} 66 | } 67 | } 68 | }, 69 | "access_log": { 70 | "if": "`${uri == '/healthcheck' ? false : true}`", 71 | "path": "/dev/stdout" 72 | } 73 | } -------------------------------------------------------------------------------- /docs/components/Docs/Navigation.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 | -------------------------------------------------------------------------------- /docs/content/docs/3.guide/1.migrating-from-official-php-images.md: -------------------------------------------------------------------------------- 1 | --- 2 | head.title: 'Migrating from official PHP Docker images - Docker PHP - Server Side Up' 3 | description: 'Learn how easy it is to move from the official PHP docker images to serversideup/php.' 4 | layout: docs 5 | --- 6 | # Migrating from the official PHP images 7 | ::lead-p 8 | `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. 🚀 9 | :: 10 | 11 | ## Changing the base image 12 | 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. 13 | 14 | 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! 15 | 16 | ## Before making the change 17 | 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. 18 | 19 | The best place to get this information is with the following pages: 20 | - [Default Configurations](/docs/getting-started/default-configurations) 21 | - [Environment Variable Specifications](/docs/reference/environment-variable-specification) 22 | 23 | ## Older versions of PHP 24 | 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. 25 | 26 | 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. 27 | 28 | To learn more how we tag our images, see our [installation guide](/docs/getting-started/installation). -------------------------------------------------------------------------------- /src/common/usr/local/bin/docker-php-serversideup-set-id: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | ################################################### 5 | # Usage: docker-php-serversideup-set-id [username] [uid]:[gid] 6 | ################################################### 7 | # This script is intended to be called on build for sysadmins who want to 8 | # change the UID and GID of a specific user in a format [uid]:[gid]. This is useful for when you 9 | # want to match the UID and GID of the host machine to the container. 10 | # Specifically, this can be helpful to call during a build target in development 11 | # so developers don't need to worry about permissions issues. 12 | script_name="docker-php-serversideup-set-id" 13 | 14 | # Sanity checks 15 | if [ "$#" -ne 2 ]; then 16 | echo "Usage: $script_name [username] [uid]:[gid]" 17 | exit 1 18 | fi 19 | 20 | username="$1" 21 | uid_gid="$2" 22 | 23 | # Split UID and GID 24 | uid=$(echo "$uid_gid" | cut -d':' -f1) 25 | gid=$(echo "$uid_gid" | cut -d':' -f2) 26 | 27 | # Verify that uid and gid are numeric 28 | if ! echo "$uid" | grep -qE '^[0-9]+$' || ! echo "$gid" | grep -qE '^[0-9]+$'; then 29 | echo "$script_name: UID and GID must be numeric." 30 | exit 1 31 | fi 32 | 33 | # Check if the user exists 34 | if ! id "$username" > /dev/null 2>&1; then 35 | echo "$script_name: User \"$username\" does not exist." 36 | exit 1 37 | fi 38 | 39 | current_uid=$(id -u "$username" 2>/dev/null) 40 | current_gid=$(id -g "$username" 2>/dev/null) 41 | 42 | # Exit if the UID and GID are already set 43 | if [ "$current_uid" -eq "$uid" ] && [ "$current_gid" -eq "$gid" ]; then 44 | echo "$script_name: User $username already has UID $uid and GID $gid." 45 | exit 0 46 | fi 47 | 48 | # Check if another group has the GID already 49 | if getent group "$gid" > /dev/null; then 50 | moved_group_id="99$gid" 51 | existing_group_name=$(getent group "$gid" | cut -d: -f1) 52 | echo "$script_name: ⚡️ Moving GID of $existing_group_name to $moved_group_id" 53 | groupmod -g "$moved_group_id" "$existing_group_name" 54 | fi 55 | 56 | # Check if another user has the UID already 57 | if getent passwd "$uid" > /dev/null; then 58 | moved_user_id="99$uid" 59 | echo "$script_name: ⚡️ Moving UID of $username to $moved_user_id" 60 | usermod -u "$moved_user_id" "$username" 61 | fi 62 | 63 | # Change the UID and GID 64 | groupmod -g "$gid" "$username" 65 | usermod -u "$uid" "$username" 66 | 67 | echo "$script_name: ✅ Set $username UID to $uid and GID to $gid." -------------------------------------------------------------------------------- /docs/components/content/Libraries.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | -------------------------------------------------------------------------------- /docs/content/docs/2.getting-started/3.upgrade-guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | head.title: 'Upgrade Guide - Docker PHP - Server Side Up' 3 | description: 'Learn how the serversideup/php Docker images are built and how to upgrade.' 4 | layout: docs 5 | --- 6 | 7 | # Upgrading 8 | If you do not select a specific patch version, then you will receive automatic PHP updates. 9 | 10 | For example, you can select your version based on the different version numbers: 11 | - Major Version (example: `8` will give you the latest 8.x version) 12 | - Minor Version (example: `8.3` will give you the latest 8.3.x version) 13 | - Patch Version (example: `8.3.2` will always stay at the 8.3.2 version) 14 | 15 | 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`). 16 | 17 | ## Release process 18 | All source code is merged into the `main` branch, which automatically build our "beta" images. 19 | 20 | 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. 21 | 22 | ## Updating the Docker images on your own 23 | 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. 24 | 25 | 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. 26 | 27 | ::code-panel 28 | --- 29 | label: Example Dockerfile with manual updates for Debian 30 | --- 31 | ```dockerfile 32 | FROM serversideup/php:8.3.2-fpm-nginx 33 | 34 | RUN apt-get update \ 35 | && apt-get upgrade -y \ 36 | && apt-get clean \ 37 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/* 38 | ``` 39 | :: 40 | 41 | If you're running an Alpine-based image, you can use the following commands: 42 | 43 | ::code-panel 44 | --- 45 | label: Example Dockerfile with manual updates for Alpine 46 | --- 47 | ```dockerfile 48 | FROM serversideup/php:8.3.2-fpm-nginx-alpine 49 | 50 | RUN apk update \ 51 | && apk upgrade \ 52 | && rm -rf /var/cache/apk/* 53 | ``` 54 | :: 55 | 56 | ## Subscribe to repository updates 57 | 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). 58 | 59 | ![Watch Repository](/images/docs/watch-repo.png) -------------------------------------------------------------------------------- /docs/content/docs/4.laravel/1.laravel-automations.md: -------------------------------------------------------------------------------- 1 | --- 2 | head.title: 'Laravel Automations Script - Docker PHP - Server Side Up' 3 | description: 'Automate your deployments and minimize your efforts with Laravel.' 4 | layout: docs 5 | --- 6 | 7 | # Laravel Automations 8 | `serversideup/php` has a "Laravel Automations" script that helps you automate certain steps during your deployments. By default, the script is **DISABLED**. We only recommend enabling this script in production environments. 9 | 10 | ::note 11 | `AUTORUN_ENABLED` must be set to `true` to enable the script. See our [variable reference document](/docs/reference/environment-variable-specification) for more details. 12 | :: 13 | 14 | ## What the script does 15 | This script executes on container start up and performs the following tasks: 16 | 17 | ### php artisan migrate 18 | Before running migrations, we ensure the database is online and ready to accept connections. By default, we will wait 30 seconds before timing out. 19 | 20 | You can enable the [`--isolated`](https://laravel.com/docs/11.x/migrations#running-migrations) flag by setting `AUTORUN_LARAVEL_MIGRATION_ISOLATION` to `true`, which will ensure no other containers are running a migration. 21 | 22 | **Special Notes for Isolated Migrations:** 23 | - Requires Laravel v9.38.0+ 24 | - Your database must support database locks (meaning SQLite is not supported) 25 | 26 | ### php artisan storage:link 27 | This command creates a symbolic link from `public/storage` to `storage/app/public`. 28 | 29 | ### php artisan config:cache 30 | This command caches all configuration files into a single file, which can then be quickly loaded by Laravel. Once the configuration is cache, the `.env` file will no longer be loaded. 31 | 32 | [Read more about configuration caching →](https://laravel.com/docs/11.x/configuration#configuration-caching) 33 | 34 | ### php artisan route:cache 35 | This command caches the routes, dramatically decrease the time it takes to register all of your application's routes. After running this command, your cached routes file will be loaded on every request. 36 | 37 | [Read more about route caching →](https://laravel.com/docs/11.x/routing#route-caching) 38 | 39 | ### php artisan view:cache 40 | This command caches all of the views in your application, which can greatly decrease the time it takes to render your views. 41 | 42 | [Read more about view caching →](https://laravel.com/docs/11.x/views#optimizing-views) 43 | 44 | ### php artisan event:cache 45 | This command creates a manifest of all your application's events and listeners, which can greatly speed up the process of registering them with Laravel. 46 | 47 | [Read more about event caching →](https://laravel.com/docs/11.x/events#event-discovery-in-production) -------------------------------------------------------------------------------- /src/common/etc/entrypoint.d/1-debug-mode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | script_name="debug-mode" 3 | 4 | if [ "$DISABLE_DEFAULT_CONFIG" = true ]; then 5 | if [ "$LOG_OUTPUT_LEVEL" = "debug" ]; then 6 | echo "👉 $script_name: DISABLE_DEFAULT_CONFIG does not equal \"false\", so debug mode will NOT be automatically set." 7 | fi 8 | exit 0 # Exit if DISABLE_DEFAULT_CONFIG is true 9 | fi 10 | 11 | ####################################### 12 | # Functions 13 | ####################################### 14 | 15 | fpm_is_installed (){ 16 | if [ -d "/usr/local/etc/php-fpm.d" ]; then 17 | return 0 18 | else 19 | return 1 20 | fi 21 | } 22 | 23 | set_php_ini (){ 24 | php_ini_setting=$1 25 | php_ini_value=$2 26 | php_ini_debug_file="$PHP_INI_DIR/conf.d/zzz-serversideup-docker-php-debug.ini" 27 | php_fpm_debug_conf_file="/usr/local/etc/php-fpm.d/zzz-docker-php-serversideup-fpm-debug.conf" 28 | 29 | echo "$php_ini_setting = $php_ini_value" >> "$php_ini_debug_file" 30 | echo "ℹ️ NOTICE ($script_name): INI - $php_ini_setting has been set to \"$php_ini_value\"." 31 | 32 | # Check for PHP-FPM 33 | if fpm_is_installed; then 34 | echo "php_admin_value[$php_ini_setting] = $php_ini_value" >> "$php_fpm_debug_conf_file" 35 | echo "ℹ️ NOTICE ($script_name): FPM - $php_ini_setting has been set to \"$php_ini_value\"" 36 | fi 37 | } 38 | 39 | set_fpm_log_level (){ 40 | if ! fpm_is_installed; then 41 | return 0 42 | fi 43 | 44 | fpm_log_level=$1 45 | sed -i "/\[global\]/a log_level = $fpm_log_level" /usr/local/etc/php-fpm.conf 46 | echo "ℹ️ NOTICE ($script_name): FPM - log_level has been set to \"$fpm_log_level\"" 47 | 48 | echo "access.log = /proc/self/fd/2" >> /usr/local/etc/php-fpm.d/zzz-docker-php-serversideup-fpm-debug.conf 49 | echo "ℹ️ NOTICE ($script_name): FPM - access.log has been set to \"STDERR\"" 50 | } 51 | 52 | ####################################### 53 | # Main (if default config is enabled) 54 | ####################################### 55 | 56 | case "$LOG_OUTPUT_LEVEL" in 57 | debug) 58 | set_php_ini display_errors On 59 | set_php_ini display_startup_errors On 60 | set_php_ini error_reporting "32767" # E_ALL 61 | set_fpm_log_level debug 62 | ;; 63 | info) 64 | set_fpm_log_level notice 65 | ;; 66 | notice) 67 | set_fpm_log_level notice 68 | ;; 69 | warn) 70 | : # Do nothing 71 | ;; 72 | error) 73 | set_fpm_log_level error 74 | ;; 75 | crit) 76 | set_fpm_log_level alert 77 | ;; 78 | alert) 79 | set_fpm_log_level alert 80 | ;; 81 | emerg) 82 | set_fpm_log_level alert 83 | ;; 84 | *) 85 | echo "👉 $script_name: LOG_OUTPUT_LEVEL is not set to a valid value. Please set it to one of the following: debug, info, notice, warn, error, crit, alert, emerg." 86 | exit 1 87 | ;; 88 | esac 89 | -------------------------------------------------------------------------------- /docs/components/Docs/NavigationGroup.vue: -------------------------------------------------------------------------------- 1 | 50 | 51 | 59 | -------------------------------------------------------------------------------- /docs/components/Docs/Header.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | -------------------------------------------------------------------------------- /docs/content/docs/5.customizing-the-image/1.changing-common-php-settings.md: -------------------------------------------------------------------------------- 1 | --- 2 | head.title: 'Changing common PHP settings - Docker PHP - Server Side Up' 3 | description: 'Customizing PHP images is as easy as setting an environment variable. So easy your grandma could do it!' 4 | layout: docs 5 | --- 6 | 7 | # Changing common PHP settings 8 | ::lead-p 9 | 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. 10 | :: 11 | 12 | ## Common Examples 13 | All our environment variables are documented and can be found in our [environment variable specification](/docs/reference/environment-variable-specification) documentation. 14 | 15 | Here are a few examples on how you can change common PHP settings. 16 | 17 | ::code-panel 18 | --- 19 | label: "Docker Compose: Changing allowed upload size" 20 | --- 21 | ```yaml 22 | version: '3' 23 | services: 24 | php: 25 | image: serversideup/php:8.2.12-unit-bookworm 26 | environment: 27 | PHP_POST_MAX_SIZE: "500M" 28 | PHP_UPLOAD_MAX_FILE_SIZE: "500M" 29 | SSL_MODE: "mixed" 30 | ports: 31 | - 80:8080 32 | - 443:8443 33 | volumes: 34 | - .:/var/www/html/ 35 | ``` 36 | :: 37 | 38 | ::code-panel 39 | --- 40 | label: "Docker CLI: Setting the PHP timezone to New York" 41 | --- 42 | ```bash 43 | docker run -d \ 44 | -p 80:8080 \ 45 | -v $(pwd):/var/www/html \ 46 | -e PHP_DATE_TIMEZONE="America/New_York" \ 47 | serversideup/php:8.2.12-fpm-nginx-bookworm 48 | ``` 49 | :: 50 | 51 | ## Setting your own php.ini 52 | PHP will read the `php.ini` file from the `/usr/local/etc/php/conf.d/` directory in alphabetical order. This means you can create your own `php.ini` file and mount it to the container to override the default settings. 53 | 54 | For example, we can create this file in our project directory: 55 | ::code-panel 56 | --- 57 | label: "zzz-custom-php.ini" 58 | --- 59 | ```ini 60 | mysqli.max_persistent = 300 61 | opcache.max_file_size = 10M 62 | opcache.log_verbosity_level = 3 63 | ``` 64 | :: 65 | 66 | Then in our Dockerfile, we can copy this file to the `/usr/local/etc/php/conf.d/` directory: 67 | ::code-panel 68 | --- 69 | label: "Dockerfile: Append to our default configuration" 70 | --- 71 | ```dockerfile 72 | FROM serversideup/php:8.3-fpm-nginx-bookworm 73 | 74 | COPY zzz-custom-php.ini /usr/local/etc/php/conf.d/ 75 | ``` 76 | :: 77 | 78 | If you prefer to remove the default `php.ini` file, you can do so by adding the following line to your Dockerfile: 79 | 80 | ::code-panel 81 | --- 82 | label: "Dockerfile: Remove our default configuration" 83 | --- 84 | ```dockerfile 85 | FROM serversideup/php:8.3-fpm-nginx-bookworm 86 | 87 | RUN rm /usr/local/etc/php/conf.d/serversideup-docker-php.ini 88 | COPY zzz-custom-php.ini /usr/local/etc/php/conf.d/ 89 | ``` 90 | :: 91 | 92 | ## Validating changes 93 | 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). -------------------------------------------------------------------------------- /docs/components/content/MarketingTestimonials.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/content/docs/4.laravel/2.laravel-task-scheduler.md: -------------------------------------------------------------------------------- 1 | --- 2 | head.title: 'Laravel Task Scheduler with Docker - Docker PHP - Server Side Up' 3 | description: 'Learn how to configure a Laravel Task Scheduler with Docker.' 4 | layout: docs 5 | --- 6 | 7 | # Laravel Task Scheduler with Docker 8 | Running a Laravel task scheduler with Docker can be a little different from the traditional methods. 9 | 10 | ## Important concepts 11 | 1. We will **not** use `cron` to run the scheduler 12 | 1. By default `schedule:work` checks every minute, so we will use that to run the system process 13 | 1. The actual time trigger itself is set within Laravel 14 | 1. You can do cool things with `PHP_FPM_POOL_NAME` to separate the task from the main PHP pool. This is helpful when debugging or monitoring the task. 15 | 16 | ## More detail 17 | We need to run the [schedule:work](https://laravel.com/docs/11.x/scheduling#running-the-scheduler-locally) command from Laravel. Although the docs say "Running the scheduler locally", this is what we want in production. It will run the scheduler in the foreground and execute it every minute. You can configure your Laravel app for the exact time that a command should run through a [scheduled task](https://laravel.com/docs/11.x/scheduling#scheduling-artisan-commands). 18 | 19 | 20 | ## Examples 21 | Here is a simplified example of how you can achieve this with Docker Compose: 22 | ::code-panel 23 | --- 24 | label: Example & Simplified Docker Compose File 25 | --- 26 | ```yaml 27 | services: 28 | php: 29 | image: my/laravel-app 30 | environment: 31 | PHP_FPM_POOL_NAME: "my-app_php" 32 | 33 | task: 34 | image: my/laravel-app 35 | command: ["php", "/var/www/html/artisan", "schedule:work"] 36 | environment: 37 | PHP_FPM_POOL_NAME: "my-app_task" 38 | ``` 39 | :: 40 | 41 | 42 | This is an example how we would set the actual execution time within Laravel itself: 43 | ::code-panel 44 | --- 45 | label: Example Laravel `Kernel.php` 46 | --- 47 | ```php 48 | command('process:invoices')->daily()->at('02:00')->timezone('America/Chicago'); 75 | $schedule->command('process:latefees')->daily()->at('04:00')->timezone('America/Chicago'); 76 | } 77 | 78 | /** 79 | * Register the commands for the application. 80 | * 81 | * @return void 82 | */ 83 | protected function commands() 84 | { 85 | $this->load(__DIR__.'/Commands'); 86 | 87 | require base_path('routes/console.php'); 88 | } 89 | } 90 | ``` 91 | :: -------------------------------------------------------------------------------- /docs/layouts/marketing.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | -------------------------------------------------------------------------------- /docs/layouts/docs.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | -------------------------------------------------------------------------------- /src/variations/fpm-apache/etc/apache2/conf-available/security.conf: -------------------------------------------------------------------------------- 1 | # 2 | # Disable access to the entire file system except for the directories that 3 | # are explicitly allowed later. 4 | # 5 | # This currently breaks the configurations that come with some web application 6 | # Debian packages. 7 | # 8 | # 9 | # AllowOverride None 10 | # Require all denied 11 | # 12 | 13 | 14 | # Changing the following options will not really affect the security of the 15 | # server, but might make attacks slightly more difficult in some cases. 16 | 17 | # 18 | # ServerTokens 19 | # This directive configures what you return as the Server HTTP response 20 | # Header. The default is 'Full' which sends information about the OS-Type 21 | # and compiled in modules. 22 | # Set to one of: Full | OS | Minimal | Minor | Major | Prod 23 | # where Full conveys the most information, and Prod the least. 24 | #ServerTokens Minimal 25 | # ServerTokens OS 26 | # #ServerTokens Full 27 | ServerTokens Prod 28 | 29 | # 30 | # Optionally add a line containing the server version and virtual host 31 | # name to server-generated pages (internal error documents, FTP directory 32 | # listings, mod_status and mod_info output etc., but not CGI generated 33 | # documents or custom error documents). 34 | # Set to "EMail" to also include a mailto: link to the ServerAdmin. 35 | # Set to one of: On | Off | EMail 36 | ServerSignature Off 37 | # ServerSignature On 38 | 39 | # 40 | # Allow TRACE method 41 | # 42 | # Set to "extended" to also reflect the request body (only for testing and 43 | # diagnostic purposes). 44 | # 45 | # Set to one of: On | Off | extended 46 | TraceEnable Off 47 | #TraceEnable On 48 | 49 | # 50 | # Forbid access to version control directories 51 | # 52 | # If you use version control systems in your document root, you should 53 | # probably deny access to their directories. For example, for subversion: 54 | # 55 | 56 | Require all denied 57 | 58 | 59 | # Prevent Apache from serving Gitlab files 60 | 61 | Require all denied 62 | 63 | 64 | # Disable XML-RPC on all wordpress sites 65 | 66 | Require all denied 67 | # allow from xxx.xxx.xxx.xxx 68 | 69 | 70 | # 71 | # Setting this header will prevent MSIE from interpreting files as something 72 | # else than declared by the content type in the HTTP headers. 73 | # Requires mod_headers to be enabled. 74 | # 75 | Header always set X-Content-Type-Options: "nosniff" 76 | 77 | # 78 | # Setting this header will prevent other sites from embedding pages from this 79 | # site as frames. This defends against clickjacking attacks. 80 | # Requires mod_headers to be enabled. 81 | # 82 | Header always set X-Frame-Options: "sameorigin" 83 | 84 | # 85 | # Referrer policy 86 | # 87 | Header always set Referrer-Policy "no-referrer-when-downgrade" 88 | 89 | # 90 | # Content Security Policy 91 | # UPDATE - September 2020: Commenting this out until we grasp better security requirements 92 | # 93 | #Header always set Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" 94 | 95 | # 96 | # Strict-Transport-Security Policy (set HSTS) 97 | # 98 | Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains" -------------------------------------------------------------------------------- /src/variations/cli/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_OS_VERSION='bookworm' 2 | ARG PHP_VERSION='8.3' 3 | ARG PHP_VARIATION='cli' 4 | 5 | ########## 6 | # CLI: Main Image 7 | ########## 8 | FROM php:${PHP_VERSION}-${PHP_VARIATION}-${BASE_OS_VERSION} 9 | 10 | ARG DEPENDENCY_PACKAGES_ALPINE='shadow' 11 | ARG DEPENDENCY_PACKAGES_DEBIAN='zip' 12 | ARG DEPENDENCY_PHP_EXTENSIONS='opcache pcntl pdo_mysql pdo_pgsql redis zip' 13 | ARG REPOSITORY_BUILD_VERSION='dev' 14 | 15 | LABEL org.opencontainers.image.title="serversideup/php (${PHP_VARIATION})" \ 16 | org.opencontainers.image.description="Supercharge your PHP experience. Based off the official PHP images, serversideup/php includes pre-configured PHP extensions and settings for enhanced performance and security. Optimized for Laravel and WordPress." \ 17 | org.opencontainers.image.url="https://serversideup.net/open-source/docker-php/" \ 18 | org.opencontainers.image.source="https://github.com/serversideup/docker-php" \ 19 | org.opencontainers.image.documentation="https://serversideup.net/open-source/docker-php/docs/" \ 20 | org.opencontainers.image.vendor="ServerSideUp" \ 21 | org.opencontainers.image.authors="Jay Rogers (@jaydrogers)" \ 22 | org.opencontainers.image.version="${REPOSITORY_BUILD_VERSION}" \ 23 | org.opencontainers.image.licenses="GPL-3.0-or-later" 24 | 25 | ENV APP_BASE_DIR=/var/www/html \ 26 | COMPOSER_ALLOW_SUPERUSER=1 \ 27 | COMPOSER_HOME=/composer \ 28 | COMPOSER_MAX_PARALLEL_HTTP=24 \ 29 | DISABLE_DEFAULT_CONFIG=false \ 30 | LOG_OUTPUT_LEVEL=warn \ 31 | PHP_DATE_TIMEZONE="UTC" \ 32 | PHP_DISPLAY_ERRORS=Off \ 33 | PHP_DISPLAY_STARTUP_ERRORS=Off \ 34 | PHP_ERROR_LOG="/dev/stderr" \ 35 | PHP_ERROR_REPORTING="22527" \ 36 | PHP_MAX_EXECUTION_TIME="99" \ 37 | PHP_MAX_INPUT_TIME="-1" \ 38 | PHP_MEMORY_LIMIT="256M" \ 39 | PHP_OPCACHE_ENABLE="0" \ 40 | PHP_OPCACHE_INTERNED_STRINGS_BUFFER="8" \ 41 | PHP_OPCACHE_MAX_ACCELERATED_FILES="10000" \ 42 | PHP_OPCACHE_MEMORY_CONSUMPTION="128" \ 43 | PHP_OPCACHE_REVALIDATE_FREQ="2" \ 44 | PHP_OPEN_BASEDIR="" \ 45 | PHP_POST_MAX_SIZE="100M" \ 46 | PHP_SESSION_COOKIE_SECURE=false \ 47 | PHP_UPLOAD_MAX_FILE_SIZE="100M" \ 48 | SHOW_WELCOME_MESSAGE=true 49 | 50 | # copy our scripts 51 | COPY --chmod=755 src/common/ / 52 | 53 | # install pecl extensions & dependencies 54 | RUN docker-php-serversideup-dep-install-alpine "${DEPENDENCY_PACKAGES_ALPINE}" && \ 55 | docker-php-serversideup-dep-install-debian "${DEPENDENCY_PACKAGES_DEBIAN}" && \ 56 | docker-php-serversideup-install-php-ext-installer && \ 57 | \ 58 | # Ensure /var/www/ has the correct permissions 59 | chown -R www-data:www-data /var/www && \ 60 | chmod -R 755 /var/www && \ 61 | \ 62 | # Make composer cache directory 63 | mkdir -p "${COMPOSER_HOME}" && \ 64 | chown -R www-data:www-data "${COMPOSER_HOME}" && \ 65 | \ 66 | # Install default PHP extensions 67 | install-php-extensions "${DEPENDENCY_PHP_EXTENSIONS}" 68 | 69 | # install composer from Composer's official Docker image 70 | COPY --from=composer:2 /usr/bin/composer /usr/bin/composer 71 | 72 | RUN docker-php-serversideup-set-file-permissions --owner www-data:www-data --service cli 73 | 74 | WORKDIR ${APP_BASE_DIR} 75 | 76 | USER www-data 77 | 78 | ENTRYPOINT ["docker-php-serversideup-entrypoint"] 79 | --------------------------------------------------------------------------------