FROM alpine:3.19 AS baseimage # Install PHP+Friends RUN </dev/null|#rm -rf /etc/service 2>/dev/null|g' /etc/runit/init.d/001-prepare EOF # Add workdir /app WORKDIR /app RUN <> /etc/nginx/nginx.conf mkdir -p /etc/service.d/nginx cat << EOF > /etc/service.d/nginx/run #!/bin/sh /usr/sbin/nginx EOF cat << EOF > /etc/nginx/nginx.conf # Set number of worker processes automatically based on number of CPU cores. worker_processes auto; # Enables the use of JIT for regular expressions to speed-up their processing. pcre_jit on; # Configures default error logger. error_log /app/logs/nginx_error.log warn; # Includes files with directives to load dynamic modules. include /etc/nginx/modules/*.conf; # Include files with config snippets into the root context. include /etc/nginx/conf.d/*.conf; events { # The maximum number of simultaneous connections that can be opened by a worker process. worker_connections 1024; } http { include /etc/nginx/mime.types; # Includes mapping of file name extensions to MIME types of responses and defines the default type. default_type application/octet-stream; server_tokens off; # Don't tell nginx version to the clients. Default is 'on'. # Specifies the maximum accepted body size of a client request, as indicated by the request header Content-Length. If the stated content # length is greater than this size, then the client receives the HTTP error code 413. Set to 0 to disable. client_max_body_size 0; # Default is '1m'. sendfile on; # Sendfile copies data between one FD and other from within the kernel, which is more efficient than read() + write(). tcp_nopush on; # Causes nginx to attempt to send its HTTP response head in one packet, instead of using partial frames. Default is 'off'. gzip on; # Enable gzipping of responses. gzip_vary on; # Set the Vary HTTP header as defined in the RFC 2616. Default is 'off'. map \$http_upgrade \$connection_upgrade { # Helper variable for proxying websockets. default upgrade; '' close; } # Specifies the main log format. log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" ' '\$status \$body_bytes_sent "\$http_referer" ' '"\$http_user_agent" "\$http_x_forwarded_for"'; access_log /app/logs/nginx_access.log main; # Sets the path, format, and configuration for a buffered log write. include /etc/nginx/http.d/*.conf; # Includes virtual hosts configs. include /app/*.nginx; # Include project specific configuration. } daemon off; EOF cat << EOF > /etc/nginx/http.d/default.conf server { listen 80 default_server; listen [::]:80 default_server; client_max_body_size 1024M; root /app/public; server_name _; index index.html index.php index.htm; location / { # First attempt to serve request as file, then as directory, then fall back to displaying a 404. try_files \$uri \$uri/ /index.php?\$args; } location ~ \.php$ { try_files \$uri \$uri/ /index.php?\$args; fastcgi_pass unix:/run/php-fpm/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name; fastcgi_read_timeout 300; include fastcgi_params; fastcgi_buffers 16 16k; fastcgi_buffer_size 32k; } location ~ /\.ht { deny all; } } EOF cat << EOF > /etc/service.d/nginx/run #!/usr/bin/env bash set -ue /usr/sbin/nginx EOF touch /etc/service.d/nginx/enable # Configure PHP-FPM mkdir -p /etc/service.d/php touch /etc/php83/conf.d/env.conf chmod a+rw /etc/php83/conf.d/env.conf cat << EOF > /etc/service.d/php/run #!/usr/bin/env bash set -ue echo "Parsing environment" printenv | sort echo "Exporting environment" env | sed "s/\(.*\)=\(.*\)/env[\1]='\2'/" env | sed "s/\(.*\)=\(.*\)/env[\1]='\2'/" > /etc/php83/conf.d/env.conf echo "Starting PHP-FPM" /usr/bin/php-fpm -F EOF cat << EOF > /etc/php83/php-fpm.conf [global] pid = /run/php-fpm/php-fpm.pid error_log = /app/logs/php_error.log process.max = 128 ; Default Value: 0 daemonize = no include=/etc/php83/php-fpm.d/*.conf EOF cat << EOF > /etc/php83/php-fpm.d/www.conf [www] ;user = php # Not running as root, so this does nothing. ;group = php listen = /run/php-fpm/php-fpm.sock listen.backlog = -1 listen.owner = php listen.group = php listen.mode = 0660 pm = dynamic pm.max_children = 128 ; Maximum workers pm.start_servers = 4 ; How many nodes to start pm.min_spare_servers = 2 ; Minimum hotspares pm.max_spare_servers = 5 ; Maximum acceptable spares pm.max_spawn_rate = 32 ; Maximum velocity to spawn more nodes pm.process_idle_timeout = 10s ; How long a server may remind idle before culling pm.max_requests = 500 ; How many requests to serve to let run before culling access.log = /app/logs/php_access.log ;slowlog = /app/logs/php_slow_requests.log ;request_slowlog_timeout = 5s ;request_slowlog_trace_depth = 20 ;chdir = /app/public clear_env = no EOF cat << EOF > /etc/php83/php.ini [PHP] short_open_tag = Off implicit_flush = Off serialize_precision = -1 zend.enable_gc = On zend.exception_ignore_args = On zend.exception_string_param_max_len = 0 expose_php = Off max_execution_time = 10 max_input_time = 60 memory_limit = 128M error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT display_errors = On display_startup_errors = On log_errors = On ignore_repeated_errors = Off ignore_repeated_source = Off report_memleaks = On variables_order = "GPCS" request_order = "GP" register_argc_argv = Off auto_globals_jit = On post_max_size = 128M default_mimetype = "text/html" default_charset = "UTF-8" include_path = ".:/usr/share/php83" enable_dl = Off file_uploads = On upload_max_filesize = 32M max_file_uploads = 20 allow_url_fopen = On allow_url_include = Off default_socket_timeout = 60 [CLI Server] cli_server.color = On [Session] session.save_handler = files session.use_strict_mode = 0 session.use_cookies = 1 session.use_only_cookies = 1 session.name = SESSION session.auto_start = 0 session.cookie_lifetime = 0 session.cookie_path = / session.serialize_handler = php session.gc_probability = 1 session.gc_divisor = 1000 session.gc_maxlifetime = 1440 session.cache_limiter = nocache session.cache_expire = 180 session.use_trans_sid = 0 session.trans_sid_tags = "a=href,area=href,frame=src,form=" session.sid_bits_per_character = 5 [Assertion] zend.assertions = -1 EOF touch /etc/service.d/php/enable # Tail the logs mkdir -p /etc/service.d/log-tail cat << EOF > /etc/service.d/log-tail/run #!/usr/bin/env bash set -ue # For all the logs in /app/logs/*.log, empty them for log in /app/logs/*.log; do echo -n > "\$log" done # Tail all the logs tail -f /app/logs/php_access.log & tail -f /app/logs/php_error.log & tail -f /app/logs/nginx_access.log & tail -f /app/logs/nginx_error.log EOF touch /etc/service.d/log-tail/enable # Fix ownership mkdir -p \ /var/log/nginx \ /run/php-fpm chown php:php -R \ /etc/runit \ /etc/service /etc/service.d \ /var/lib/nginx /var/log/nginx /run/nginx \ /var/log/php83 /run/php-fpm \ /app RUN # Use that new php user USER php # Configure SSH to trust github.com RUN <> ~/.ssh/known_hosts RUN # We expect composer.json & composer.lock to exist in the app ONBUILD USER root ONBUILD COPY ./composer.* /app ONBUILD COPY *vendor /app/vendor ONBUILD RUN chown -R php:php /app ONBUILD USER php ONBUILD RUN composer install # We expect /public to exist in the app ONBUILD COPY ./public /app/public # Copy everything else. ONBUILD COPY . /app ONBUILD RUN mkdir -p /app/logs ENV PATH="/app/bin:/app/vendor/bin:${PATH}" \ COMPOSER_FUND=0 FROM baseimage AS bucket-serve