diff --git a/bin/docker-compose b/bin/docker-compose index 0ef1811..a3f260c 100755 --- a/bin/docker-compose +++ b/bin/docker-compose @@ -61,4 +61,3 @@ if [[ "$PWD" == *"docker-stack"* || "$PWD" == *"htdocs"* ]]; then else ${REAL_DOCKER_COMPOSE_CMD} ${BASH_ARGVS[*]}; fi - diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile index 93a94b1..a625170 100644 --- a/docker/nginx/Dockerfile +++ b/docker/nginx/Dockerfile @@ -8,9 +8,9 @@ RUN usermod -u $USERID nginx RUN groupmod -o -g $GROUPID nginx ADD nginx.conf /etc/nginx/nginx.conf -ADD default.conf /etc/nginx/conf.d/default.conf +ADD default-dev.conf /etc/nginx/conf.d/default.conf ADD m-hosts.conf /etc/nginx/conf.d/z-m-hosts.conf -ADD m-servers.conf /etc/nginx/conf.d/z-m-servers.conf +ADD m-servers-dev.conf /etc/nginx/conf.d/z-m-servers.conf ADD m-certs.conf /etc/nginx/conf.d/z-m-certs.conf # SSL diff --git a/docker/nginx/Dockerfile-prod b/docker/nginx/Dockerfile-prod new file mode 100644 index 0000000..6485365 --- /dev/null +++ b/docker/nginx/Dockerfile-prod @@ -0,0 +1,22 @@ +FROM nginx:1.25 +ARG USERID=1000 +ARG GROUPID=1000 +RUN groupmod -g 999 dialout + +# fix www-data user to avoid permissions issues +RUN usermod -u $USERID nginx +RUN groupmod -o -g $GROUPID nginx + +ADD nginx.conf /etc/nginx/nginx.conf +ADD default-prod.conf /etc/nginx/conf.d/default.conf +ADD m-hosts.conf /etc/nginx/conf.d/z-m-hosts.conf +ADD m-servers-prod.conf /etc/nginx/conf.d/z-m-servers.conf +ADD m-certs.conf /etc/nginx/conf.d/z-m-certs.conf + +# SSL +ADD certs/* /etc/ssl/certs/ +ADD certs/* /etc/ssl/private/ +RUN whoami +RUN chown -R -f nginx: /etc/ssl /var/cache/nginx /var/log/nginx /var/run /var/run/* + +EXPOSE 443 diff --git a/docker/nginx/default-dev.conf b/docker/nginx/default-dev.conf new file mode 100644 index 0000000..06e56bb --- /dev/null +++ b/docker/nginx/default-dev.conf @@ -0,0 +1,36 @@ +server { + listen 80; + server_name _; + + access_log /var/log/nginx/default.access.log main; + + location / { + root /var/www/htdocs/; + index index.html index.htm index.php; + } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + # pass the PHP scripts to FastCGI server + # + location ~ \.php$ { + set $php_host ${PHP_HOSTM2}; + fastcgi_pass ${php_host}:9000; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; + include fastcgi_params; + } + + # deny access to .htaccess files, if Apache's document root + location ~ /\.ht { + deny all; + } +} + diff --git a/docker/nginx/default-prod.conf b/docker/nginx/default-prod.conf new file mode 100644 index 0000000..65afbb2 --- /dev/null +++ b/docker/nginx/default-prod.conf @@ -0,0 +1,36 @@ +server { + listen 8080; + server_name _; + + access_log /var/log/nginx/default.access.log main; + + location / { + root /var/www/htdocs/; + index index.html index.htm index.php; + } + + #error_page 404 /404.html; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + + # pass the PHP scripts to FastCGI server + # + location ~ \.php$ { + set $php_host ${PHP_HOSTM2}; + fastcgi_pass ${php_host}:9000; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; + include fastcgi_params; + } + + # deny access to .htaccess files, if Apache's document root + location ~ /\.ht { + deny all; + } +} + diff --git a/docker/nginx/default.conf b/docker/nginx/default.conf index 06e56bb..65afbb2 100644 --- a/docker/nginx/default.conf +++ b/docker/nginx/default.conf @@ -1,5 +1,5 @@ server { - listen 80; + listen 8080; server_name _; access_log /var/log/nginx/default.access.log main; diff --git a/docker/nginx/m-servers-dev.conf b/docker/nginx/m-servers-dev.conf new file mode 100644 index 0000000..a89178b --- /dev/null +++ b/docker/nginx/m-servers-dev.conf @@ -0,0 +1,344 @@ +########################### +## DO NOT EDIT THIS FILE ## +########################### + +# Magento 2 focused PHP hosts +server { + listen 80; + listen 443 ssl; + http2 on; + # Docker DNS reolver is .11, NOT A MISTAKE + resolver 127.0.0.11 ipv6=off; + + server_name ~^.*\.(loc|local|localhost)$; + ssl_certificate $SSL_CERT; + ssl_certificate_key $SSL_KEY; + + error_log /dev/stdout; + access_log /dev/stdout; + + # Magento Vars + set $MAGE_MODE developer; # or production or developer + + root /var/www/htdocs/${http_host}${root_subfolder}; + + index index.php; + autoindex off; + charset off; + client_max_body_size 20M; + + add_header 'X-Content-Type-Options' 'nosniff'; + add_header 'X-XSS-Protection' '1; mode=block'; + + location /setup { + root /var/www/htdocs/${http_host}/; + location ~ ^/setup/index.php { + set $php_host ${PHP_HOSTM2}; +# fastcgi_pass ${PHP_HOSTM2}:9000; + fastcgi_pass unix:/tmp/${php_host}-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + + location ~ ^/setup/(?!pub/). { + deny all; + } + + location ~ ^/setup/pub/ { + add_header X-Frame-Options "SAMEORIGIN"; + } + } + + location /update { + root /var/www/htdocs/${http_host}/; + + location ~ ^/update/index.php { + fastcgi_split_path_info ^(/update/index.php)(/.+)$; + set $php_host ${PHP_HOSTM2}; +# fastcgi_pass ${PHP_HOSTM2}:9000; + fastcgi_pass unix:/tmp/${php_host}-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + include fastcgi_params; + } + + # deny everything but index.php + location ~ ^/update/(?!pub/). { + deny all; + } + + location ~ ^/update/pub/ { + add_header X-Frame-Options "SAMEORIGIN"; + } + } + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location /pub { + location ~ ^/pub/media/(downloadable|customer|import|theme_customization/.*\.xml) { + deny all; + } + alias /var/www/htdocs/${http_host}/pub; + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /static/ { + if ($MAGE_MODE = "production") { + expires max; + } + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ { + add_header Cache-Control "public"; + add_header X-Frame-Options "SAMEORIGIN"; + expires +1y; + + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + } + location ~* \.(zip|gz|gzip|bz2|csv|xml)$ { + add_header Cache-Control "no-store"; + add_header X-Frame-Options "SAMEORIGIN"; + expires off; + + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + } + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /media/ { + try_files $uri $uri/ =404; + + location ~ ^/media/theme_customization/.*\.xml { + deny all; + } + + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ { + add_header Cache-Control "public"; + add_header X-Frame-Options "SAMEORIGIN"; + expires +1y; + try_files $uri $uri/ =404; + } + location ~* \.(zip|gz|gzip|bz2|csv|xml)$ { + add_header Cache-Control "no-store"; + add_header X-Frame-Options "SAMEORIGIN"; + expires off; + try_files $uri $uri/ =404; + } + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /media/customer/ { + deny all; + } + + location /media/downloadable/ { + deny all; + } + + location /media/import/ { + deny all; + } + + location ~ cron\.php { + deny all; + } + + location ~ (index|url|messages|test|get|static|report|404|503)\.php$ { + try_files $uri =404; + set $php_host ${PHP_HOSTM2}; + fastcgi_pass unix:/tmp/${php_host}-fpm.sock; + + fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; + fastcgi_param PHP_VALUE "memory_limit=256M \n max_execution_time=600"; + fastcgi_read_timeout 600s; + fastcgi_connect_timeout 600s; + fastcgi_buffers 16 256k; + fastcgi_buffer_size 256k; + + fastcgi_param MAGE_MODE $MAGE_MODE; + fastcgi_param MAGE_RUN_TYPE store; + fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE; + + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PHP_VALUE auto_prepend_file=$PHP_PREPENDM2; + include fastcgi_params; + } + + # mftf magento cli support + location ~* ^/dev/tests/acceptance/utils($|/) { + root /var/www/htdocs/${http_host}/; + location ~ ^/dev/tests/acceptance/utils/command.php { + set $php_host ${PHP_HOSTM2}; + fastcgi_pass unix:/tmp/${php_host}-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + } +} + +# Mailhog proxy +server { + listen 80; + listen 443 ssl; + http2 on; + + server_name mailhog.loc; + + ssl_certificate $SSL_CERT; + ssl_certificate_key $SSL_KEY; + + resolver 127.0.0.11 ipv6=off; + + chunked_transfer_encoding on; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host "mailhog.loc"; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + + location / { + set $target mailhog:8025; + proxy_pass http://$target; + } +} + +# VSCode proxy +server { + listen 80; + listen 443 ssl; + http2 on; + + server_name vscode.loc; + + ssl_certificate $SSL_CERT; + ssl_certificate_key $SSL_KEY; + + resolver 127.0.0.11 ipv6=off; + + chunked_transfer_encoding on; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host "vscode.loc"; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + + location / { + set $target vscode-server:8443; + proxy_pass http://$target; + } +} + +# Kibana proxy +server { + listen 80; + listen 443 ssl; + http2 on; + + server_name kibana.loc; + + ssl_certificate $SSL_CERT; + ssl_certificate_key $SSL_KEY; + + resolver 127.0.0.11 ipv6=off; + + chunked_transfer_encoding on; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host "kibana.loc"; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + + location / { + set $target kibana:5601; + proxy_pass http://$target; + } +} + +# Lighthouse proxy +server { + listen 80; + listen 443 ssl; + http2 on; + + server_name lighthouse.loc; + + ssl_certificate $SSL_CERT; + ssl_certificate_key $SSL_KEY; + + resolver 127.0.0.11 ipv6=off; + + chunked_transfer_encoding on; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + + location / { + set $target lighthouse-server:9001; + proxy_pass http://$target; + } +} + +# Dozzle proxy +server { + listen 80; + listen 443 ssl; + http2 on; + server_name dozzle.loc; + + ssl_certificate $SSL_CERT; + ssl_certificate_key $SSL_KEY; + + resolver 127.0.0.11 ipv6=off; + + chunked_transfer_encoding on; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + + location / { + set $target dozzle:8080; + proxy_pass http://$target; + } +} + +# RabbitMQ management proxy +server { + listen 80; + server_name rabbitmq.loc; + + resolver 127.0.0.11 ipv6=off; + + chunked_transfer_encoding on; + proxy_set_header X-NginX-Proxy true; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + + location / { + set $target rabbitmq:15672; + proxy_pass http://$target; + } +} diff --git a/docker/nginx/m-servers-prod.conf b/docker/nginx/m-servers-prod.conf new file mode 100644 index 0000000..ed81f74 --- /dev/null +++ b/docker/nginx/m-servers-prod.conf @@ -0,0 +1,335 @@ +########################### +## DO NOT EDIT THIS FILE ## +########################### + +# Magento 2 focused PHP hosts +server { + listen 80; + # Docker DNS resolver is .11, NOT A MISTAKE + resolver 127.0.0.11 ipv6=off; + + server_name ~^.*\.(loc|local|localhost)$; + + error_log /dev/stdout; + access_log /dev/stdout; + + # Magento Vars + set $MAGE_MODE production; # or production or developer + + root /var/www/htdocs/${http_host}${root_subfolder}; + + index index.php; + autoindex off; + charset off; + client_max_body_size 20M; + + add_header 'X-Content-Type-Options' 'nosniff'; + add_header 'X-XSS-Protection' '1; mode=block'; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location /pub { + location ~ ^/pub/media/(downloadable|customer|import|theme_customization/.*\.xml) { + deny all; + } + set $php_host ${PHP_HOSTM2}; + alias /var/www/htdocs/eg-m2-opensource.loc/pub; + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /static/ { + if ($MAGE_MODE = "production") { + expires max; + } + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ { + add_header Cache-Control "public"; + add_header X-Frame-Options "SAMEORIGIN"; + expires +1y; + + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + } + location ~* \.(zip|gz|gzip|bz2|csv|xml)$ { + add_header Cache-Control "no-store"; + add_header X-Frame-Options "SAMEORIGIN"; + expires off; + + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + } + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /media/ { + try_files $uri $uri/ =404; + + location ~ ^/media/theme_customization/.*\.xml { + deny all; + } + + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ { + add_header Cache-Control "public"; + add_header X-Frame-Options "SAMEORIGIN"; + expires +1y; + try_files $uri $uri/ =404; + } + location ~* \.(zip|gz|gzip|bz2|csv|xml)$ { + add_header Cache-Control "no-store"; + add_header X-Frame-Options "SAMEORIGIN"; + expires off; + try_files $uri $uri/ =404; + } + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /media/customer/ { + deny all; + } + + location /media/downloadable/ { + deny all; + } + + location /media/import/ { + deny all; + } + + location ~ cron\.php { + deny all; + } + + location ~ (index|url|messages|test|get|static|report|404|503)\.php$ { + try_files $uri =404; + set $php_host ${PHP_HOSTM2}; + fastcgi_pass unix:/tmp/${php_host}-fpm.sock; + + fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; + fastcgi_param PHP_VALUE "memory_limit=256M \n max_execution_time=600"; + fastcgi_read_timeout 600s; + fastcgi_connect_timeout 600s; + fastcgi_buffers 16 256k; + fastcgi_buffer_size 256k; + + fastcgi_param MAGE_MODE $MAGE_MODE; + fastcgi_param MAGE_RUN_TYPE store; + fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE; + + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PHP_VALUE auto_prepend_file=$PHP_PREPENDM2; + include fastcgi_params; + } + + # mftf magento cli support + location ~* ^/dev/tests/acceptance/utils($|/) { + root /var/www/htdocs/${http_host}/; + location ~ ^/dev/tests/acceptance/utils/command.php { + set $php_host ${PHP_HOSTM2}; + fastcgi_pass unix:/tmp/${php_host}-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + } +} +server { + listen 443 ssl; + http2 on; + # Docker DNS reolver is .11, NOT A MISTAKE + resolver 127.0.0.11 ipv6=off; + + server_name ~^.*\.(loc|local|localhost)$; + ssl_certificate $SSL_CERT; + ssl_certificate_key $SSL_KEY; + + error_log /dev/stdout; + access_log /dev/stdout; + + # Magento Vars + set $MAGE_MODE production; # or production or developer + + root /var/www/htdocs/${http_host}${root_subfolder}; + + index index.php; + autoindex off; + charset off; + client_max_body_size 20M; + + add_header 'X-Content-Type-Options' 'nosniff'; + add_header 'X-XSS-Protection' '1; mode=block'; + + + location / { + set $varnish_upstream varnish; + proxy_pass http://$varnish_upstream:80; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + proxy_set_header X-Forwarded-Port 443; + proxy_set_header Host $host; + } + +} + +# Mailhog proxy +server { + listen 80; + listen 443 ssl; + http2 on; + + server_name mailhog.loc; + + ssl_certificate $SSL_CERT; + ssl_certificate_key $SSL_KEY; + + resolver 127.0.0.11 ipv6=off; + + chunked_transfer_encoding on; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host "mailhog.loc"; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + + location / { + set $target mailhog:8025; + proxy_pass http://$target; + } +} + +# VSCode proxy +server { + listen 80; + listen 443 ssl; + http2 on; + + server_name vscode.loc; + + ssl_certificate $SSL_CERT; + ssl_certificate_key $SSL_KEY; + + resolver 127.0.0.11 ipv6=off; + + chunked_transfer_encoding on; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host "vscode.loc"; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + + location / { + set $target vscode-server:8443; + proxy_pass http://$target; + } +} + +# Kibana proxy +server { + listen 80; + listen 443 ssl; + http2 on; + + server_name kibana.loc; + + ssl_certificate $SSL_CERT; + ssl_certificate_key $SSL_KEY; + + resolver 127.0.0.11 ipv6=off; + + chunked_transfer_encoding on; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host "kibana.loc"; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + + location / { + set $target kibana:5601; + proxy_pass http://$target; + } +} + +# Lighthouse proxy +server { + listen 80; + listen 443 ssl; + http2 on; + + server_name lighthouse.loc; + + ssl_certificate $SSL_CERT; + ssl_certificate_key $SSL_KEY; + + resolver 127.0.0.11 ipv6=off; + + chunked_transfer_encoding on; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + + location / { + set $target lighthouse-server:9001; + proxy_pass http://$target; + } +} + +# Dozzle proxy +server { + listen 80; + listen 443 ssl; + http2 on; + server_name dozzle.loc; + + ssl_certificate $SSL_CERT; + ssl_certificate_key $SSL_KEY; + + resolver 127.0.0.11 ipv6=off; + + chunked_transfer_encoding on; + proxy_set_header X-NginX-Proxy true; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + + location / { + set $target dozzle:8080; + proxy_pass http://$target; + } +} + +# RabbitMQ management proxy +server { + listen 80; + server_name rabbitmq.loc; + + resolver 127.0.0.11 ipv6=off; + + chunked_transfer_encoding on; + proxy_set_header X-NginX-Proxy true; + proxy_http_version 1.1; + proxy_redirect off; + proxy_buffering off; + + location / { + set $target rabbitmq:15672; + proxy_pass http://$target; + } +} diff --git a/docker/nginx/m-servers.conf b/docker/nginx/m-servers.conf index b545e22..7a84f44 100644 --- a/docker/nginx/m-servers.conf +++ b/docker/nginx/m-servers.conf @@ -5,6 +5,141 @@ # Magento 2 focused PHP hosts server { listen 80; + # Docker DNS resolver is .11, NOT A MISTAKE + resolver 127.0.0.11 ipv6=off; + + server_name ~^.*\.(loc|local|localhost)$; + + error_log /dev/stdout; + access_log /dev/stdout; + + # Magento Vars + set $MAGE_MODE production; # or production or developer + + root /var/www/htdocs/${http_host}${root_subfolder}; + + index index.php; + autoindex off; + charset off; + client_max_body_size 20M; + + add_header 'X-Content-Type-Options' 'nosniff'; + add_header 'X-XSS-Protection' '1; mode=block'; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location /pub { + location ~ ^/pub/media/(downloadable|customer|import|theme_customization/.*\.xml) { + deny all; + } + set $php_host ${PHP_HOSTM2}; + alias /var/www/htdocs/eg-m2-opensource.loc/pub; + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /static/ { + if ($MAGE_MODE = "production") { + expires max; + } + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ { + add_header Cache-Control "public"; + add_header X-Frame-Options "SAMEORIGIN"; + expires +1y; + + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + } + location ~* \.(zip|gz|gzip|bz2|csv|xml)$ { + add_header Cache-Control "no-store"; + add_header X-Frame-Options "SAMEORIGIN"; + expires off; + + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + } + if (!-f $request_filename) { + rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last; + } + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /media/ { + try_files $uri $uri/ =404; + + location ~ ^/media/theme_customization/.*\.xml { + deny all; + } + + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ { + add_header Cache-Control "public"; + add_header X-Frame-Options "SAMEORIGIN"; + expires +1y; + try_files $uri $uri/ =404; + } + location ~* \.(zip|gz|gzip|bz2|csv|xml)$ { + add_header Cache-Control "no-store"; + add_header X-Frame-Options "SAMEORIGIN"; + expires off; + try_files $uri $uri/ =404; + } + add_header X-Frame-Options "SAMEORIGIN"; + } + + location /media/customer/ { + deny all; + } + + location /media/downloadable/ { + deny all; + } + + location /media/import/ { + deny all; + } + + location ~ cron\.php { + deny all; + } + + location ~ (index|url|messages|test|get|static|report|404|503)\.php$ { + try_files $uri =404; + set $php_host ${PHP_HOSTM2}; + fastcgi_pass unix:/tmp/${php_host}-fpm.sock; + + fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; + fastcgi_param PHP_VALUE "memory_limit=256M \n max_execution_time=600"; + fastcgi_read_timeout 600s; + fastcgi_connect_timeout 600s; + fastcgi_buffers 16 256k; + fastcgi_buffer_size 256k; + + fastcgi_param MAGE_MODE $MAGE_MODE; + fastcgi_param MAGE_RUN_TYPE store; + fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE; + + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PHP_VALUE auto_prepend_file=$PHP_PREPENDM2; + include fastcgi_params; + } + + # mftf magento cli support + location ~* ^/dev/tests/acceptance/utils($|/) { + root /var/www/htdocs/${http_host}/; + location ~ ^/dev/tests/acceptance/utils/command.php { + set $php_host ${PHP_HOSTM2}; + fastcgi_pass unix:/tmp/${php_host}-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + } +} +server { listen 443 ssl; http2 on; # Docker DNS reolver is .11, NOT A MISTAKE @@ -18,7 +153,7 @@ server { access_log /dev/stdout; # Magento Vars - set $MAGE_MODE developer; # or production or developer + set $MAGE_MODE production; # or production or developer root /var/www/htdocs/${http_host}${root_subfolder}; @@ -34,7 +169,6 @@ server { root /var/www/htdocs/${http_host}/; location ~ ^/setup/index.php { set $php_host ${PHP_HOSTM2}; -# fastcgi_pass ${PHP_HOSTM2}:9000; fastcgi_pass unix:/tmp/${php_host}-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; @@ -56,7 +190,6 @@ server { location ~ ^/update/index.php { fastcgi_split_path_info ^(/update/index.php)(/.+)$; set $php_host ${PHP_HOSTM2}; -# fastcgi_pass ${PHP_HOSTM2}:9000; fastcgi_pass unix:/tmp/${php_host}-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; @@ -76,6 +209,13 @@ server { location / { try_files $uri $uri/ /index.php?$args; + set $varnish_upstream varnish; + proxy_pass http://$varnish_upstream:80; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + proxy_set_header X-Forwarded-Port 443; + proxy_set_header Host $host; } location /pub { diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf index 04e06bb..7af27ce 100644 --- a/docker/nginx/nginx.conf +++ b/docker/nginx/nginx.conf @@ -1,4 +1,3 @@ - user nginx; worker_processes 1; diff --git a/docker/php/8.2/Dockerfile b/docker/php/8.2/Dockerfile index a7a9d7a..cd997bf 100644 --- a/docker/php/8.2/Dockerfile +++ b/docker/php/8.2/Dockerfile @@ -47,16 +47,6 @@ RUN apt-get update \ # && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8707\n" > /usr/local/etc/php/conf.d/blackfire.ini \ # && rm -rf /tmp/blackfire /tmp/blackfire-probe.tar.gz -# Install latest Node.js -RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - -RUN apt-get -y install nodejs - -# INSTALL YARN -RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ - echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ - apt update && \ - apt install -y yarn - # Configure the gd library RUN docker-php-ext-configure \ gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ @@ -101,9 +91,6 @@ RUN curl -O https://files.magerun.net/n98-magerun2.phar \ && chmod +x n98-magerun2.phar \ && mv n98-magerun2.phar /usr/local/bin/n98-magerun2 -# INSTALL GRUNT -RUN npm install -g grunt-cli - #INSTALL PLAYWRIGHT FOR CRITICAL CSS RUN apt-get update \ && apt-get install -y \ @@ -112,19 +99,35 @@ RUN apt-get update \ libgbm1\ libasound2 -#XDEBUG -RUN pecl install xdebug-3.2.1 \ - && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini -RUN echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini \ - && echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/xdebug.ini \ - && echo "xdebug.client_port=9000" >> /usr/local/etc/php/conf.d/xdebug.ini \ - && echo "xdebug.start_with_request=trigger" >> /usr/local/etc/php/conf.d/xdebug.ini \ - && echo "xdebug.show_error_trace=1" >> /usr/local/etc/php/conf.d/xdebug.ini \ - && echo "xdebug.discover_client_host=1" >> /usr/local/etc/php/conf.d/xdebug.ini \ - && echo "xdebug.idekey=\"PHPSTORM\"" >> /usr/local/etc/php/conf.d/xdebug.ini \ - && echo "xdebug.discover_client_host=1" >> /usr/local/etc/php/conf.d/xdebug.ini \ - && echo "xdebug.log=\"/tmp/xdebug.log\"" >> /usr/local/etc/php/conf.d/xdebug.ini \ - && echo "xdebug.output_dir=\"/tmp/\"" >> /usr/local/etc/php/conf.d/xdebug.ini +# Install latest Node.js +RUN apt-get update && sudo apt-get install -y ca-certificates curl gnupg +RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +ARG NODE_MAJOR=20 +RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list +RUN apt-get update && sudo apt-get install nodejs -y + +# INSTALL YARN +RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ + echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ + apt update && \ + apt install -y yarn + +# INSTALL GRUNT +RUN npm install -g grunt-cli + +#XDEBUG @todo switch xdebug on/off via deploy:mode:set production/developer +#RUN pecl install xdebug-3.2.1 \ +# && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini +#RUN echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini \ +# && echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/xdebug.ini \ +# && echo "xdebug.client_port=9000" >> /usr/local/etc/php/conf.d/xdebug.ini \ +# && echo "xdebug.start_with_request=trigger" >> /usr/local/etc/php/conf.d/xdebug.ini \ +# && echo "xdebug.show_error_trace=1" >> /usr/local/etc/php/conf.d/xdebug.ini \ +# && echo "xdebug.discover_client_host=1" >> /usr/local/etc/php/conf.d/xdebug.ini \ +# && echo "xdebug.idekey=\"PHPSTORM\"" >> /usr/local/etc/php/conf.d/xdebug.ini \ +# && echo "xdebug.discover_client_host=1" >> /usr/local/etc/php/conf.d/xdebug.ini \ +# && echo "xdebug.log=\"/tmp/xdebug.log\"" >> /usr/local/etc/php/conf.d/xdebug.ini \ +# && echo "xdebug.output_dir=\"/tmp/\"" >> /usr/local/etc/php/conf.d/xdebug.ini # Add base php.ini and php-fpm config ADD php.ini-developer /usr/local/etc/php/php.ini diff --git a/docker/services.yml b/docker/services.yml index 560ace4..952e93f 100644 --- a/docker/services.yml +++ b/docker/services.yml @@ -1,284 +1,292 @@ version: '3' services: - mailhog: - image: mailhog/mailhog - ports: - - "1025:1025" - - "8025:8025" + mailhog: + image: mailhog/mailhog + ports: + - "1025:1025" + - "8025:8025" - php74: - user: "${USERID}:${GROUPID}" - build: - context: ./php/7.4 - volumes: - - composer_cache:${HOME}/.composer/cache - - ssh-key:/var/www/htdocs/.ssh - - web_files:/var/www/htdocs - - shared-tmp:/tmp - environment: - MYSQL_USER: ${MYSQL_USER} - MYSQL_PASSWORD: ${MYSQL_PASSWORD} - XDEBUG_MODE: ${XDEBUG_MODE} + php74: + user: "${USERID}:${GROUPID}" + build: + context: ./php/7.4 + volumes: + - composer_cache:${HOME}/.composer/cache + - ssh-key:/var/www/htdocs/.ssh + - web_files:/var/www/htdocs + - shared-tmp:/tmp + environment: + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + XDEBUG_MODE: ${XDEBUG_MODE} - php81: - user: "${USERID}:${GROUPID}" - build: - context: ./php/8.1 - volumes: - - composer_cache:${HOME}/.composer/cache - - ssh-key:/var/www/htdocs/.ssh - - web_files:/var/www/htdocs - - shared-tmp:/tmp - environment: - MYSQL_USER: ${MYSQL_USER} - MYSQL_PASSWORD: ${MYSQL_PASSWORD} - XDEBUG_MODE: ${XDEBUG_MODE} + php81: + user: "${USERID}:${GROUPID}" + build: + context: ./php/8.1 + volumes: + - composer_cache:${HOME}/.composer/cache + - ssh-key:/var/www/htdocs/.ssh + - web_files:/var/www/htdocs + - shared-tmp:/tmp + environment: + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + XDEBUG_MODE: ${XDEBUG_MODE} - php82: - user: "${USERID}:${GROUPID}" - build: - context: ./php/8.2 - volumes: - - composer_cache:${HOME}/.composer/cache - - ssh-key:/var/www/htdocs/.ssh - - web_files:/var/www/htdocs - - shared-tmp:/tmp - - /var/run/docker.sock:/var/run/docker.sock - - docker-files:/var/www/htdocs/docker - - project-files:/var/www/htdocs/project - - bin-files:/var/www/htdocs/bin - environment: - MYSQL_USER: ${MYSQL_USER} - MYSQL_PASSWORD: ${MYSQL_PASSWORD} - XDEBUG_MODE: ${XDEBUG_MODE} + php82: + user: "${USERID}:${GROUPID}" + build: + context: ./php/8.2 + volumes: + - composer_cache:${HOME}/.composer/cache + - ssh-key:/var/www/htdocs/.ssh + - web_files:/var/www/htdocs + - shared-tmp:/tmp + - /var/run/docker.sock:/var/run/docker.sock + - docker-files:/var/www/htdocs/docker + - project-files:/var/www/htdocs/project + - bin-files:/var/www/htdocs/bin + environment: + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + XDEBUG_MODE: ${XDEBUG_MODE} + PHP_IDE_CONFIG: "serverName=docker" + extra_hosts: + - "host.docker.internal:host-gateway" - nginx: - build: - context: ./nginx - ports: - - 80:80 - - 443:443 - volumes: - - web_files:/var/www/htdocs - - shared-tmp:/tmp - networks: - default: - aliases: - - eg-m2-opensource.loc + nginx: + build: + context: ./nginx + volumes: + - web_files:/var/www/htdocs + - shared-tmp:/tmp + ports: + - "443:443" + - "80:80" - selenium: - image: selenium/standalone-chrome:latest - shm_size: '2gb' - ports: - - "4444:4444" - - "7900:7900" - depends_on: - - nginx + varnish: + image: varnish:7.3-alpine + volumes: + - ./varnish/default.vcl:/etc/varnish/default.vcl + depends_on: + - nginx + links: + - nginx - elasticsearch7: - build: - context: ./elasticsearch/7 - environment: - - xpack.security.enabled=false - - discovery.type=single-node - ulimits: - memlock: - soft: -1 - hard: -1 - nofile: - soft: 65536 - hard: 65536 - cap_add: - - IPC_LOCK - volumes: - - elasticsearch7-data:/usr/share/elasticsearch7/data - ports: - - 9207:9200 - - 9307:9300 + selenium: + image: selenium/standalone-chrome:latest + shm_size: '2gb' + ports: + - "4444:4444" + - "7900:7900" + depends_on: + - nginx - elasticsearch716: - build: - context: ./elasticsearch/7.16 - environment: - - xpack.security.enabled=false - - xpack.watcher.enabled=false - - xpack.monitoring.enabled=true - - discovery.type=single-node - - "ES_JAVA_OPTS=-Xms512m -Xmx512m" - ulimits: - memlock: - soft: -1 - hard: -1 - nofile: - soft: 65536 - hard: 65536 - cap_add: - - IPC_LOCK - volumes: - - elasticsearch716-data:/usr/share/elasticsearch7/data - ports: - - 9716:9200 - - 9816:9300 + elasticsearch7: + build: + context: ./elasticsearch/7 + environment: + - xpack.security.enabled=false + - discovery.type=single-node + ulimits: + memlock: + soft: -1 + hard: -1 + nofile: + soft: 65536 + hard: 65536 + cap_add: + - IPC_LOCK + volumes: + - elasticsearch7-data:/usr/share/elasticsearch7/data + ports: + - 9207:9200 + - 9307:9300 - opensearch12: - build: - context: ./opensearch/1.2 - environment: - - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" - - node.name=opensearch123 - - discovery.type=single-node - - bootstrap.memory_lock=true - - plugins.security.disabled=true - - network.host=0.0.0.0 - ulimits: - memlock: - soft: -1 - hard: -1 + elasticsearch716: + build: + context: ./elasticsearch/7.16 + environment: + - xpack.security.enabled=false + - xpack.watcher.enabled=false + - xpack.monitoring.enabled=true + - discovery.type=single-node + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + ulimits: + memlock: + soft: -1 + hard: -1 + nofile: + soft: 65536 + hard: 65536 + cap_add: + - IPC_LOCK + volumes: + - elasticsearch716-data:/usr/share/elasticsearch7/data + ports: + - 9716:9200 + - 9816:9300 - opensearch25: - build: - context: ./opensearch/2.5 - environment: - - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" - - node.name=opensearch25 - - discovery.type=single-node - - bootstrap.memory_lock=true - - plugins.security.disabled=true - - network.host=0.0.0.0 - ulimits: - memlock: - soft: -1 - hard: -1 + opensearch12: + build: + context: ./opensearch/1.2 + environment: + - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" + - node.name=opensearch123 + - discovery.type=single-node + - bootstrap.memory_lock=true + - plugins.security.disabled=true + - network.host=0.0.0.0 + ulimits: + memlock: + soft: -1 + hard: -1 - kibana: - container_name: kibana - image: docker.elastic.co/kibana/kibana:7.13.0 - depends_on: - - elasticsearch716 - - apm-server - environment: - - ELASTICSEARCH_URL=http://elasticsearch716:9200 - - ELASTICSEARCH_HOSTS=http://elasticsearch716:9200 - - xpack.apm.enabled=false - - xpack.encryptedSavedObjects.encryptionKey= + opensearch25: + build: + context: ./opensearch/2.5 + environment: + - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" + - node.name=opensearch25 + - discovery.type=single-node + - bootstrap.memory_lock=true + - plugins.security.disabled=true + - network.host=0.0.0.0 + ulimits: + memlock: + soft: -1 + hard: -1 - apm-server: - image: docker.elastic.co/apm/apm-server:7.13.0 - cap_add: ["CHOWN", "DAC_OVERRIDE", "SETGID", "SETUID"] - cap_drop: ["ALL"] - depends_on: - - elasticsearch716 - command: > - apm-server -e - -E apm-server.rum.enabled=true - -E setup.kibana.host=kibana:5601 - -E setup.template.settings.index.number_of_replicas=0 - -E apm-server.kibana.enabled=true - -E apm-server.kibana.host=kibana:5601 - -E output.elasticsearch.hosts=["elasticsearch716:9200"] - healthcheck: - interval: 10s - retries: 12 - test: curl --write-out 'HTTP %{http_code}' --fail --silent --output /dev/null http://localhost:8200/ + kibana: + container_name: kibana + image: docker.elastic.co/kibana/kibana:7.13.0 + depends_on: + - elasticsearch716 + - apm-server + environment: + - ELASTICSEARCH_URL=http://elasticsearch716:9200 + - ELASTICSEARCH_HOSTS=http://elasticsearch716:9200 + - xpack.apm.enabled=false + - xpack.encryptedSavedObjects.encryptionKey= - mysql57: - build: - context: ./mysql/5.7 - ports: - - 3307:3306 - volumes: - - mysql_data57:/var/lib/mysql - environment: - MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} - MYSQL_DATABASE: ${MYSQL_DATABASE} - MYSQL_USER: ${MYSQL_USER} - MYSQL_PASSWORD: ${MYSQL_PASSWORD} + apm-server: + image: docker.elastic.co/apm/apm-server:7.13.0 + cap_add: [ "CHOWN", "DAC_OVERRIDE", "SETGID", "SETUID" ] + cap_drop: [ "ALL" ] + depends_on: + - elasticsearch716 + command: > + apm-server -e + -E apm-server.rum.enabled=true + -E setup.kibana.host=kibana:5601 + -E setup.template.settings.index.number_of_replicas=0 + -E apm-server.kibana.enabled=true + -E apm-server.kibana.host=kibana:5601 + -E output.elasticsearch.hosts=["elasticsearch716:9200"] + healthcheck: + interval: 10s + retries: 12 + test: curl --write-out 'HTTP %{http_code}' --fail --silent --output /dev/null http://localhost:8200/ - mysql80: - build: - context: ./mysql/8.0 - ports: - - 3308:3306 - volumes: - - mysql_data80:/var/lib/mysql - working_dir: /var/lib/mysql - command: --default-authentication-plugin=mysql_native_password - environment: - MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} - MYSQL_ROOT_HOST: "%" - MYSQL_DATABASE: ${MYSQL_DATABASE} - MYSQL_USER: ${MYSQL_USER} - MYSQL_PASSWORD: ${MYSQL_PASSWORD} + mysql57: + build: + context: ./mysql/5.7 + ports: + - 3307:3306 + volumes: + - mysql_data57:/var/lib/mysql + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: ${MYSQL_DATABASE} + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} - redissession: - image: redis:5-alpine - command: redis-server /usr/local/etc/redis/redis.conf - volumes: - - ./redissession/redis.conf:/usr/local/etc/redis/redis.conf - - shared-tmp:/tmp + mysql80: + build: + context: ./mysql/8.0 + ports: + - 3308:3306 + volumes: + - mysql_data80:/var/lib/mysql + working_dir: /var/lib/mysql + command: --default-authentication-plugin=mysql_native_password + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_ROOT_HOST: "%" + MYSQL_DATABASE: ${MYSQL_DATABASE} + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} - rediscache: - image: redis:5-alpine - command: redis-server /usr/local/etc/redis/redis.conf - volumes: - - ./rediscache/redis.conf:/usr/local/etc/redis/redis.conf - - shared-tmp:/tmp + redissession: + image: redis:5-alpine + command: redis-server /usr/local/etc/redis/redis.conf + volumes: + - ./redissession/redis.conf:/usr/local/etc/redis/redis.conf + - shared-tmp:/tmp - redisfullpage: - image: redis:5-alpine - command: redis-server /usr/local/etc/redis/redis.conf - volumes: - - ./redisfullpage/redis.conf:/usr/local/etc/redis/redis.conf - - shared-tmp:/tmp + rediscache: + image: redis:5-alpine + command: redis-server /usr/local/etc/redis/redis.conf + volumes: + - ./rediscache/redis.conf:/usr/local/etc/redis/redis.conf + - shared-tmp:/tmp - rabbitmq: - image: rabbitmq:3.8-management - container_name: 'rabbitmq' - command: "/bin/bash -c \"rabbitmq-plugins enable rabbitmq_management; rabbitmq-plugins enable rabbitmq_mqtt; rabbitmq-plugins enable rabbitmq_web_mqtt; rabbitmq-plugins enable rabbitmq_amqp1_0; rabbitmq-server\"" - ports: - - 1883:1883 - volumes: - - ./rabbitmq/rabbitmq-isolated.conf:/etc/rabbitmq/rabbitmq.config + redisfullpage: + image: redis:5-alpine + command: redis-server /usr/local/etc/redis/redis.conf + volumes: + - ./redisfullpage/redis.conf:/usr/local/etc/redis/redis.conf + - shared-tmp:/tmp - dozzle: - container_name: dozzle - image: amir20/dozzle:latest - volumes: - - /var/run/docker.sock:/var/run/docker.sock + rabbitmq: + image: rabbitmq:3.8-management + container_name: 'rabbitmq' + command: "/bin/bash -c \"rabbitmq-plugins enable rabbitmq_management; rabbitmq-plugins enable rabbitmq_mqtt; rabbitmq-plugins enable rabbitmq_web_mqtt; rabbitmq-plugins enable rabbitmq_amqp1_0; rabbitmq-server\"" + ports: + - 1883:1883 + volumes: + - ./rabbitmq/rabbitmq-isolated.conf:/etc/rabbitmq/rabbitmq.config - lighthouse-server: - build: - context: ./lighthouse-server - ports: - - '9001:9001' - volumes: - - lhci-data:/data - cap_add: - - SYS_ADMIN + dozzle: + container_name: dozzle + image: amir20/dozzle:latest + volumes: + - /var/run/docker.sock:/var/run/docker.sock - phpstorm-server: - user: "${USERID}:${GROUPID}" - build: - context: ./phpstorm-server - ports: - - '5993:5993' - environment: - - RUNNING_PROJECT=${RUNNING_PROJECT} - volumes: - - ssh-key:/var/www/htdocs/.ssh - - web_files:/var/www/htdocs + lighthouse-server: + build: + context: ./lighthouse-server + ports: + - '9001:9001' + volumes: + - lhci-data:/data + cap_add: + - SYS_ADMIN - vscode-server: - user: "${USERID}:${GROUPID}" - build: - context: ./vscode-server - ports: - - "8443:8443" - - "9000:9000" - environment: - - RUNNING_PROJECT=${RUNNING_PROJECT} - - VSCODE_SECURE=${VSCODE_SECURE} - volumes: - - ssh-key:/var/www/htdocs/.ssh - - web_files:/var/www/htdocs + phpstorm-server: + user: "${USERID}:${GROUPID}" + build: + context: ./phpstorm-server + ports: + - '5993:5993' + environment: + - RUNNING_PROJECT=${RUNNING_PROJECT} + volumes: + - ssh-key:/var/www/htdocs/.ssh + - web_files:/var/www/htdocs + + vscode-server: + user: "${USERID}:${GROUPID}" + build: + context: ./vscode-server + ports: + - "8443:8443" + - "9000:9000" + environment: + - RUNNING_PROJECT=${RUNNING_PROJECT} + - VSCODE_SECURE=${VSCODE_SECURE} + volumes: + - ssh-key:/var/www/htdocs/.ssh + - web_files:/var/www/htdocs diff --git a/docker/varnish/default.vcl b/docker/varnish/default.vcl new file mode 100644 index 0000000..1dff1b0 --- /dev/null +++ b/docker/varnish/default.vcl @@ -0,0 +1,254 @@ +# VCL version 5.0 is not supported so it should be 4.0 even though actually used Varnish version is 6 +vcl 4.0; + +import std; +# The minimal Varnish version is 6.0 +# For SSL offloading, pass the following header in your proxy server or load balancer: 'X-Forwarded-Proto: https' + +backend default { + .host = "nginx"; + .port = "80"; + .first_byte_timeout = 600s; + .probe = { + .url = "/pub/health_check.php"; + .timeout = 2s; + .interval = 5s; + .window = 10; + .threshold = 5; + } +} + +acl purge { +} + +sub vcl_recv { + if (req.restarts > 0) { + set req.hash_always_miss = true; + } + + if (req.method == "PURGE") { + if (client.ip !~ purge) { + return (synth(405, "Method not allowed")); + } + # To use the X-Pool header for purging varnish during automated deployments, make sure the X-Pool header + # has been added to the response in your backend server config. This is used, for example, by the + # capistrano-magento2 gem for purging old content from varnish during it's deploy routine. + if (!req.http.X-Magento-Tags-Pattern && !req.http.X-Pool) { + return (synth(400, "X-Magento-Tags-Pattern or X-Pool header required")); + } + if (req.http.X-Magento-Tags-Pattern) { + ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern); + } + if (req.http.X-Pool) { + ban("obj.http.X-Pool ~ " + req.http.X-Pool); + } + return (synth(200, "Purged")); + } + + if (req.method != "GET" && + req.method != "HEAD" && + req.method != "PUT" && + req.method != "POST" && + req.method != "TRACE" && + req.method != "OPTIONS" && + req.method != "DELETE") { + /* Non-RFC2616 or CONNECT which is weird. */ + return (pipe); + } + + # We only deal with GET and HEAD by default + if (req.method != "GET" && req.method != "HEAD") { + return (pass); + } + + # Bypass customer, shopping cart, checkout + if (req.url ~ "/customer" || req.url ~ "/checkout") { + return (pass); + } + + # Bypass health check requests + if (req.url ~ "^/(pub/)?(health_check.php)$") { + return (pass); + } + + # Set initial grace period usage status + set req.http.grace = "none"; + + # normalize url in case of leading HTTP scheme and domain + set req.url = regsub(req.url, "^http[s]?://", ""); + + # collect all cookies + std.collect(req.http.Cookie); + + # Compression filter. See https://www.varnish-cache.org/trac/wiki/FAQ/Compression + if (req.http.Accept-Encoding) { + if (req.url ~ "\.(jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|flv)$") { + # No point in compressing these + unset req.http.Accept-Encoding; + } elsif (req.http.Accept-Encoding ~ "gzip") { + set req.http.Accept-Encoding = "gzip"; + } elsif (req.http.Accept-Encoding ~ "deflate" && req.http.user-agent !~ "MSIE") { + set req.http.Accept-Encoding = "deflate"; + } else { + # unknown algorithm + unset req.http.Accept-Encoding; + } + } + + # Remove all marketing get parameters to minimize the cache objects + if (req.url ~ "(\?|&)(gclid|cx|ie|cof|siteurl|zanpid|origin|fbclid|mc_[a-z]+|utm_[a-z]+|_bta_[a-z]+)=") { + set req.url = regsuball(req.url, "(gclid|cx|ie|cof|siteurl|zanpid|origin|fbclid|mc_[a-z]+|utm_[a-z]+|_bta_[a-z]+)=[-_A-z0-9+()%.]+&?", ""); + set req.url = regsub(req.url, "[?|&]+$", ""); + } + + # Static files caching + if (req.url ~ "^/(pub/)?(media|static)/") { + # Static files should not be cached by default + #eturn (pass); + + # But if you use a few locales and don't use CDN you can enable caching static files by commenting previous line (#return (pass);) and uncommenting next 3 lines + unset req.http.Https; + unset req.http.X-Forwarded-Proto; + unset req.http.Cookie; + } + + # Bypass authenticated GraphQL requests without a X-Magento-Cache-Id + if (req.url ~ "/graphql" && !req.http.X-Magento-Cache-Id && req.http.Authorization ~ "^Bearer") { + return (pass); + } + + return (hash); +} + +sub vcl_hash { + if ((req.url !~ "/graphql" || !req.http.X-Magento-Cache-Id) && req.http.cookie ~ "X-Magento-Vary=") { + hash_data(regsub(req.http.cookie, "^.*?X-Magento-Vary=([^;]+);*.*$", "\1")); + } + + # To make sure http users don't see ssl warning + if (req.http.X-Forwarded-Proto) { + hash_data(req.http.X-Forwarded-Proto); + } + + + if (req.url ~ "/graphql") { + call process_graphql_headers; + } +} + +sub process_graphql_headers { + if (req.http.X-Magento-Cache-Id) { + hash_data(req.http.X-Magento-Cache-Id); + + # When the frontend stops sending the auth token, make sure users stop getting results cached for logged-in users + if (req.http.Authorization ~ "^Bearer") { + hash_data("Authorized"); + } + } + + if (req.http.Store) { + hash_data(req.http.Store); + } + + if (req.http.Content-Currency) { + hash_data(req.http.Content-Currency); + } +} + +sub vcl_backend_response { + + set beresp.grace = 3d; + + if (beresp.http.content-type ~ "text") { + set beresp.do_esi = true; + } + + if (bereq.url ~ "\.js$" || beresp.http.content-type ~ "text") { + set beresp.do_gzip = true; + } + + if (beresp.http.X-Magento-Debug) { + set beresp.http.X-Magento-Cache-Control = beresp.http.Cache-Control; + } + + # cache only successfully responses and 404s that are not marked as private + if (beresp.status != 200 && + beresp.status != 404 && + beresp.http.Cache-Control ~ "private") { + set beresp.uncacheable = true; + set beresp.ttl = 86400s; + return (deliver); + } + + # validate if we need to cache it and prevent from setting cookie + if (beresp.ttl > 0s && (bereq.method == "GET" || bereq.method == "HEAD")) { + unset beresp.http.set-cookie; + } + + # If page is not cacheable then bypass varnish for 2 minutes as Hit-For-Pass + if (beresp.ttl <= 0s || + beresp.http.Surrogate-control ~ "no-store" || + (!beresp.http.Surrogate-Control && + beresp.http.Cache-Control ~ "no-cache|no-store") || + beresp.http.Vary == "*") { + # Mark as Hit-For-Pass for the next 2 minutes + set beresp.ttl = 120s; + set beresp.uncacheable = true; + } + + # If the cache key in the Magento response doesn't match the one that was sent in the request, don't cache under the request's key + if (bereq.url ~ "/graphql" && bereq.http.X-Magento-Cache-Id && bereq.http.X-Magento-Cache-Id != beresp.http.X-Magento-Cache-Id) { + set beresp.ttl = 0s; + set beresp.uncacheable = true; + } + + return (deliver); +} + +sub vcl_deliver { + if (resp.http.x-varnish ~ " ") { + set resp.http.X-Magento-Cache-Debug = "HIT"; + set resp.http.Grace = req.http.grace; + } else { + set resp.http.X-Magento-Cache-Debug = "MISS"; + } + + # Not letting browser to cache non-static files. + if (resp.http.Cache-Control !~ "private" && req.url !~ "^/(pub/)?(media|static)/") { + set resp.http.Pragma = "no-cache"; + set resp.http.Expires = "-1"; + set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0"; + } + + if (!resp.http.X-Magento-Debug) { + unset resp.http.Age; + } + unset resp.http.X-Magento-Debug; + unset resp.http.X-Magento-Tags; + unset resp.http.X-Powered-By; + unset resp.http.Server; + unset resp.http.X-Varnish; + unset resp.http.Via; + unset resp.http.Link; +} + +sub vcl_hit { + if (obj.ttl >= 0s) { + # Hit within TTL period + return (deliver); + } + if (std.healthy(req.backend_hint)) { + if (obj.ttl + 300s > 0s) { + # Hit after TTL expiration, but within grace period + set req.http.grace = "normal (healthy server)"; + return (deliver); + } else { + # Hit after TTL and grace expiration + return (restart); + } + } else { + # server is not healthy, retrieve from cache + set req.http.grace = "unlimited (unhealthy server)"; + return (deliver); + } +} diff --git a/project/includes/_functions_m2.sh b/project/includes/_functions_m2.sh index 6d453af..b364ffb 100644 --- a/project/includes/_functions_m2.sh +++ b/project/includes/_functions_m2.sh @@ -221,7 +221,7 @@ composer_require_dev_tools () { if [[ "${resources_storage}" == "local" && -d "./project/resources/${vmhost_name}/configurator" ]] || [[ "${resources_storage}" == "s3" && "$(s3cmd ls s3://${s3_bucket}/${vmhost_name}/configurator | wc -l)" -eq 1 ]]; then echo_info "Installing CTI Digital Configurator ..."; - ./bin/docker-exec ${php_host} "cd /var/www/htdocs/${vmhost_name}/; ${COMPOSER_COMMAND} require --no-update --dev ctidigital/magento2-configurator:3.1.3"; + ./bin/docker-exec ${php_host} "cd /var/www/htdocs/${vmhost_name}/; ${COMPOSER_COMMAND} require --no-update --dev ctidigital/magento2-configurator"; ./bin/docker-exec ${php_host} "cd /var/www/htdocs/${vmhost_name}/; ${COMPOSER_COMMAND} update ctidigital/magento2-configurator"; else echo_error "Failed to find configuration files in ${resources_storage}" @@ -248,6 +248,19 @@ docker:mode:set() { fi docker:copy "${PHP_BUILD_ENV}/php.ini-${DEPLOY_MODE}" ${php_host}:/usr/local/etc/php/php.ini; ./bin/docker-compose restart "${php_host}"; + if [[ "${DEPLOY_MODE}" == "production" && -f 'docker/nginx/Dockerfile-prod' ]]; then + mv docker/nginx/Dockerfile docker/nginx/Dockerfile-dev && mv docker/nginx/Dockerfile-prod docker/nginx/Dockerfile; + elif [[ "${DEPLOY_MODE}" == "developer" && -f 'docker/nginx/Dockerfile-dev' ]]; then + mv docker/nginx/Dockerfile docker/nginx/Dockerfile-prod && mv docker/nginx/Dockerfile-dev docker/nginx/Dockerfile; + fi + docker:refresh + if [[ "${DEPLOY_MODE}" == "production" ]]; then + bin/magento config:set system/full_page_cache/caching_application 2 # setting varnish full page cache + else + bin/magento config:set system/full_page_cache/caching_application 1 # setting built-in full page cache + fi + bin/magento cache:flush + } ##################################### diff --git a/project/includes/_functions_shared.sh b/project/includes/_functions_shared.sh index 40ff79c..cca2572 100644 --- a/project/includes/_functions_shared.sh +++ b/project/includes/_functions_shared.sh @@ -349,7 +349,7 @@ IDE:vscode () { ###################################################### # Create local clone of CVS Repository -# +# ** needs to add host key or git clone fails ** # Required variables: # $repo_type # $project_name diff --git a/project/m2_commerce b/project/m2_commerce index 0961a20..0b6ad13 100755 --- a/project/m2_commerce +++ b/project/m2_commerce @@ -27,7 +27,7 @@ cvs_branch="2.4.5-p2"; resources_storage='local'; # Where to access shared resources (see README.md), 'local' or 's3' db_host='mysql80'; # 'percona56' or 'percona57' php_host='php81'; # 'php56', 'php70', 'php72', 'php73' or 'php74' -required_containers=( "nginx" "rediscache" "redissession" "redisfullpage" "elasticsearch7" "${php_host}" "${db_host}"); +required_containers=( "nginx" "rediscache" "redissession" "redisfullpage" "elasticsearch7" "${php_host}" "${db_host} varnish"); composer_version="2"; db_name='example_m2_commerce'; # unique name for this database vmhost_name='eg-m2-commerce.loc'; # domain name for this project in local vm.