├── .gitignore ├── Dockerfile ├── docker ├── fpm-pool.conf ├── nginx.conf ├── php.ini └── supervisord.conf └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.13 2 | 3 | # Install packages and remove default server definition 4 | RUN apk --no-cache add \ 5 | curl \ 6 | nginx \ 7 | php8 \ 8 | php8-ctype \ 9 | php8-curl \ 10 | php8-dom \ 11 | php8-fpm \ 12 | php8-gd \ 13 | php8-intl \ 14 | php8-json \ 15 | php8-mbstring \ 16 | php8-mysqli \ 17 | php8-opcache \ 18 | php8-openssl \ 19 | php8-phar \ 20 | php8-session \ 21 | php8-xml \ 22 | php8-tokenizer \ 23 | php8-xmlreader \ 24 | php8-zlib \ 25 | supervisor \ 26 | && rm /etc/nginx/conf.d/default.conf 27 | 28 | # Create symlink so programs depending on `php` still function 29 | RUN ln -s /usr/bin/php8 /usr/bin/php 30 | 31 | # Configure nginx 32 | COPY docker/nginx.conf /etc/nginx/nginx.conf 33 | 34 | # Configure PHP-FPM 35 | COPY docker/fpm-pool.conf /etc/php8/php-fpm.d/www.conf 36 | COPY docker/php.ini /etc/php8/conf.d/custom.ini 37 | 38 | # Configure supervisord 39 | COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf 40 | 41 | # Setup document root 42 | RUN mkdir -p /var/www/html 43 | 44 | # Make sure files/folders needed by the processes are accessable when they run under the nobody user 45 | RUN chown -R nobody.nobody /var/www/html && \ 46 | chown -R nobody.nobody /run && \ 47 | chown -R nobody.nobody /var/lib/nginx && \ 48 | chown -R nobody.nobody /var/log/nginx 49 | 50 | # Switch to use a non-root user from here on 51 | USER nobody 52 | 53 | # Add application 54 | WORKDIR /var/www/html 55 | COPY --chown=nobody . /var/www/html/ 56 | 57 | # Expose the port nginx is reachable on 58 | EXPOSE 8080 59 | 60 | # Let supervisord start nginx & php-fpm 61 | CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] 62 | 63 | # Configure a healthcheck to validate that everything is up&running 64 | HEALTHCHECK --timeout=10s CMD curl --silent --fail http://127.0.0.1:8080/fpm-ping 65 | -------------------------------------------------------------------------------- /docker/fpm-pool.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | ; Log to stderr 3 | error_log = /dev/stderr 4 | 5 | [www] 6 | ; The address on which to accept FastCGI requests. 7 | ; Valid syntaxes are: 8 | ; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on 9 | ; a specific port; 10 | ; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on 11 | ; a specific port; 12 | ; 'port' - to listen on a TCP socket to all addresses 13 | ; (IPv6 and IPv4-mapped) on a specific port; 14 | ; '/path/to/unix/socket' - to listen on a unix socket. 15 | ; Note: This value is mandatory. 16 | listen = 127.0.0.1:9000 17 | 18 | ; Enable status page 19 | pm.status_path = /fpm-status 20 | 21 | ; Ondemand process manager 22 | pm = ondemand 23 | 24 | ; The number of child processes to be created when pm is set to 'static' and the 25 | ; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. 26 | ; This value sets the limit on the number of simultaneous requests that will be 27 | ; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. 28 | ; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP 29 | ; CGI. The below defaults are based on a server without much resources. Don't 30 | ; forget to tweak pm.* to fit your needs. 31 | ; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' 32 | ; Note: This value is mandatory. 33 | pm.max_children = 100 34 | 35 | ; The number of seconds after which an idle process will be killed. 36 | ; Note: Used only when pm is set to 'ondemand' 37 | ; Default Value: 10s 38 | pm.process_idle_timeout = 10s; 39 | 40 | ; The number of requests each child process should execute before respawning. 41 | ; This can be useful to work around memory leaks in 3rd party libraries. For 42 | ; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. 43 | ; Default Value: 0 44 | pm.max_requests = 1000 45 | 46 | ; Make sure the FPM workers can reach the environment variables for configuration 47 | clear_env = no 48 | 49 | ; Catch output from PHP 50 | catch_workers_output = yes 51 | 52 | ; Remove the 'child 10 said into stderr' prefix in the log and only show the actual message 53 | decorate_workers_output = no 54 | 55 | ; Enable ping page to use in healthcheck 56 | ping.path = /fpm-ping 57 | -------------------------------------------------------------------------------- /docker/nginx.conf: -------------------------------------------------------------------------------- 1 | worker_processes auto; 2 | error_log stderr warn; 3 | pid /run/nginx.pid; 4 | 5 | events { 6 | worker_connections 1024; 7 | } 8 | 9 | http { 10 | include mime.types; 11 | default_type application/octet-stream; 12 | 13 | # Define custom log format to include reponse times 14 | log_format main_timed '$remote_addr - $remote_user [$time_local] "$request" ' 15 | '$status $body_bytes_sent "$http_referer" ' 16 | '"$http_user_agent" "$http_x_forwarded_for" ' 17 | '$request_time $upstream_response_time $pipe $upstream_cache_status'; 18 | 19 | access_log /dev/stdout main_timed; 20 | error_log /dev/stderr notice; 21 | 22 | keepalive_timeout 65; 23 | 24 | # Write temporary files to /tmp so they can be created as a non-privileged user 25 | client_body_temp_path /tmp/client_temp; 26 | proxy_temp_path /tmp/proxy_temp_path; 27 | fastcgi_temp_path /tmp/fastcgi_temp; 28 | uwsgi_temp_path /tmp/uwsgi_temp; 29 | scgi_temp_path /tmp/scgi_temp; 30 | 31 | # Default server definition 32 | server { 33 | listen [::]:8080 default_server; 34 | listen 8080 default_server; 35 | server_name _; 36 | 37 | sendfile off; 38 | 39 | root /var/www/html/public; 40 | index index.php index.html; 41 | 42 | location / { 43 | # First attempt to serve request as file, then 44 | # as directory, then fall back to index.php 45 | try_files $uri $uri/ /index.php?q=$uri&$args; 46 | } 47 | 48 | # Redirect server error pages to the static page /50x.html 49 | error_page 500 502 503 504 /50x.html; 50 | location = /50x.html { 51 | root /var/lib/nginx/html; 52 | } 53 | 54 | # Pass the PHP scripts to PHP-FPM listening on 127.0.0.1:9000 55 | location ~ \.php$ { 56 | try_files $uri =404; 57 | fastcgi_split_path_info ^(.+\.php)(/.+)$; 58 | fastcgi_pass 127.0.0.1:9000; 59 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 60 | fastcgi_param SCRIPT_NAME $fastcgi_script_name; 61 | fastcgi_index index.php; 62 | include fastcgi_params; 63 | } 64 | 65 | location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ { 66 | expires 5d; 67 | } 68 | 69 | # Deny access to . files, for security 70 | location ~ /\. { 71 | log_not_found off; 72 | deny all; 73 | } 74 | 75 | # Allow fpm ping and status from localhost 76 | location ~ ^/(fpm-status|fpm-ping)$ { 77 | access_log off; 78 | allow 127.0.0.1; 79 | deny all; 80 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 81 | include fastcgi_params; 82 | fastcgi_pass 127.0.0.1:9000; 83 | } 84 | } 85 | 86 | gzip on; 87 | gzip_proxied any; 88 | gzip_types text/plain application/xml text/css text/js text/xml application/x-javascript text/javascript application/json application/xml+rss; 89 | gzip_vary on; 90 | gzip_disable "msie6"; 91 | 92 | # Include other server configs 93 | include /etc/nginx/conf.d/*.conf; 94 | } 95 | -------------------------------------------------------------------------------- /docker/php.ini: -------------------------------------------------------------------------------- 1 | [Date] 2 | date.timezone="UTC" 3 | -------------------------------------------------------------------------------- /docker/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | logfile=/dev/null 4 | logfile_maxbytes=0 5 | pidfile=/run/supervisord.pid 6 | 7 | [program:php-fpm] 8 | command=php-fpm8 -F 9 | stdout_logfile=/dev/stdout 10 | stdout_logfile_maxbytes=0 11 | stderr_logfile=/dev/stderr 12 | stderr_logfile_maxbytes=0 13 | autorestart=false 14 | startretries=0 15 | 16 | [program:nginx] 17 | command=nginx -g 'daemon off;' 18 | stdout_logfile=/dev/stdout 19 | stdout_logfile_maxbytes=0 20 | stderr_logfile=/dev/stderr 21 | stderr_logfile_maxbytes=0 22 | autorestart=false 23 | startretries=0 24 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ### Laravel Docker Container (Production) 2 | 3 | Mostly taken from [TrafeX/docker-php-nginx](https://github.com/TrafeX/docker-php-nginx); with very small modifications to nginx & config paths. It also adds tokenizer support. --------------------------------------------------------------------------------