├── .gitignore ├── src ├── start-nginx.sh ├── php │ ├── ondrej_ubuntu_php.gpg │ └── packages │ │ ├── 8.4.txt │ │ ├── 8.0.txt │ │ ├── 8.1.txt │ │ ├── 8.2.txt │ │ ├── 8.3.txt │ │ └── 7.4.txt ├── entrypoint-unit.sh ├── entrypoint.sh ├── nginx │ ├── conf.d │ │ ├── websockets.conf │ │ └── access-log.conf │ ├── nginx.conf │ └── sites-available │ │ ├── default │ │ └── default-octane ├── supervisor │ ├── conf.d │ │ ├── fpm.conf │ │ └── nginx.conf │ ├── octane-swoole.conf │ ├── octane-franken.conf │ ├── octane-rr.conf │ └── supervisord.conf ├── unit │ └── conf.json ├── Dockerfile ├── Dockerfile-unit └── fpm │ └── pool.d │ └── www.conf ├── fly-builder ├── entrypoint ├── docker-entrypoint.d │ ├── docker │ └── sysctl ├── Dockerfile ├── etc │ └── docker │ │ └── daemon.json └── readme.md ├── .github └── workflows │ ├── test-pr.yml │ └── docker-images.yml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | .secrets -------------------------------------------------------------------------------- /src/start-nginx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | sleep 0.25 && exec nginx 4 | -------------------------------------------------------------------------------- /src/php/ondrej_ubuntu_php.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fly-apps/laravel-docker/HEAD/src/php/ondrej_ubuntu_php.gpg -------------------------------------------------------------------------------- /src/entrypoint-unit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ $# -gt 0 ]]; then 4 | exec "$@" 5 | else 6 | exec unitd --no-daemon --log /dev/stdout 7 | fi 8 | -------------------------------------------------------------------------------- /src/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [[ $# -gt 0 ]]; then 4 | exec "$@" 5 | else 6 | exec supervisord -c /etc/supervisor/supervisord.conf 7 | fi 8 | -------------------------------------------------------------------------------- /src/nginx/conf.d/websockets.conf: -------------------------------------------------------------------------------- 1 | # See https://laravel.com/docs/9.x/octane#serving-your-application-via-nginx 2 | map $http_upgrade $connection_upgrade { 3 | default upgrade; 4 | '' close; 5 | } -------------------------------------------------------------------------------- /fly-builder/entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [[ -d "docker-entrypoint.d" ]] 6 | then 7 | echo "Running docker-entrypoint.d files" 8 | /bin/run-parts docker-entrypoint.d 9 | fi 10 | 11 | echo "Running $@" 12 | 13 | exec "$@" -------------------------------------------------------------------------------- /src/php/packages/8.4.txt: -------------------------------------------------------------------------------- 1 | php8.4-bcmath 2 | php8.4-cli 3 | php8.4-common 4 | php8.4-curl 5 | php8.4-gd 6 | php8.4-intl 7 | php8.4-mbstring 8 | php8.4-mysql 9 | php8.4-pgsql 10 | php8.4-redis 11 | php8.4-soap 12 | php8.4-sqlite3 13 | php8.4-xml 14 | php8.4-zip 15 | php8.4-fpm 16 | -------------------------------------------------------------------------------- /src/php/packages/8.0.txt: -------------------------------------------------------------------------------- 1 | php8.0-bcmath 2 | php8.0-cli 3 | php8.0-common 4 | php8.0-curl 5 | php8.0-gd 6 | php8.0-intl 7 | php8.0-mbstring 8 | php8.0-mysql 9 | php8.0-pgsql 10 | php8.0-redis 11 | php8.0-soap 12 | php8.0-sqlite3 13 | php8.0-xml 14 | php8.0-zip 15 | php8.0-swoole 16 | php8.0-fpm -------------------------------------------------------------------------------- /src/php/packages/8.1.txt: -------------------------------------------------------------------------------- 1 | php8.1-bcmath 2 | php8.1-cli 3 | php8.1-common 4 | php8.1-curl 5 | php8.1-gd 6 | php8.1-intl 7 | php8.1-mbstring 8 | php8.1-mysql 9 | php8.1-pgsql 10 | php8.1-redis 11 | php8.1-soap 12 | php8.1-sqlite3 13 | php8.1-xml 14 | php8.1-zip 15 | php8.1-swoole 16 | php8.1-fpm -------------------------------------------------------------------------------- /src/php/packages/8.2.txt: -------------------------------------------------------------------------------- 1 | php8.2-bcmath 2 | php8.2-cli 3 | php8.2-common 4 | php8.2-curl 5 | php8.2-gd 6 | php8.2-intl 7 | php8.2-mbstring 8 | php8.2-mysql 9 | php8.2-pgsql 10 | php8.2-redis 11 | php8.2-soap 12 | php8.2-sqlite3 13 | php8.2-xml 14 | php8.2-zip 15 | php8.2-swoole 16 | php8.2-fpm -------------------------------------------------------------------------------- /src/php/packages/8.3.txt: -------------------------------------------------------------------------------- 1 | php8.3-bcmath 2 | php8.3-cli 3 | php8.3-common 4 | php8.3-curl 5 | php8.3-gd 6 | php8.3-intl 7 | php8.3-mbstring 8 | php8.3-mysql 9 | php8.3-pgsql 10 | php8.3-redis 11 | php8.3-soap 12 | php8.3-sqlite3 13 | php8.3-xml 14 | php8.3-zip 15 | php8.3-swoole 16 | php8.3-fpm -------------------------------------------------------------------------------- /src/php/packages/7.4.txt: -------------------------------------------------------------------------------- 1 | php7.4-bcmath 2 | php7.4-cli 3 | php7.4-common 4 | php7.4-curl 5 | php7.4-gd 6 | php7.4-intl 7 | php7.4-json 8 | php7.4-mbstring 9 | php7.4-mysql 10 | php7.4-pgsql 11 | php7.4-redis 12 | php7.4-soap 13 | php7.4-sqlite3 14 | php7.4-xml 15 | php7.4-zip 16 | php7.4-swoole 17 | php7.4-fpm -------------------------------------------------------------------------------- /fly-builder/docker-entrypoint.d/docker: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "Setting up Docker data directory" 6 | mkdir -p /data/docker 7 | 8 | echo "Configuring ipv6 for docker" 9 | ip6tables -t nat -A POSTROUTING -s 2001:db8:1::/64 ! -o docker0 -j MASQUERADE 10 | 11 | echo "Done setting up docker!" 12 | -------------------------------------------------------------------------------- /src/supervisor/conf.d/fpm.conf: -------------------------------------------------------------------------------- 1 | [program:php] 2 | priority=5 3 | autostart=true 4 | autorestart=true 5 | stdout_events_enabled=true 6 | stderr_events_enabled=true 7 | command=php-fpm 8 | stdout_logfile=/dev/stdout 9 | stdout_logfile_maxbytes=0 10 | stderr_logfile=/dev/stderr 11 | stderr_logfile_maxbytes=0 12 | -------------------------------------------------------------------------------- /src/supervisor/conf.d/nginx.conf: -------------------------------------------------------------------------------- 1 | [program:nginx] 2 | priority=10 3 | autostart=true 4 | autorestart=true 5 | stdout_events_enabled=true 6 | stderr_events_enabled=true 7 | command=/usr/local/bin/start-nginx 8 | stdout_logfile=/dev/stdout 9 | stdout_logfile_maxbytes=0 10 | stderr_logfile=/dev/stderr 11 | stderr_logfile_maxbytes=0 12 | -------------------------------------------------------------------------------- /.github/workflows/test-pr.yml: -------------------------------------------------------------------------------- 1 | name: Test PR 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - '**' 7 | types: 8 | - opened 9 | - synchronize 10 | - reopened 11 | workflow_dispatch: 12 | 13 | jobs: 14 | 15 | build: 16 | 17 | runs-on: ubuntu-latest 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | 22 | - name: Build and Push Images 23 | run: ./build.sh 24 | -------------------------------------------------------------------------------- /src/supervisor/octane-swoole.conf: -------------------------------------------------------------------------------- 1 | [program:octane] 2 | priority=5 3 | command=php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=swoole --host=0.0.0.0 --port=8000 4 | user=www-data 5 | autostart=true 6 | autorestart=true 7 | stdout_events_enabled=true 8 | stderr_events_enabled=true 9 | stdout_logfile=/dev/stdout 10 | stdout_logfile_maxbytes=0 11 | stderr_logfile=/dev/stderr 12 | stderr_logfile_maxbytes=0 13 | -------------------------------------------------------------------------------- /src/supervisor/octane-franken.conf: -------------------------------------------------------------------------------- 1 | [program:octane] 2 | priority=5 3 | command=php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=frankenphp --admin-port=2019 --port=8000 4 | user=www-data 5 | autostart=true 6 | autorestart=true 7 | stdout_events_enabled=true 8 | stderr_events_enabled=true 9 | stdout_logfile=/dev/stdout 10 | stdout_logfile_maxbytes=0 11 | stderr_logfile=/dev/stderr 12 | stderr_logfile_maxbytes=0 13 | -------------------------------------------------------------------------------- /src/supervisor/octane-rr.conf: -------------------------------------------------------------------------------- 1 | [program:octane] 2 | priority=5 3 | command=php -d variables_order=EGPCS /var/www/html/artisan octane:start --server=roadrunner --host=0.0.0.0 --rpc-port=6001 --port=8000 4 | user=www-data 5 | autostart=true 6 | autorestart=true 7 | stdout_events_enabled=true 8 | stderr_events_enabled=true 9 | stdout_logfile=/dev/stdout 10 | stdout_logfile_maxbytes=0 11 | stderr_logfile=/dev/stderr 12 | stderr_logfile_maxbytes=0 13 | -------------------------------------------------------------------------------- /fly-builder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker/buildx-bin:v0.8 as buildx 2 | 3 | FROM docker:20-dind 4 | 5 | RUN apk add bash ip6tables pigz sysstat procps lsof 6 | 7 | COPY etc/docker/daemon.json /etc/docker/daemon.json 8 | 9 | COPY --from=buildx /buildx /root/.docker/cli-plugins/docker-buildx 10 | 11 | COPY ./entrypoint ./entrypoint 12 | COPY ./docker-entrypoint.d/* ./docker-entrypoint.d/ 13 | 14 | ENV DOCKER_TMPDIR=/data/docker/tmp 15 | 16 | ENTRYPOINT ["./entrypoint"] 17 | 18 | CMD ["dockerd", "-p", "/var/run/docker.pid"] 19 | -------------------------------------------------------------------------------- /.github/workflows/docker-images.yml: -------------------------------------------------------------------------------- 1 | name: Build Base Images 2 | on: 3 | schedule: 4 | - cron: "0 0 * * 5" 5 | workflow_dispatch: 6 | 7 | jobs: 8 | 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v3 15 | 16 | - name: Login to Docker Hub 17 | uses: docker/login-action@v2 18 | with: 19 | username: ${{ secrets.DOCKERHUB_USERNAME }} 20 | password: ${{ secrets.DOCKERHUB_TOKEN }} 21 | 22 | - name: Build and Push Images 23 | run: ./build.sh push 24 | -------------------------------------------------------------------------------- /src/nginx/conf.d/access-log.conf: -------------------------------------------------------------------------------- 1 | # If Fly-Client-Ip is empty, set $forwarded_header_value to 2 | # value of X-Forwarded-For, else set 3 | # $forwarded_header_value to value of Fly-Client-Ip 4 | map $http_fly_client_ip $forwarded_header_value { 5 | default $http_fly_client_ip; 6 | "" $http_x_forwarded_for; 7 | } 8 | 9 | # Use variable $forwarded_header_value in place where we'd normally 10 | # see $http_x_forwarded_For. We prefer the value of Fly-Client-Ip 11 | # if it's available 12 | log_format fly '$remote_addr - $remote_user [$time_local] "$request" ' 13 | '$status $body_bytes_sent "$http_referer" ' 14 | '"$http_user_agent" "$forwarded_header_value"'; -------------------------------------------------------------------------------- /fly-builder/etc/docker/daemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "data-root": "/data/docker", 3 | "experimental": true, 4 | "ipv6": true, 5 | "ip6tables": true, 6 | "fixed-cidr-v6": "2001:db8:1::/64", 7 | "default-address-pools": [ 8 | { 9 | "base": "10.100.0.1/16", 10 | "size": 24 11 | } 12 | ], 13 | "debug": true, 14 | "log-level": "debug", 15 | "features": { 16 | "buildkit": true 17 | }, 18 | "hosts": [ 19 | "unix:///var/run/docker.sock", 20 | "tcp://[::]:2375" 21 | ], 22 | "mtu": 1400, 23 | "max-concurrent-downloads": 10, 24 | "max-concurrent-uploads": 5, 25 | "metrics-addr": "0.0.0.0:9323", 26 | "tls": false 27 | } -------------------------------------------------------------------------------- /src/unit/conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "listeners": { 3 | "*:8080": { 4 | "pass": "routes" 5 | } 6 | }, 7 | 8 | "routes": [ 9 | { 10 | "match": { 11 | "uri": "!/index.php" 12 | }, 13 | "action": { 14 | "share": "/var/www/html/public$uri", 15 | "fallback": { 16 | "pass": "applications/laravel" 17 | } 18 | } 19 | } 20 | ], 21 | 22 | "applications": { 23 | "laravel": { 24 | "type": "php", 25 | "root": "/var/www/html/public/", 26 | "script": "index.php", 27 | "processes": {} 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/supervisor/supervisord.conf: -------------------------------------------------------------------------------- 1 | ; supervisor config file 2 | 3 | [unix_http_server] 4 | file=/var/run/supervisor.sock ; (the path to the socket file) 5 | chmod=0700 ; sockef file mode (default 0700) 6 | 7 | [supervisord] 8 | logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) 9 | pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) 10 | childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) 11 | ; @fly 12 | nodaemon=true 13 | 14 | ; the below section must remain in the config file for RPC 15 | ; (supervisorctl/web interface) to work, additional interfaces may be 16 | ; added by defining them in separate rpcinterface: sections 17 | [rpcinterface:supervisor] 18 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 19 | 20 | [supervisorctl] 21 | serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket 22 | 23 | ; The [include] section can just contain the "files" setting. This 24 | ; setting can list multiple files (separated by whitespace or 25 | ; newlines). It can also contain wildcards. The filenames are 26 | ; interpreted as relative to this file. Included files *cannot* 27 | ; include files themselves. 28 | 29 | [include] 30 | files = /etc/supervisor/conf.d/*.conf -------------------------------------------------------------------------------- /fly-builder/readme.md: -------------------------------------------------------------------------------- 1 | # Fly Builder 2 | 3 | Run Docker in a Fly.io VM. 4 | 5 | This helps run `docker build...` on AMD64 instances, especially useful when you're hacking on this project from an ARM-based infrastructure or a machine that runs on a battery. 6 | 7 | A lot of this is based on [this repository](https://github.com/fly-apps/docker-daemon). 8 | 9 | ## Setting Up the Remote Builder 10 | 11 | Creating a builder for use like this can be done using [Fly Machines](https://fly.io/docs/machines/). 12 | 13 | Here are the steps: 14 | 15 | ```bash 16 | # Create an app to house the VM that will run Docker 17 | fly apps create --machines --name laravel-docker-builder 18 | 19 | # Create a volume 20 | fly volumes create -r dfw -a laravel-docker-builder -s 50 laravel_docker 21 | 22 | # From this directory, which contains a Dockerfile 23 | fly m run . -r dfw -v laravel_docker:/data -a laravel-docker-builder 24 | ``` 25 | 26 | ## Using the Remote Builder 27 | 28 | Once you [setup Wireguard](https://fly.io/docs/reference/private-networking/#private-network-vpn) with Fly, you can activate the VPN and run Docker builds remotely by setting `DOCKER_HOST`: 29 | 30 | ```bash 31 | # Get the IP Address of the VM we created 32 | fly m list -a laravel-docker-builder 33 | 34 | # Use that as your DOCKER_HOST 35 | DOCKER_HOST=tcp://[fdaa:0:6ba9:a7b:97:142d:77ac:2]:2375 docker ps 36 | ``` 37 | -------------------------------------------------------------------------------- /src/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | user www-data; 2 | worker_processes auto; 3 | pid /run/nginx.pid; 4 | include /etc/nginx/modules-enabled/*.conf; 5 | daemon off; 6 | 7 | events { 8 | worker_connections 768; 9 | # multi_accept on; 10 | } 11 | 12 | http { 13 | 14 | ## 15 | # Basic Settings 16 | ## 17 | 18 | sendfile on; 19 | tcp_nopush on; 20 | tcp_nodelay on; 21 | keepalive_timeout 65; 22 | types_hash_max_size 2048; 23 | server_tokens off; 24 | 25 | # server_names_hash_bucket_size 64; 26 | # server_name_in_redirect off; 27 | 28 | include /etc/nginx/mime.types; 29 | default_type application/octet-stream; 30 | 31 | ## 32 | # SSL Settings 33 | ## 34 | 35 | ssl_protocols TLSv1.2 TLSv1.3; 36 | ssl_prefer_server_ciphers on; 37 | 38 | ## 39 | # Logging Settings 40 | ## 41 | 42 | access_log /dev/stdout; 43 | error_log /dev/stderr; 44 | 45 | ## 46 | # Increase header size for better support on Laravel APIs 47 | ## 48 | http2_max_field_size 16k; 49 | http2_max_header_size 32k; 50 | 51 | ## 52 | # Gzip Settings 53 | ## 54 | 55 | gzip on; 56 | gzip_vary on; 57 | gzip_proxied any; 58 | gzip_comp_level 6; 59 | gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml; 60 | 61 | ## 62 | # Virtual Host Configs 63 | ## 64 | 65 | include /etc/nginx/conf.d/*.conf; 66 | include /etc/nginx/sites-enabled/*; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /fly-builder/docker-entrypoint.d/sysctl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "Allowing ipv6 forwarding via sysctl" 6 | sysctl net.ipv6.conf.default.forwarding=1 7 | sysctl net.ipv6.conf.all.forwarding=1 8 | 9 | echo "General sysctl tweaks" 10 | sysctl vm.swappiness=0 11 | sysctl vm.dirty_ratio=6 12 | sysctl vm.dirty_background_ratio=3 13 | 14 | # Default Socket Receive Buffer 15 | sysctl net.core.rmem_default=31457280 16 | 17 | # Maximum Socket Receive Buffer 18 | sysctl net.core.rmem_max=33554432 19 | 20 | # Default Socket Send Buffer 21 | sysctl net.core.wmem_default=31457280 22 | 23 | # Maximum Socket Send Buffer 24 | sysctl net.core.wmem_max=33554432 25 | 26 | # Increase number of incoming connections 27 | sysctl net.core.somaxconn=65535 28 | 29 | # Increase number of incoming connections backlog 30 | sysctl net.core.netdev_max_backlog=65536 31 | 32 | # Increase the maximum amount of option memory buffers 33 | sysctl net.core.optmem_max=25165824 34 | 35 | # Increase the maximum total buffer-space allocatable 36 | # This is measured in units of pages (4096 bytes) 37 | sysctl "net.ipv4.tcp_mem=786432 1048576 26777216" 38 | sysctl "net.ipv4.udp_mem=65536 131072 262144" 39 | 40 | # Increase the read-buffer space allocatable 41 | sysctl "net.ipv4.tcp_rmem=8192 87380 33554432" 42 | sysctl net.ipv4.udp_rmem_min=16384 43 | 44 | # Increase the write-buffer-space allocatable 45 | sysctl "net.ipv4.tcp_wmem=8192 65536 33554432" 46 | sysctl net.ipv4.udp_wmem_min=16384 -------------------------------------------------------------------------------- /src/nginx/sites-available/default: -------------------------------------------------------------------------------- 1 | server { 2 | listen 8080 default_server; 3 | listen [::]:8080 default_server; 4 | 5 | root /var/www/html/public; 6 | 7 | index index.html index.htm index.php; 8 | 9 | server_name _; 10 | 11 | charset utf-8; 12 | 13 | client_max_body_size 2048M; 14 | 15 | access_log /dev/stdout fly; 16 | 17 | location / { 18 | try_files $uri $uri/ /index.php?$query_string; 19 | } 20 | 21 | location ~ \.php$ { 22 | include snippets/fastcgi-php.conf; 23 | fastcgi_param HTTP_X_FORWARDED_FOR $http_fly_client_ip; 24 | fastcgi_pass unix:/var/run/php/php-fpm.sock; 25 | fastcgi_buffers 16 16k; 26 | fastcgi_buffer_size 32k; 27 | } 28 | 29 | location = /favicon.ico { 30 | log_not_found off; 31 | access_log off; 32 | } 33 | 34 | location = /robots.txt { 35 | log_not_found off; 36 | access_log off; 37 | } 38 | 39 | 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)$ { 40 | expires 7d; 41 | access_log off; 42 | log_not_found off; 43 | # Pass to PHP to ensure PHP apps can handle routes that end in these filetypes 44 | try_files $uri /index.php?$query_string; 45 | } 46 | 47 | location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ { 48 | add_header Access-Control-Allow-Origin "*"; 49 | expires 7d; 50 | access_log off; 51 | } 52 | 53 | location ~ /\.(?!well-known) { 54 | deny all; 55 | } 56 | 57 | add_header X-Frame-Options "SAMEORIGIN" always; 58 | add_header X-Content-Type-Options "nosniff" always; 59 | add_header Referrer-Policy "no-referrer-when-downgrade" always; 60 | } 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Docker 2 | 3 | This repository creates base Docker images for use with [Laravel](https://laravel.com) on [Fly.io](https://fly.io). 4 | 5 | ## PHP 6 | 7 | This creates a base container for the following PHP versions 8 | 9 | * 7.4 10 | * 8.0 11 | * 8.1 12 | * 8.2 13 | * 8.3 14 | * 8.4 15 | 16 | Built containers from this project will be available at https://hub.docker.com/r/fideloper/fly-laravel 17 | 18 | ## Building 19 | 20 | You can build containers from this project using a command like so: 21 | 22 | ```bash 23 | # From the project root: 24 | PHP_VERSION="8.4" 25 | docker build \ 26 | -t myimage:$PHP_VERSION 27 | --build-arg PHP_VERSION=$PHP_VERSION \ 28 | -f src/Dockerfile \ 29 | ./src 30 | ``` 31 | 32 | ## Configuration 33 | 34 | The following environment variables can be set at run-time or when extending this container: 35 | 36 | | env | description | default value | 37 | |------|--------------------------------------|---------------| 38 | | PHP_PM_MAX_CHILDREN | php-fpm setting pm.max_children | 10 | 39 | | PHP_PM_START_SERVERS | php-fpm setting pm.start_servers | 3 | 40 | | PHP_MIN_SPARE_SERVERS | php-fpm setting pm.min_spare_servers | 2 | 41 | | PHP_MAX_SPARE_SERVERS | php-fpm setting pm.max_spare_servers | 4 | 42 | | PHP_DATE_TIMEZONE | php setting timezone | UTC | 43 | | PHP_DISPLAY_ERRORS | php setting display_errors | Off | 44 | | PHP_ERROR_REPORTING | php setting error_reporting | 22527 | 45 | | PHP_MEMORY_LIMIT | php setting memory_limit | 256M | 46 | | PHP_MAX_EXECUTION_TIME | php setting max_execution_time | 90 | 47 | | PHP_POST_MAX_SIZE | php setting post_max_size | 100M | 48 | | PHP_UPLOAD_MAX_FILE_SIZE | php setting upload_max_file_size | 100M | 49 | | PHP_ALLOW_URL_FOPEN | php setting allow_url_fopen | Off | 50 | -------------------------------------------------------------------------------- /src/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | ARG PHP_VERSION='8.2' 4 | 5 | LABEL maintainer="Chris Fidao (fideloper@fly.io)" 6 | 7 | ENV DEBIAN_FRONTEND=noninteractive \ 8 | COMPOSER_ALLOW_SUPERUSER=1 \ 9 | COMPOSER_HOME=/composer \ 10 | COMPOSER_MAX_PARALLEL_HTTP=24 \ 11 | PHP_PM_MAX_CHILDREN=10 \ 12 | PHP_PM_START_SERVERS=3 \ 13 | PHP_MIN_SPARE_SERVERS=2 \ 14 | PHP_MAX_SPARE_SERVERS=4 \ 15 | PHP_DATE_TIMEZONE=UTC \ 16 | PHP_DISPLAY_ERRORS=Off \ 17 | PHP_ERROR_REPORTING=22527 \ 18 | PHP_MEMORY_LIMIT=256M \ 19 | PHP_MAX_EXECUTION_TIME=90 \ 20 | PHP_POST_MAX_SIZE=100M \ 21 | PHP_UPLOAD_MAX_FILE_SIZE=100M \ 22 | PHP_ALLOW_URL_FOPEN=Off 23 | 24 | COPY --from=composer:2 /usr/bin/composer /usr/bin/composer 25 | COPY php/ondrej_ubuntu_php.gpg /etc/apt/trusted.gpg.d/ondrej_ubuntu_php.gpg 26 | ADD php/packages/${PHP_VERSION}.txt /tmp/php-packages.txt 27 | 28 | RUN apt-get update \ 29 | && apt-get install -y --no-install-recommends gnupg2 ca-certificates git-core curl zip unzip \ 30 | rsync vim-tiny htop sqlite3 nginx supervisor cron \ 31 | && ln -sf /usr/bin/vim.tiny /etc/alternatives/vim \ 32 | && ln -sf /etc/alternatives/vim /usr/bin/vim \ 33 | && echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu jammy main" > /etc/apt/sources.list.d/ondrej-ubuntu-php-focal.list \ 34 | && apt-get update \ 35 | && apt-get -y --no-install-recommends install $(cat /tmp/php-packages.txt) \ 36 | && ln -sf /usr/sbin/php-fpm${PHP_VERSION} /usr/sbin/php-fpm \ 37 | && mkdir -p /var/www/html/public && echo " /var/www/html/public/index.php \ 38 | && apt-get clean \ 39 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/* 40 | 41 | COPY nginx/ /etc/nginx/ 42 | COPY fpm/ /etc/php/${PHP_VERSION}/fpm/ 43 | COPY supervisor/ /etc/supervisor/ 44 | COPY entrypoint.sh /entrypoint 45 | COPY start-nginx.sh /usr/local/bin/start-nginx 46 | 47 | WORKDIR /var/www/html 48 | 49 | ENTRYPOINT ["/entrypoint"] 50 | -------------------------------------------------------------------------------- /src/nginx/sites-available/default-octane: -------------------------------------------------------------------------------- 1 | server { 2 | listen 8080 default_server; 3 | listen [::]:8080 default_server; 4 | 5 | root /var/www/html/public; 6 | 7 | index index.html index.htm index.php; 8 | 9 | server_name _; 10 | 11 | charset utf-8; 12 | 13 | client_max_body_size 2048M; 14 | 15 | access_log /dev/stdout fly; 16 | 17 | location /index.php { 18 | try_files /not_exists @octane; 19 | } 20 | 21 | location / { 22 | try_files $uri $uri/ @octane; 23 | } 24 | 25 | location @octane { 26 | set $suffix ""; 27 | 28 | if ($uri = /index.php) { 29 | set $suffix ?$query_string; 30 | } 31 | 32 | proxy_http_version 1.1; 33 | proxy_set_header Host $http_host; 34 | proxy_set_header Scheme $scheme; 35 | proxy_set_header SERVER_PORT $server_port; 36 | proxy_set_header REMOTE_ADDR $remote_addr; 37 | proxy_set_header X-Forwarded-For $http_fly_client_ip; 38 | proxy_set_header Upgrade $http_upgrade; 39 | proxy_set_header Connection $connection_upgrade; 40 | 41 | proxy_buffers 16 16k; 42 | proxy_buffer_size 32k; 43 | 44 | proxy_pass http://127.0.0.1:8000$suffix; 45 | } 46 | 47 | location = /favicon.ico { 48 | log_not_found off; 49 | access_log off; 50 | } 51 | 52 | location = /robots.txt { 53 | log_not_found off; 54 | access_log off; 55 | } 56 | 57 | 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)$ { 58 | expires 7d; 59 | access_log off; 60 | log_not_found off; 61 | # Pass to PHP to ensure PHP apps can handle routes that end in these filetypes 62 | try_files $uri @octane; 63 | } 64 | 65 | location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ { 66 | add_header Access-Control-Allow-Origin "*"; 67 | expires 7d; 68 | access_log off; 69 | } 70 | 71 | location ~ /\.(?!well-known) { 72 | deny all; 73 | } 74 | 75 | add_header X-Frame-Options "SAMEORIGIN" always; 76 | add_header X-Content-Type-Options "nosniff" always; 77 | add_header Referrer-Policy "no-referrer-when-downgrade" always; 78 | } 79 | -------------------------------------------------------------------------------- /src/Dockerfile-unit: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 as unit-builder 2 | 3 | ARG PHP_VERSION='8.2' 4 | ARG UNIT_VERSION='1.31.1' 5 | 6 | ENV DEBIAN_FRONTEND=noninteractive 7 | 8 | COPY php/ondrej_ubuntu_php.gpg /etc/apt/trusted.gpg.d/ondrej_ubuntu_php.gpg 9 | 10 | # Get essentials for compiling Unit PHP 11 | RUN apt-get update \ 12 | && apt-get install -y --no-install-recommends build-essential gnupg2 ca-certificates curl zip unzip \ 13 | && echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu jammy main" > /etc/apt/sources.list.d/ondrej-ubuntu-php-jammy.list \ 14 | && apt-get update \ 15 | && apt-get -y --no-install-recommends install php${PHP_VERSION}-embed php${PHP_VERSION}-dev php${PHP_VERSION}-cli 16 | 17 | # Build PHP module for Nginx Unit 18 | RUN curl -O https://unit.nginx.org/download/unit-${UNIT_VERSION}.tar.gz \ 19 | && tar xzf unit-$UNIT_VERSION.tar.gz \ 20 | && cd unit-$UNIT_VERSION \ 21 | && ./configure --prefix=/usr --state=/var/lib/unit --control=unix:/var/run/control.unit.sock \ 22 | --pid=/var/run/unit.pid --log=/var/log/unit.log --tmp=/var/tmp --user=unit --group=unit \ 23 | --tests --modules=/usr/lib/unit/modules --libdir=/usr/lib/x86_64-linux-gnu \ 24 | && ./configure php --module=php --config=php-config${PHP_VERSION} \ 25 | && make php \ 26 | && make install php 27 | 28 | 29 | FROM ubuntu:22.04 30 | 31 | ARG PHP_VERSION='8.2' 32 | 33 | LABEL maintainer="Chris Fidao (fideloper@fly.io)" 34 | 35 | ENV DEBIAN_FRONTEND=noninteractive \ 36 | COMPOSER_ALLOW_SUPERUSER=1 \ 37 | COMPOSER_HOME=/composer \ 38 | COMPOSER_MAX_PARALLEL_HTTP=24 \ 39 | PHP_PM_MAX_CHILDREN=10 \ 40 | PHP_PM_START_SERVERS=3 \ 41 | PHP_MIN_SPARE_SERVERS=2 \ 42 | PHP_MAX_SPARE_SERVERS=4 \ 43 | PHP_DATE_TIMEZONE=UTC \ 44 | PHP_DISPLAY_ERRORS=Off \ 45 | PHP_ERROR_REPORTING=22527 \ 46 | PHP_MEMORY_LIMIT=256M \ 47 | PHP_MAX_EXECUTION_TIME=90 \ 48 | PHP_POST_MAX_SIZE=100M \ 49 | PHP_UPLOAD_MAX_FILE_SIZE=100M \ 50 | PHP_ALLOW_URL_FOPEN=Off 51 | 52 | COPY --from=composer:2 /usr/bin/composer /usr/bin/composer 53 | COPY php/ondrej_ubuntu_php.gpg /etc/apt/trusted.gpg.d/ondrej_ubuntu_php.gpg 54 | ADD php/packages/${PHP_VERSION}.txt /tmp/php-packages.txt 55 | 56 | RUN apt-get update \ 57 | && apt-get install -y --no-install-recommends gnupg2 ca-certificates git-core curl zip unzip \ 58 | rsync vim-tiny htop sqlite3 cron \ 59 | && ln -sf /usr/bin/vim.tiny /etc/alternatives/vim \ 60 | && ln -sf /etc/alternatives/vim /usr/bin/vim \ 61 | && echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu jammy main" > /etc/apt/sources.list.d/ondrej-ubuntu-php-jammy.list \ 62 | && apt-get update \ 63 | && apt-get -y --no-install-recommends install php${PHP_VERSION}-embed $(cat /tmp/php-packages.txt) \ 64 | && mkdir -p /var/www/html/public && echo " /var/www/html/public/index.php \ 65 | && curl --output /usr/share/keyrings/nginx-keyring.gpg https://unit.nginx.org/keys/nginx-keyring.gpg \ 66 | && echo "deb [signed-by=/usr/share/keyrings/nginx-keyring.gpg] https://packages.nginx.org/unit/ubuntu/ jammy unit\ndeb-src [signed-by=/usr/share/keyrings/nginx-keyring.gpg] https://packages.nginx.org/unit/ubuntu/ jammy unit" > /etc/apt/sources.list.d/unit.list \ 67 | && apt-get update \ 68 | && apt-get install -y unit \ 69 | && apt-get clean \ 70 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/* \ 71 | && chown -R unit:unit /var/www/html 72 | 73 | COPY --from=unit-builder /usr/lib/unit/modules/php.unit.so /usr/lib/unit/modules/php.unit.so 74 | COPY unit/conf.json /var/lib/unit/conf.json 75 | COPY entrypoint-unit.sh /entrypoint 76 | 77 | WORKDIR /var/www/html 78 | 79 | ENTRYPOINT ["/entrypoint"] 80 | -------------------------------------------------------------------------------- /src/fpm/pool.d/www.conf: -------------------------------------------------------------------------------- 1 | ; @fly 2 | [global] 3 | ; Avoid logs being sent to syslog 4 | error_log = /proc/self/fd/2 5 | 6 | ; Do not daemonize (eg send process to the background) 7 | daemonize = no 8 | 9 | ; Start a new pool named 'www'. 10 | ; the variable $pool can be used in any directive and will be replaced by the 11 | ; pool name ('www' here) 12 | [www] 13 | 14 | ; Per pool prefix 15 | ; It only applies on the following directives: 16 | ; - 'access.log' 17 | ; - 'slowlog' 18 | ; - 'listen' (unixsocket) 19 | ; - 'chroot' 20 | ; - 'chdir' 21 | ; - 'php_values' 22 | ; - 'php_admin_values' 23 | ; When not set, the global prefix (or /usr) applies instead. 24 | ; Note: This directive can also be relative to the global prefix. 25 | ; Default Value: none 26 | ;prefix = /path/to/pools/$pool 27 | 28 | ; Unix user/group of processes 29 | ; Note: The user is mandatory. If the group is not set, the default user's group 30 | ; will be used. 31 | user = www-data 32 | group = www-data 33 | 34 | ; The address on which to accept FastCGI requests. 35 | ; Valid syntaxes are: 36 | ; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on 37 | ; a specific port; 38 | ; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on 39 | ; a specific port; 40 | ; 'port' - to listen on a TCP socket to all addresses 41 | ; (IPv6 and IPv4-mapped) on a specific port; 42 | ; '/path/to/unix/socket' - to listen on a unix socket. 43 | ; Note: This value is mandatory. 44 | ; @fly 45 | listen = /var/run/php/php-fpm.sock 46 | 47 | ; Set listen(2) backlog. 48 | ; Default Value: 511 (-1 on Linux, FreeBSD and OpenBSD) 49 | ;listen.backlog = 511 50 | 51 | ; Set permissions for unix socket, if one is used. In Linux, read/write 52 | ; permissions must be set in order to allow connections from a web server. Many 53 | ; BSD-derived systems allow connections regardless of permissions. The owner 54 | ; and group can be specified either by name or by their numeric IDs. 55 | ; Default Values: user and group are set as the running user 56 | ; mode is set to 0660 57 | listen.owner = www-data 58 | listen.group = www-data 59 | ;listen.mode = 0660 60 | ; When POSIX Access Control Lists are supported you can set them using 61 | ; these options, value is a comma separated list of user/group names. 62 | ; When set, listen.owner and listen.group are ignored 63 | ;listen.acl_users = 64 | ;listen.acl_groups = 65 | 66 | ; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect. 67 | ; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original 68 | ; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address 69 | ; must be separated by a comma. If this value is left blank, connections will be 70 | ; accepted from any ip address. 71 | ; Default Value: any 72 | ;listen.allowed_clients = 127.0.0.1 73 | 74 | ; Set the associated the route table (FIB). FreeBSD only 75 | ; Default Value: -1 76 | ;listen.setfib = 1 77 | 78 | ; Specify the nice(2) priority to apply to the pool processes (only if set) 79 | ; The value can vary from -19 (highest priority) to 20 (lower priority) 80 | ; Note: - It will only work if the FPM master process is launched as root 81 | ; - The pool processes will inherit the master process priority 82 | ; unless it specified otherwise 83 | ; Default Value: no set 84 | ; process.priority = -19 85 | 86 | ; Set the process dumpable flag (PR_SET_DUMPABLE prctl for Linux or 87 | ; PROC_TRACE_CTL procctl for FreeBSD) even if the process user 88 | ; or group is different than the master process user. It allows to create process 89 | ; core dump and ptrace the process for the pool user. 90 | ; Default Value: no 91 | ; process.dumpable = yes 92 | 93 | ; Choose how the process manager will control the number of child processes. 94 | ; Possible Values: 95 | ; static - a fixed number (pm.max_children) of child processes; 96 | ; dynamic - the number of child processes are set dynamically based on the 97 | ; following directives. With this process management, there will be 98 | ; always at least 1 children. 99 | ; pm.max_children - the maximum number of children that can 100 | ; be alive at the same time. 101 | ; pm.start_servers - the number of children created on startup. 102 | ; pm.min_spare_servers - the minimum number of children in 'idle' 103 | ; state (waiting to process). If the number 104 | ; of 'idle' processes is less than this 105 | ; number then some children will be created. 106 | ; pm.max_spare_servers - the maximum number of children in 'idle' 107 | ; state (waiting to process). If the number 108 | ; of 'idle' processes is greater than this 109 | ; number then some children will be killed. 110 | ; pm.max_spawn_rate - the maximum number of rate to spawn child 111 | ; processes at once. 112 | ; ondemand - no children are created at startup. Children will be forked when 113 | ; new requests will connect. The following parameter are used: 114 | ; pm.max_children - the maximum number of children that 115 | ; can be alive at the same time. 116 | ; pm.process_idle_timeout - The number of seconds after which 117 | ; an idle process will be killed. 118 | ; Note: This value is mandatory. 119 | pm = dynamic 120 | 121 | ; The number of child processes to be created when pm is set to 'static' and the 122 | ; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. 123 | ; This value sets the limit on the number of simultaneous requests that will be 124 | ; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. 125 | ; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP 126 | ; CGI. The below defaults are based on a server without much resources. Don't 127 | ; forget to tweak pm.* to fit your needs. 128 | ; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' 129 | ; Note: This value is mandatory. 130 | ; default: 5 131 | ; @fly 132 | pm.max_children = ${PHP_PM_MAX_CHILDREN} 133 | 134 | ; The number of child processes created on startup. 135 | ; Note: Used only when pm is set to 'dynamic' 136 | ; Default Value: (min_spare_servers + max_spare_servers) / 2 137 | ; default: 2 138 | ; @fly 139 | pm.start_servers = ${PHP_PM_START_SERVERS} 140 | 141 | ; The desired minimum number of idle server processes. 142 | ; Note: Used only when pm is set to 'dynamic' 143 | ; Note: Mandatory when pm is set to 'dynamic' 144 | ; default: 1 145 | ; @fly 146 | pm.min_spare_servers = ${PHP_MIN_SPARE_SERVERS} 147 | 148 | ; The desired maximum number of idle server processes. 149 | ; Note: Used only when pm is set to 'dynamic' 150 | ; Note: Mandatory when pm is set to 'dynamic' 151 | ; default: 3 152 | ; @fly 153 | pm.max_spare_servers = ${PHP_MAX_SPARE_SERVERS} 154 | 155 | ; The number of rate to spawn child processes at once. 156 | ; Note: Used only when pm is set to 'dynamic' 157 | ; Note: Mandatory when pm is set to 'dynamic' 158 | ; Default Value: 32 159 | ;pm.max_spawn_rate = 32 160 | 161 | ; The number of seconds after which an idle process will be killed. 162 | ; Note: Used only when pm is set to 'ondemand' 163 | ; Default Value: 10s 164 | ;pm.process_idle_timeout = 10s; 165 | 166 | ; The number of requests each child process should execute before respawning. 167 | ; This can be useful to work around memory leaks in 3rd party libraries. For 168 | ; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. 169 | ; Default Value: 0 170 | ;pm.max_requests = 500 171 | 172 | ; The URI to view the FPM status page. If this value is not set, no URI will be 173 | ; recognized as a status page. It shows the following information: 174 | ; pool - the name of the pool; 175 | ; process manager - static, dynamic or ondemand; 176 | ; start time - the date and time FPM has started; 177 | ; start since - number of seconds since FPM has started; 178 | ; accepted conn - the number of request accepted by the pool; 179 | ; listen queue - the number of request in the queue of pending 180 | ; connections (see backlog in listen(2)); 181 | ; max listen queue - the maximum number of requests in the queue 182 | ; of pending connections since FPM has started; 183 | ; listen queue len - the size of the socket queue of pending connections; 184 | ; idle processes - the number of idle processes; 185 | ; active processes - the number of active processes; 186 | ; total processes - the number of idle + active processes; 187 | ; max active processes - the maximum number of active processes since FPM 188 | ; has started; 189 | ; max children reached - number of times, the process limit has been reached, 190 | ; when pm tries to start more children (works only for 191 | ; pm 'dynamic' and 'ondemand'); 192 | ; Value are updated in real time. 193 | ; Example output: 194 | ; pool: www 195 | ; process manager: static 196 | ; start time: 01/Jul/2011:17:53:49 +0200 197 | ; start since: 62636 198 | ; accepted conn: 190460 199 | ; listen queue: 0 200 | ; max listen queue: 1 201 | ; listen queue len: 42 202 | ; idle processes: 4 203 | ; active processes: 11 204 | ; total processes: 15 205 | ; max active processes: 12 206 | ; max children reached: 0 207 | ; 208 | ; By default the status page output is formatted as text/plain. Passing either 209 | ; 'html', 'xml' or 'json' in the query string will return the corresponding 210 | ; output syntax. Example: 211 | ; http://www.foo.bar/status 212 | ; http://www.foo.bar/status?json 213 | ; http://www.foo.bar/status?html 214 | ; http://www.foo.bar/status?xml 215 | ; 216 | ; By default the status page only outputs short status. Passing 'full' in the 217 | ; query string will also return status for each pool process. 218 | ; Example: 219 | ; http://www.foo.bar/status?full 220 | ; http://www.foo.bar/status?json&full 221 | ; http://www.foo.bar/status?html&full 222 | ; http://www.foo.bar/status?xml&full 223 | ; The Full status returns for each process: 224 | ; pid - the PID of the process; 225 | ; state - the state of the process (Idle, Running, ...); 226 | ; start time - the date and time the process has started; 227 | ; start since - the number of seconds since the process has started; 228 | ; requests - the number of requests the process has served; 229 | ; request duration - the duration in µs of the requests; 230 | ; request method - the request method (GET, POST, ...); 231 | ; request URI - the request URI with the query string; 232 | ; content length - the content length of the request (only with POST); 233 | ; user - the user (PHP_AUTH_USER) (or '-' if not set); 234 | ; script - the main script called (or '-' if not set); 235 | ; last request cpu - the %cpu the last request consumed 236 | ; it's always 0 if the process is not in Idle state 237 | ; because CPU calculation is done when the request 238 | ; processing has terminated; 239 | ; last request memory - the max amount of memory the last request consumed 240 | ; it's always 0 if the process is not in Idle state 241 | ; because memory calculation is done when the request 242 | ; processing has terminated; 243 | ; If the process is in Idle state, then informations are related to the 244 | ; last request the process has served. Otherwise informations are related to 245 | ; the current request being served. 246 | ; Example output: 247 | ; ************************ 248 | ; pid: 31330 249 | ; state: Running 250 | ; start time: 01/Jul/2011:17:53:49 +0200 251 | ; start since: 63087 252 | ; requests: 12808 253 | ; request duration: 1250261 254 | ; request method: GET 255 | ; request URI: /test_mem.php?N=10000 256 | ; content length: 0 257 | ; user: - 258 | ; script: /home/fat/web/docs/php/test_mem.php 259 | ; last request cpu: 0.00 260 | ; last request memory: 0 261 | ; 262 | ; Note: There is a real-time FPM status monitoring sample web page available 263 | ; It's available in: /usr/share/php/8.2/fpm/status.html 264 | ; 265 | ; Note: The value must start with a leading slash (/). The value can be 266 | ; anything, but it may not be a good idea to use the .php extension or it 267 | ; may conflict with a real PHP file. 268 | ; Default Value: not set 269 | ;pm.status_path = /status 270 | 271 | ; The address on which to accept FastCGI status request. This creates a new 272 | ; invisible pool that can handle requests independently. This is useful 273 | ; if the main pool is busy with long running requests because it is still possible 274 | ; to get the status before finishing the long running requests. 275 | ; 276 | ; Valid syntaxes are: 277 | ; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on 278 | ; a specific port; 279 | ; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on 280 | ; a specific port; 281 | ; 'port' - to listen on a TCP socket to all addresses 282 | ; (IPv6 and IPv4-mapped) on a specific port; 283 | ; '/path/to/unix/socket' - to listen on a unix socket. 284 | ; Default Value: value of the listen option 285 | ;pm.status_listen = 127.0.0.1:9001 286 | 287 | ; The ping URI to call the monitoring page of FPM. If this value is not set, no 288 | ; URI will be recognized as a ping page. This could be used to test from outside 289 | ; that FPM is alive and responding, or to 290 | ; - create a graph of FPM availability (rrd or such); 291 | ; - remove a server from a group if it is not responding (load balancing); 292 | ; - trigger alerts for the operating team (24/7). 293 | ; Note: The value must start with a leading slash (/). The value can be 294 | ; anything, but it may not be a good idea to use the .php extension or it 295 | ; may conflict with a real PHP file. 296 | ; Default Value: not set 297 | ;ping.path = /ping 298 | 299 | ; This directive may be used to customize the response of a ping request. The 300 | ; response is formatted as text/plain with a 200 response code. 301 | ; Default Value: pong 302 | ;ping.response = pong 303 | 304 | ; The access log file 305 | ; Default: not set 306 | ; @fly 307 | access.log = /proc/self/fd/1 308 | 309 | ; The access log format. 310 | ; The following syntax is allowed 311 | ; %%: the '%' character 312 | ; %C: %CPU used by the request 313 | ; it can accept the following format: 314 | ; - %{user}C for user CPU only 315 | ; - %{system}C for system CPU only 316 | ; - %{total}C for user + system CPU (default) 317 | ; %d: time taken to serve the request 318 | ; it can accept the following format: 319 | ; - %{seconds}d (default) 320 | ; - %{milliseconds}d 321 | ; - %{milli}d 322 | ; - %{microseconds}d 323 | ; - %{micro}d 324 | ; %e: an environment variable (same as $_ENV or $_SERVER) 325 | ; it must be associated with embraces to specify the name of the env 326 | ; variable. Some examples: 327 | ; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e 328 | ; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e 329 | ; %f: script filename 330 | ; %l: content-length of the request (for POST request only) 331 | ; %m: request method 332 | ; %M: peak of memory allocated by PHP 333 | ; it can accept the following format: 334 | ; - %{bytes}M (default) 335 | ; - %{kilobytes}M 336 | ; - %{kilo}M 337 | ; - %{megabytes}M 338 | ; - %{mega}M 339 | ; %n: pool name 340 | ; %o: output header 341 | ; it must be associated with embraces to specify the name of the header: 342 | ; - %{Content-Type}o 343 | ; - %{X-Powered-By}o 344 | ; - %{Transfert-Encoding}o 345 | ; - .... 346 | ; %p: PID of the child that serviced the request 347 | ; %P: PID of the parent of the child that serviced the request 348 | ; %q: the query string 349 | ; %Q: the '?' character if query string exists 350 | ; %r: the request URI (without the query string, see %q and %Q) 351 | ; %R: remote IP address 352 | ; %s: status (response code) 353 | ; %t: server time the request was received 354 | ; it can accept a strftime(3) format: 355 | ; %d/%b/%Y:%H:%M:%S %z (default) 356 | ; The strftime(3) format must be encapsulated in a %{}t tag 357 | ; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t 358 | ; %T: time the log has been written (the request has finished) 359 | ; it can accept a strftime(3) format: 360 | ; %d/%b/%Y:%H:%M:%S %z (default) 361 | ; The strftime(3) format must be encapsulated in a %{}t tag 362 | ; e.g. for a ISO8601 formatted timestring, use: %{%Y-%m-%dT%H:%M:%S%z}t 363 | ; %u: remote user 364 | ; 365 | ; Default: "%R - %u %t \"%m %r\" %s" 366 | ;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{milli}d %{kilo}M %C%%" 367 | 368 | ; A list of request_uri values which should be filtered from the access log. 369 | ; 370 | ; As a security precuation, this setting will be ignored if: 371 | ; - the request method is not GET or HEAD; or 372 | ; - there is a request body; or 373 | ; - there are query parameters; or 374 | ; - the response code is outwith the successful range of 200 to 299 375 | ; 376 | ; Note: The paths are matched against the output of the access.format tag "%r". 377 | ; On common configurations, this may look more like SCRIPT_NAME than the 378 | ; expected pre-rewrite URI. 379 | ; 380 | ; Default Value: not set 381 | ;access.suppress_path[] = /ping 382 | ;access.suppress_path[] = /health_check.php 383 | 384 | ; The log file for slow requests 385 | ; Default Value: not set 386 | ; Note: slowlog is mandatory if request_slowlog_timeout is set 387 | ;slowlog = log/$pool.log.slow 388 | 389 | ; The timeout for serving a single request after which a PHP backtrace will be 390 | ; dumped to the 'slowlog' file. A value of '0s' means 'off'. 391 | ; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) 392 | ; Default Value: 0 393 | ;request_slowlog_timeout = 0 394 | 395 | ; Depth of slow log stack trace. 396 | ; Default Value: 20 397 | ;request_slowlog_trace_depth = 20 398 | 399 | ; The timeout for serving a single request after which the worker process will 400 | ; be killed. This option should be used when the 'max_execution_time' ini option 401 | ; does not stop script execution for some reason. A value of '0' means 'off'. 402 | ; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) 403 | ; Default Value: 0 404 | ;request_terminate_timeout = 0 405 | 406 | ; The timeout set by 'request_terminate_timeout' ini option is not engaged after 407 | ; application calls 'fastcgi_finish_request' or when application has finished and 408 | ; shutdown functions are being called (registered via register_shutdown_function). 409 | ; This option will enable timeout limit to be applied unconditionally 410 | ; even in such cases. 411 | ; Default Value: no 412 | ;request_terminate_timeout_track_finished = no 413 | 414 | ; Set open file descriptor rlimit. 415 | ; Default Value: system defined value 416 | ;rlimit_files = 1024 417 | 418 | ; Set max core size rlimit. 419 | ; Possible Values: 'unlimited' or an integer greater or equal to 0 420 | ; Default Value: system defined value 421 | ;rlimit_core = 0 422 | 423 | ; Chroot to this directory at the start. This value must be defined as an 424 | ; absolute path. When this value is not set, chroot is not used. 425 | ; Note: you can prefix with '$prefix' to chroot to the pool prefix or one 426 | ; of its subdirectories. If the pool prefix is not set, the global prefix 427 | ; will be used instead. 428 | ; Note: chrooting is a great security feature and should be used whenever 429 | ; possible. However, all PHP paths will be relative to the chroot 430 | ; (error_log, sessions.save_path, ...). 431 | ; Default Value: not set 432 | ;chroot = 433 | 434 | ; Chdir to this directory at the start. 435 | ; Note: relative path can be used. 436 | ; Default Value: current directory or / when chroot 437 | ;chdir = /var/www 438 | 439 | ; Redirect worker stdout and stderr into main error log. If not set, stdout and 440 | ; stderr will be redirected to /dev/null according to FastCGI specs. 441 | ; Note: on highloaded environment, this can cause some delay in the page 442 | ; process time (several ms). 443 | ; Default Value: no 444 | ; @fly 445 | catch_workers_output = yes 446 | 447 | ; Decorate worker output with prefix and suffix containing information about 448 | ; the child that writes to the log and if stdout or stderr is used as well as 449 | ; log level and time. This options is used only if catch_workers_output is yes. 450 | ; Settings to "no" will output data as written to the stdout or stderr. 451 | ; Default value: yes 452 | ; @fly 453 | decorate_workers_output = no 454 | 455 | ; Clear environment in FPM workers 456 | ; Prevents arbitrary environment variables from reaching FPM worker processes 457 | ; by clearing the environment in workers before env vars specified in this 458 | ; pool configuration are added. 459 | ; Setting to "no" will make all environment variables available to PHP code 460 | ; via getenv(), $_ENV and $_SERVER. 461 | ; Default Value: yes 462 | ; @fly 463 | clear_env = no 464 | 465 | ; Limits the extensions of the main script FPM will allow to parse. This can 466 | ; prevent configuration mistakes on the web server side. You should only limit 467 | ; FPM to .php extensions to prevent malicious users to use other extensions to 468 | ; execute php code. 469 | ; Note: set an empty value to allow all extensions. 470 | ; Default Value: .php 471 | ;security.limit_extensions = .php .php3 .php4 .php5 .php7 472 | 473 | ; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from 474 | ; the current environment. 475 | ; Default Value: clean env 476 | ;env[HOSTNAME] = $HOSTNAME 477 | ;env[PATH] = /usr/local/bin:/usr/bin:/bin 478 | ;env[TMP] = /tmp 479 | ;env[TMPDIR] = /tmp 480 | ;env[TEMP] = /tmp 481 | 482 | ; Additional php.ini defines, specific to this pool of workers. These settings 483 | ; overwrite the values previously defined in the php.ini. The directives are the 484 | ; same as the PHP SAPI: 485 | ; php_value/php_flag - you can set classic ini defines which can 486 | ; be overwritten from PHP call 'ini_set'. 487 | ; php_admin_value/php_admin_flag - these directives won't be overwritten by 488 | ; PHP call 'ini_set' 489 | ; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no. 490 | 491 | ; Defining 'extension' will load the corresponding shared extension from 492 | ; extension_dir. Defining 'disable_functions' or 'disable_classes' will not 493 | ; overwrite previously defined php.ini values, but will append the new value 494 | ; instead. 495 | 496 | ; Note: path INI options can be relative and will be expanded with the prefix 497 | ; (pool, global or /usr) 498 | 499 | ; Default Value: nothing is defined by default except the values in php.ini and 500 | ; specified at startup with the -d argument 501 | ;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com 502 | ;php_flag[display_errors] = off 503 | ;php_admin_value[error_log] = /var/log/fpm-php.www.log 504 | ;php_admin_flag[log_errors] = on 505 | ;php_admin_value[memory_limit] = 32M 506 | 507 | ; @fly settings: 508 | ; Security measures 509 | php_admin_value[open_basedir] = /var/www/html:/dev/stdout:/tmp 510 | php_admin_flag[session.cookie_secure] = true 511 | 512 | ; Regional settings 513 | php_value[date.timezone] = ${PHP_DATE_TIMEZONE} 514 | 515 | ; Error reporting settings 516 | php_admin_value[display_errors] = ${PHP_DISPLAY_ERRORS} 517 | php_admin_value[error_reporting] = ${PHP_ERROR_REPORTING} 518 | 519 | ; Performance settings 520 | php_admin_value[memory_limit] = ${PHP_MEMORY_LIMIT} 521 | php_admin_value[max_execution_time] = ${PHP_MAX_EXECUTION_TIME} 522 | 523 | ; Upload settings 524 | php_admin_value[post_max_size] = ${PHP_POST_MAX_SIZE} 525 | php_admin_value[upload_max_filesize] = ${PHP_UPLOAD_MAX_FILE_SIZE} 526 | 527 | ; Allow remote file access settings 528 | php_admin_value[allow_url_fopen] = ${PHP_ALLOW_URL_FOPEN} --------------------------------------------------------------------------------