diff --git a/README.md b/README.md index 1fa7007aa..9052fc698 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,34 @@ bin/restart open https://magento.test ``` +#### Existing multistore projects +```bash + +# Run bin/n98-magerun2 at least once in order to download the file +bin/n98-magerun2 + +# Creates a nginx mapping file and updates the base URLs in the database table `core_config_data` for each store. +# Admin panel base URL: https://magento.test +# Base URLs of each store: https://magento-store-code.test where store-code is the value found in `store.code` database column. +# e.g. two stores with the following codes: `en_US` and `fr_FR` will have base URLs: `https://magento-en-us.test` and `https://magento-fr-fr.test` +# Note that since we need to write `/etc/hosts` for DNS resolution, you will be prompted for your system password. +bin/setup-multistore + + +# If using Linux uncomment mount bindings in `docker-compose.dev.linux.yml` file and copy the file to `docker-compose.dev.yml` +sed -i 's/# - .\/config\/nginx\/nginx.conf/- .\/config\/nginx\/nginx.conf/' docker-compose.dev-linux.yml +sed -i 's/# - .\/config\/nginx\/default.conf/- .\/config\/nginx\/default.conf/' docker-compose.dev-linux.yml +cp docker-compose.dev-linux.yml docker-compose.dev.yml + +# If using macOS (un)comment mount bindings in `docker-compose.dev.yml` file +sed -i 's/- .\/src\/nginx.conf.sample/#- .\/src\/nginx.conf.sample/' docker-compose.dev.yml +sed -i 's/# - .\/config\/nginx\/nginx.conf/- .\/config\/nginx\/nginx.conf/' docker-compose.dev.yml +sed -i 's/# - .\/config\/nginx\/default.conf/- .\/config\/nginx\/default.conf/' docker-compose.dev.yml + +# Restart containers +bin/restart +``` + ## Updates To update your project to the latest version of `docker-magento`, run: diff --git a/compose/.gitignore b/compose/.gitignore index 8eba6c8dd..f998215fd 100644 --- a/compose/.gitignore +++ b/compose/.gitignore @@ -1 +1,3 @@ src/ +config/nginx/nginx.conf +config/nginx/default.conf diff --git a/compose/bin/add-base-urls-to-hosts b/compose/bin/add-base-urls-to-hosts new file mode 100755 index 000000000..550695fdb --- /dev/null +++ b/compose/bin/add-base-urls-to-hosts @@ -0,0 +1,24 @@ +#!/bin/bash + +STORES=$(bin/n98-magerun2 sys:store:list --format=csv | grep -v Warning | sed '/^$/d' | tail -n+2) + +NEWLINE_PRINTED=false +for STORE in $STORES; do + SEPARATOR="" + STORE_CODE="" + STORE_ID=$(echo "$STORE" | cut -d ',' -f1) + if [[ ${STORE_ID} -gt 1 ]]; then + SEPARATOR="-" + STORE_CODE=$(echo "$STORE" | cut -d ',' -f2) + STORE_CODE="${STORE_CODE//_/-}" + fi + HOSTS_URL=magento"${SEPARATOR}""${STORE_CODE}".test + URL_IN_HOSTS_FILE=$(grep -c "$HOSTS_URL" /etc/hosts) + if [[ $URL_IN_HOSTS_FILE -eq 0 ]]; then + if [[ $NEWLINE_PRINTED == false ]]; then + echo | sudo tee -a /etc/hosts + NEWLINE_PRINTED=true + fi + echo 127.0.0.1"$(printf "\t")""$HOSTS_URL" | sudo tee -a /etc/hosts + fi +done diff --git a/compose/bin/generate-nginx-mapping b/compose/bin/generate-nginx-mapping new file mode 100755 index 000000000..27f666338 --- /dev/null +++ b/compose/bin/generate-nginx-mapping @@ -0,0 +1,15 @@ +#!/bin/bash +set -e + +STORES=$(bin/n98-magerun2 sys:store:list --format=csv | grep -v Warning | sed '/^$/d' | tail -n+2) + +printf "map \$http_host \$MAGE_RUN_CODE {\n" +printf ' %s\n' "default $(echo "$STORES" | head -n1 | cut -d ',' -f2)"';' + +for STORE in $STORES; do + STORE_CODE=$(echo "$STORE" | cut -d ',' -f2) + STORE_WITH_DASHES=${STORE_CODE//_/-} + printf ' %s\n' 'magento-'"$STORE_WITH_DASHES"'.test '"$STORE_CODE"';' +done + +printf '%s\n' "}" diff --git a/compose/bin/generate-store-setters b/compose/bin/generate-store-setters new file mode 100755 index 000000000..15fdb4afe --- /dev/null +++ b/compose/bin/generate-store-setters @@ -0,0 +1,62 @@ +#!/bin/bash +set -e + +STORES=$(bin/n98-magerun2 sys:store:list --format=csv | grep -v Warning | sed '/^$/d' | tail -n+2) + +# echo "use magento;" +echo "DELETE FROM core_config_data WHERE path LIKE 'web/%/base%url';" + +for STORE in $STORES; do + STORE_CODE="" + SEPARATOR="" + SCOPE="default" + STORE_ID=$(echo "$STORE" | cut -d ',' -f1) + if [[ ${STORE_ID} -gt 1 ]]; then + SEPARATOR="-" + STORE_CODE=$(echo "$STORE" | cut -d ',' -f2) + STORE_CODE=${STORE_CODE//_/-} + SCOPE="stores" + fi + SECURE_BASE_URL="https://magento${SEPARATOR}${STORE_CODE}.test/" + UNSECURE_BASE_URL="https://magento${SEPARATOR}${STORE_CODE}.test/" + + SECURE_BASE_LINK_URL="https://magento${SEPARATOR}${STORE_CODE}.test/" + UNSECURE_BASE_LINK_URL="https://magento${SEPARATOR}${STORE_CODE}.test/" + + SECURE_BASE_MEDIA_URL=$SECURE_BASE_URL"media/" + UNSECURE_BASE_MEDIA_URL=$UNSECURE_BASE_URL"media/" + + SECURE_BASE_STATIC_URL=$SECURE_BASE_URL"static/" + UNSECURE_BASE_STATIC_URL=$UNSECURE_BASE_URL"static/" + + SQL_SECURE_BASE_URL="REPLACE INTO core_config_data (value, path, scope_id, scope) VALUES ('${SECURE_BASE_URL}', 'web/secure/base_url', '${STORE_ID}', '${SCOPE}');" + echo "$SQL_SECURE_BASE_URL" + + SQL_UNSECURE_BASE_URL="REPLACE INTO core_config_data (value, path, scope_id, scope) VALUES ('${UNSECURE_BASE_URL}', 'web/unsecure/base_url', '${STORE_ID}', '${SCOPE}');" + echo "$SQL_UNSECURE_BASE_URL" + + SQL_SECURE_BASE_LINK_URL="REPLACE INTO core_config_data (value, path, scope_id, scope) VALUES ('${SECURE_BASE_LINK_URL}', 'web/secure/base_link_url', '${STORE_ID}', '${SCOPE}');" + echo "$SQL_SECURE_BASE_LINK_URL" + + SQL_UNSECURE_BASE_LINK_URL="REPLACE INTO core_config_data (value, path, scope_id, scope) VALUES ('${UNSECURE_BASE_LINK_URL}', 'web/unsecure/base_link_url', '${STORE_ID}', '${SCOPE}');" + echo "$SQL_UNSECURE_BASE_LINK_URL" + + SQL_SECURE_BASE_MEDIA_URL="REPLACE INTO core_config_data (value, path, scope_id, scope) VALUES ('${SECURE_BASE_MEDIA_URL}', 'web/secure/base_media_url', '${STORE_ID}', '${SCOPE}');" + echo "$SQL_SECURE_BASE_MEDIA_URL" + + SQL_UNSECURE_BASE_MEDIA_URL="REPLACE INTO core_config_data (value, path, scope_id, scope) VALUES ('${UNSECURE_BASE_MEDIA_URL}', 'web/unsecure/base_media_url', '${STORE_ID}', '${SCOPE}');" + echo "$SQL_UNSECURE_BASE_MEDIA_URL" + + SQL_SECURE_BASE_STATIC_URL="REPLACE INTO core_config_data (value, path, scope_id, scope) VALUES ('${SECURE_BASE_STATIC_URL}', 'web/secure/base_static_url', '${STORE_ID}', '${SCOPE}');" + echo "$SQL_SECURE_BASE_STATIC_URL" + + SQL_UNSECURE_BASE_STATIC_URL="REPLACE INTO core_config_data (value, path, scope_id, scope) VALUES ('${UNSECURE_BASE_STATIC_URL}', 'web/unsecure/base_static_url', '${STORE_ID}', '${SCOPE}');" + echo "$SQL_UNSECURE_BASE_STATIC_URL" + + SQL_WEB_COOKIE_DOMAIN="REPLACE INTO core_config_data (value, path, scope_id, scope) VALUES ('${UNSECURE_BASE_URL}', 'web/cookie/cookie_domain', '${STORE_ID}', '${SCOPE}');" + echo "$SQL_WEB_COOKIE_DOMAIN" + + SQL_WEB_COOKIE_PATH="REPLACE INTO core_config_data (value, path, scope_id, scope) VALUES ('/', 'web/cookie/cookie_path', '${STORE_ID}', '${SCOPE}');" + echo "$SQL_WEB_COOKIE_PATH" + +done diff --git a/compose/bin/setup-domain-multistore b/compose/bin/setup-domain-multistore new file mode 100755 index 000000000..92b02e3fa --- /dev/null +++ b/compose/bin/setup-domain-multistore @@ -0,0 +1,7 @@ +#!/bin/bash + +# shellcheck source=../env/db.env +source env/db.env +bin/generate-store-setters | bin/mysql +bin/update-nginx-config +bin/add-base-urls-to-hosts diff --git a/compose/bin/update-nginx-config b/compose/bin/update-nginx-config new file mode 100755 index 000000000..bf61d4168 --- /dev/null +++ b/compose/bin/update-nginx-config @@ -0,0 +1,5 @@ +#!/bin/bash +set -e + +bin/generate-nginx-mapping >config/nginx/default.conf +cd config/nginx && cat default.conf.multistore.sample >>default.conf && cp nginx.conf.multistore.sample nginx.conf diff --git a/compose/compose.dev-linux.yaml b/compose/compose.dev-linux.yaml index 8df350fa0..537250da4 100644 --- a/compose/compose.dev-linux.yaml +++ b/compose/compose.dev-linux.yaml @@ -3,8 +3,10 @@ version: "3" services: app: volumes: &appvolumes - - ./src/nginx.conf.sample:/var/www/html/nginx.conf:cached - - ./src:/var/www/html:cached + # If you want to run a multistore Magento installation uncomment the two lines below and restart the app service + # - ./config/nginx/nginx.conf:/var/www/html/nginx.conf:delegated + # - ./config/nginx/default.conf:/etc/nginx/conf.d/default.conf:delegated + - ./src:/var/www/html phpfpm: volumes: *appvolumes diff --git a/compose/compose.dev.yaml b/compose/compose.dev.yaml index 4aa8491fc..1ac37b21e 100644 --- a/compose/compose.dev.yaml +++ b/compose/compose.dev.yaml @@ -14,6 +14,9 @@ services: - ./src/dev/tools/grunt/configs:/var/www/html/dev/tools/grunt/configs:cached - ./src/nginx.conf.sample:/var/www/html/nginx.conf:cached - ./src/package.json.sample:/var/www/html/package.json:cached + # If you want to run a multistore Magento installation uncomment the two lines below, comment the one above and restart the app service + # - ./config/nginx/nginx.conf:/var/www/html/nginx.conf:delegated + # - ./config/nginx/default.conf:/etc/nginx/conf.d/default.conf:delegated #- ./src/auth.json:/var/www/html/auth.json:cached #- ./src/m2-hotfixes:/var/www/html/m2-hotfixes:cached #- ./src/patches:/var/www/html/patches:cached diff --git a/compose/config/nginx/default.conf.multistore.sample b/compose/config/nginx/default.conf.multistore.sample new file mode 100644 index 000000000..4ef3f1dfe --- /dev/null +++ b/compose/config/nginx/default.conf.multistore.sample @@ -0,0 +1,23 @@ +upstream fastcgi_backend { + server unix:/sock/docker.sock; +} + +server { + listen 8000; + return 301 https://$host$request_uri; +} + +server { + listen [::]:8443 ssl http2 ipv6only=on; + listen 8443 ssl http2; + + ssl_certificate /etc/nginx/certs/nginx.crt; + ssl_certificate_key /etc/nginx/certs/nginx.key; + + set $MAGE_ROOT /var/www/html; + + fastcgi_buffer_size 64k; + fastcgi_buffers 8 128k; + + include /var/www/html/nginx[.]conf; +} diff --git a/compose/config/nginx/nginx.conf.multistore.sample b/compose/config/nginx/nginx.conf.multistore.sample new file mode 100644 index 000000000..ff7e32d6a --- /dev/null +++ b/compose/config/nginx/nginx.conf.multistore.sample @@ -0,0 +1,255 @@ +## Example configuration: +# upstream fastcgi_backend { +# # use tcp connection +# # server 127.0.0.1:9000; +# # or socket +# server unix:/var/run/php/php7.4-fpm.sock; +# } +# server { +# listen 80; +# server_name mage.dev; +# set $MAGE_ROOT /var/www/magento2; +# set $MAGE_DEBUG_SHOW_ARGS 0; +# include /vagrant/magento2/nginx.conf.sample; +# } +# +## Optional override of deployment mode. We recommend you use the +## command 'bin/magento deploy:mode:set' to switch modes instead. +## +## set $MAGE_MODE default; # or production or developer +## +## If you set MAGE_MODE in server config, you must pass the variable into the +## PHP entry point blocks, which are indicated below. You can pass +## it in using: +## +## fastcgi_param MAGE_MODE $MAGE_MODE; +## +## In production mode, you should uncomment the 'expires' directive in the /static/ location block + +# Modules can be loaded only at the very beginning of the Nginx config file, please move the line below to the main config file +# load_module /etc/nginx/modules/ngx_http_image_filter_module.so; + +root $MAGE_ROOT/pub; + +index index.php; +autoindex off; +charset UTF-8; +error_page 404 403 = /errors/404.php; +#add_header "X-UA-Compatible" "IE=Edge"; + + +# Deny access to sensitive files +location /.user.ini { + deny all; +} + +# PHP entry point for setup application +location ~* ^/setup($|/) { + root $MAGE_ROOT; + location ~ ^/setup/index.php { + fastcgi_pass fastcgi_backend; + + fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; + fastcgi_param PHP_VALUE "memory_limit=756M \n max_execution_time=600"; + + fastcgi_param MAGE_RUN_TYPE store; + fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE; + + fastcgi_read_timeout 600s; + fastcgi_connect_timeout 600s; + + 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"; + } +} + +# PHP entry point for update application +location ~* ^/update($|/) { + root $MAGE_ROOT; + + location ~ ^/update/index.php { + fastcgi_split_path_info ^(/update/index.php)(/.+)$; + fastcgi_pass fastcgi_backend; + 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$is_args$args; +} + +location /pub/ { + location ~ ^/pub/media/(downloadable|customer|import|custom_options|theme_customization/.*\.xml) { + deny all; + } + alias $MAGE_ROOT/pub/; + add_header X-Frame-Options "SAMEORIGIN"; +} + +location /static/ { + # Uncomment the following line in production mode + # expires max; + + # Remove signature of the static files that is used to overcome the browser cache + location ~ ^/static/version { + rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last; + } + + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|html|json)$ { + 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/ { + +## The following section allows to offload image resizing from Magento instance to the Nginx. +## Catalog image URL format should be set accordingly. +## See https://docs.magento.com/user-guide/configuration/general/web.html#url-options +# location ~* ^/media/catalog/.* { +# +# # Replace placeholders and uncomment the line below to serve product images from public S3 +# # See examples of S3 authentication at https://github.com/anomalizer/ngx_aws_auth +# # resolver 8.8.8.8; +# # proxy_pass https://..amazonaws.com; +# +# set $width "-"; +# set $height "-"; +# if ($arg_width != '') { +# set $width $arg_width; +# } +# if ($arg_height != '') { +# set $height $arg_height; +# } +# image_filter resize $width $height; +# image_filter_jpeg_quality 90; +# } + + try_files $uri $uri/ /get.php$is_args$args; + + 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/ /get.php$is_args$args; + } + 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/ /get.php$is_args$args; + } + add_header X-Frame-Options "SAMEORIGIN"; +} + +location /media/customer/ { + deny all; +} + +location /media/downloadable/ { + deny all; +} + +location /media/import/ { + deny all; +} + +location /media/custom_options/ { + deny all; +} + +location /errors/ { + location ~* \.xml$ { + deny all; + } +} + +# PHP entry point for main application +location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ { + try_files $uri =404; + fastcgi_pass fastcgi_backend; + fastcgi_buffers 16 16k; + fastcgi_buffer_size 32k; + + fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; + fastcgi_param PHP_VALUE "memory_limit=756M \n max_execution_time=18000"; + + fastcgi_param MAGE_RUN_TYPE store; + fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE; + + fastcgi_read_timeout 600s; + fastcgi_connect_timeout 600s; + + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; +} + +gzip on; +gzip_disable "msie6"; + +gzip_comp_level 6; +gzip_min_length 1100; +gzip_buffers 16 8k; +gzip_proxied any; +gzip_types + text/plain + text/css + text/js + text/xml + text/javascript + application/javascript + application/x-javascript + application/json + application/xml + application/xml+rss + image/svg+xml; +gzip_vary on; + +# Banned locations (only reached if the earlier PHP entry point regexes don't match) +location ~* (\.php$|\.phtml$|\.htaccess$|\.git) { + deny all; +} diff --git a/compose/config/nginx/nginx.conf.sample b/compose/config/nginx/nginx.conf.sample new file mode 100644 index 000000000..b2d6d29ee --- /dev/null +++ b/compose/config/nginx/nginx.conf.sample @@ -0,0 +1,247 @@ +## Example configuration: +# upstream fastcgi_backend { +# # use tcp connection +# # server 127.0.0.1:9000; +# # or socket +# server unix:/var/run/php/php7.4-fpm.sock; +# } +# server { +# listen 80; +# server_name mage.dev; +# set $MAGE_ROOT /var/www/magento2; +# set $MAGE_DEBUG_SHOW_ARGS 0; +# include /vagrant/magento2/nginx.conf.sample; +# } +# +## Optional override of deployment mode. We recommend you use the +## command 'bin/magento deploy:mode:set' to switch modes instead. +## +## set $MAGE_MODE default; # or production or developer +## +## If you set MAGE_MODE in server config, you must pass the variable into the +## PHP entry point blocks, which are indicated below. You can pass +## it in using: +## +## fastcgi_param MAGE_MODE $MAGE_MODE; +## +## In production mode, you should uncomment the 'expires' directive in the /static/ location block + +# Modules can be loaded only at the very beginning of the Nginx config file, please move the line below to the main config file +# load_module /etc/nginx/modules/ngx_http_image_filter_module.so; + +root $MAGE_ROOT/pub; + +index index.php; +autoindex off; +charset UTF-8; +error_page 404 403 = /errors/404.php; +#add_header "X-UA-Compatible" "IE=Edge"; + + +# Deny access to sensitive files +location /.user.ini { + deny all; +} + +# PHP entry point for setup application +location ~* ^/setup($|/) { + root $MAGE_ROOT; + location ~ ^/setup/index.php { + fastcgi_pass fastcgi_backend; + + fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; + fastcgi_param PHP_VALUE "memory_limit=756M \n max_execution_time=600"; + fastcgi_read_timeout 600s; + fastcgi_connect_timeout 600s; + + 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"; + } +} + +# PHP entry point for update application +location ~* ^/update($|/) { + root $MAGE_ROOT; + + location ~ ^/update/index.php { + fastcgi_split_path_info ^(/update/index.php)(/.+)$; + fastcgi_pass fastcgi_backend; + 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$is_args$args; +} + +location /pub/ { + location ~ ^/pub/media/(downloadable|customer|import|custom_options|theme_customization/.*\.xml) { + deny all; + } + alias $MAGE_ROOT/pub/; + add_header X-Frame-Options "SAMEORIGIN"; +} + +location /static/ { + # Uncomment the following line in production mode + # expires max; + + # Remove signature of the static files that is used to overcome the browser cache + location ~ ^/static/version { + rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last; + } + + location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|html|json)$ { + 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/ { + +## The following section allows to offload image resizing from Magento instance to the Nginx. +## Catalog image URL format should be set accordingly. +## See https://docs.magento.com/user-guide/configuration/general/web.html#url-options +# location ~* ^/media/catalog/.* { +# +# # Replace placeholders and uncomment the line below to serve product images from public S3 +# # See examples of S3 authentication at https://github.com/anomalizer/ngx_aws_auth +# # resolver 8.8.8.8; +# # proxy_pass https://..amazonaws.com; +# +# set $width "-"; +# set $height "-"; +# if ($arg_width != '') { +# set $width $arg_width; +# } +# if ($arg_height != '') { +# set $height $arg_height; +# } +# image_filter resize $width $height; +# image_filter_jpeg_quality 90; +# } + + try_files $uri $uri/ /get.php$is_args$args; + + 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/ /get.php$is_args$args; + } + 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/ /get.php$is_args$args; + } + add_header X-Frame-Options "SAMEORIGIN"; +} + +location /media/customer/ { + deny all; +} + +location /media/downloadable/ { + deny all; +} + +location /media/import/ { + deny all; +} + +location /media/custom_options/ { + deny all; +} + +location /errors/ { + location ~* \.xml$ { + deny all; + } +} + +# PHP entry point for main application +location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ { + try_files $uri =404; + fastcgi_pass fastcgi_backend; + fastcgi_buffers 16 16k; + fastcgi_buffer_size 32k; + + fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off"; + fastcgi_param PHP_VALUE "memory_limit=756M \n max_execution_time=18000"; + fastcgi_read_timeout 600s; + fastcgi_connect_timeout 600s; + + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; +} + +gzip on; +gzip_disable "msie6"; + +gzip_comp_level 6; +gzip_min_length 1100; +gzip_buffers 16 8k; +gzip_proxied any; +gzip_types + text/plain + text/css + text/js + text/xml + text/javascript + application/javascript + application/x-javascript + application/json + application/xml + application/xml+rss + image/svg+xml; +gzip_vary on; + +# Banned locations (only reached if the earlier PHP entry point regexes don't match) +location ~* (\.php$|\.phtml$|\.htaccess$|\.git) { + deny all; +}