11

We would like to create multiple websites in Magento 2. There is an article about this topic in the Official Magento 2 Documentation, but the way they describe is not suitable for our case.

They are suggesting to use sub-domains in order to determine different websites, such as

  • website1.magento-site.com
  • website2.magento-site.com

We would like to use sub-folders instead of sub-domains. To give an example,

  • magento-site.com/website1
  • magento-site.com/website2

How can we overcome this issue on Nginx web server?

My Configuration

I am using Ubuntu 16.04. I have installed Nginx, and have not changed any Nginx core configuration. I have created a file magento-site.com.conf inside /etc/nginx/sites-enabled/magento-site.com.conf.

/etc/nginx/sites-enabled/magento-site.com.conf

server {
    listen 8080;
    server_name magento-site.com;

    set $MAGE_RUN_CODE website1;
    set $MAGE_ROOT /var/www/magento-site.com;
    include /var/www/magento-site.com/nginx.conf;
}

EDIT 1: (2017-10-23)

I have multiple stores for each website.

3
  • you just need to add rewrites for your new path
    – MagenX
    Sep 30, 2017 at 11:18
  • There are a lot of rewrites and try_file blocks in nginx.conf already. If you look at fresh Magento 2 installation, you will see an nginx.conf with a lot of configurations. Sep 30, 2017 at 14:57
  • @MagenX Can you explain more please? Where exactly should I put the rewrite? Oct 19, 2017 at 19:32

4 Answers 4

5

What about a pure nginx solution with this double map ?

First, for the web site (thanks @MagenX)

map $request_uri $MAGE_RUN_CODE {
    default website1;
    ~^/website1/.*  website1;
    ~^/website2/.*  website2;
}

A second for the new request uri

map $request_uri $REQUEST_URI {
    default  $request_uri;
    "~*^/(website[0-9])(?<p>.*)" $p;
}

And finally, dont forget to set the new computed REQUEST_URI

location ~ \.php$ {
(...)
   include fastcgi_params;
   fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE;
   fastcgi_param REQUEST_URI $REQUEST_URI;
(...)
}
4
  • This answer is way better, thank you for sharing. Sep 17, 2020 at 10:32
  • If you override REQUEST_URI, you get infinite-redirection. Sep 17, 2020 at 10:58
  • It is working. But for static assets I am getting 404 for all.How do I solve if you can guide? Nov 28, 2020 at 12:22
  • @MagentoLearner can you tell me a little more ? what the path of an assets getting a 404 ? Nov 29, 2020 at 21:03
15

I have tried numerous ways to achieve this task. I would like to thank @matias-hidalgo for his contributions, although I did not understand his answer at first read :).

Here is the scenario. We have two different websites, and each website has two different store views as follows:

Website 1

  • Website 1 (E-commerce)
  • Website 1 (Venda Assistida)

Website 2

  • Website 2 (E-commerce)
  • Website 2 (Venda Assistida)

In my solution, we are going to change some configuration in Magento Admin. Then we are going to create some sub-folders, and finally we are going to modify nginx.conf.

First of all, we need to make some configuration change in the Magento Admin. Go to Stores -> Configuration -> General -> Web. We need to change Base URLs for each store view.

For Default Config

Please provide the following configuration for default config. enter image description here

For Website 1 (E-commerce) and Website 1 (Venda Assistida)

Please provide the following configuration for all Website 1 store views. enter image description here

For Website 2 (E-commerce) and Website 2 (Venda Assistida)

Please provide the following configuration for all Website 2 store views. enter image description here

Secondly, we need to create website1 and website2 folders in the /pub directory. In the final, you should have the following folders:

  • MAGENTO_ROOT/pub/website1
  • MAGENTO_ROOT/pub/website2

Copy the pub/index.php file into these directories. Then we will make some changes in MAGENTO_ROOT/pub/website1/index.php and MAGENTO_ROOT/pub/website2/index.php.

Content of MAGENTO_ROOT/pub/website1/index.php

I have only changed 3 lines:

1st Line: require __DIR__ . '/../../app/bootstrap.php';

2nd Line: $params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE] = 'website1';

3rd Line: $params[\Magento\Store\Model\StoreManager::PARAM_RUN_TYPE] = 'website';

<?php
/**
 * Public alias for the application entry point
 *
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

use Magento\Framework\App\Bootstrap;
use Magento\Framework\App\Filesystem\DirectoryList;

try {
    require __DIR__ . '/../../app/bootstrap.php';
} catch (\Exception $e) {
    echo <<<HTML
<div style="font:12px/1.35em arial, helvetica, sans-serif;">
    <div style="margin:0 0 25px 0; border-bottom:1px solid #ccc;">
        <h3 style="margin:0;font-size:1.7em;font-weight:normal;text-transform:none;text-align:left;color:#2f2f2f;">
        Autoload error</h3>
    </div>
    <p>{$e->getMessage()}</p>
</div>
HTML;
    exit(1);
}

$params = $_SERVER;
$params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE] = 'website1';
$params[\Magento\Store\Model\StoreManager::PARAM_RUN_TYPE] = 'website';
$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = [
    DirectoryList::PUB => [DirectoryList::URL_PATH => ''],
    DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'],
    DirectoryList::STATIC_VIEW => [DirectoryList::URL_PATH => 'static'],
    DirectoryList::UPLOAD => [DirectoryList::URL_PATH => 'media/upload'],
];

$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
/** @var \Magento\Framework\App\Http $app */
$app = $bootstrap->createApplication(\Magento\Framework\App\Http::class);
$bootstrap->run($app);

For the final touch, we need to modify nginx.conf in your MAGENTO_ROOT directory. Please put the following configuration into your nginx.conf.

location /website1 {
    root /website1;
    if (!-e $request_filename) {
        rewrite ^/(.*)$ /website1/index.php last;
        break;
    }
}

location /website2 {
    root /website2;
    if (!-e $request_filename) {
        rewrite ^/(.*)$ /website2/index.php last;
        break;
    }
}

After all this configurations and modifications, you will be able to use websites as sub-folders. I hope it helps.

14
  • 1
    Only problem i am facing with this configration is static content not working
    – Aman Alam
    Apr 14, 2018 at 20:28
  • @AmanAlam Did you change base url for static content as described? We have tested this configuration with 2 different clients in Magento 2.1. Apr 14, 2018 at 23:25
  • Yes changed base url as described and its working now thank you
    – Aman Alam
    Apr 15, 2018 at 17:27
  • 1
    @Bunyamin I followed the same method. Home page is working but category and product page are giving 404 error. Any suggestion? can you help me in that.
    – Jaimin
    May 2, 2018 at 13:56
  • 1
    @Jaimin, use above code in nginx.conf.sample not in nginx.conf. It will fix your problem.
    – umair ayub
    May 3, 2018 at 9:28
4
+50

By Nginx configuration you can use this example configuration:

server {
    listen 80;
    ## SSL directives might go here
    server_name local.magento2.com;
    root /PATH/TO/YOUR/MAGENTO/pub;

    location / {
        index index.html index.php; ## Allow a static html file to be shown first
        try_files $uri $uri/ @handler; ## If missing pass the URI to Magento's front handler
        expires 30d; ## Assume all files are cachable
    }

    location /your/subfolder {
        root /your/subfolder;
        if (!-e $request_filename) {
            rewrite ^/(.*)$ /your/subfolder/index.php last;
            break;
        }
        #limit_conn iplimit 50;
    }

    location @handler { ## Magento uses a common front handler
        rewrite / /index.php;
    }

    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)$ {
            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 ~ .php/ { ## Forward paths like /js/index.php/x.js to relevant handler
        rewrite ^(.*.php)/ $1 last;
    }

    location ~ .php$ { ## Execute PHP scripts
        if (!-e $request_filename) {
            rewrite / /index.php last;
        }
        expires        off;
        #fastcgi_pass   unix:/run/php/php5.6-fpm.sock;
        fastcgi_pass   unix:/run/php/php7.0-fpm.sock;
        fastcgi_read_timeout 10m;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        #fastcgi_param  MAGE_RUN_CODE $mage_run_code;
        #fastcgi_param  MAGE_RUN_TYPE store;
        #fastcgi_param  MAGE_MODE developer; # default or production or developer
        include        /etc/nginx/fastcgi_params;
    }
}

and use this index.php as an example:

/PATH/TO/YOUR/MAGENTO/pub/your/subfolder/index.php
<?php
use Magento\Framework\App\Bootstrap;
use Magento\Framework\App\Filesystem\DirectoryList;
try {
    require __DIR__ . '/../../../app/bootstrap.php';
} catch (\Exception $e) {
    echo <<<HTML
<div style="font:12px/1.35em arial, helvetica, sans-serif;">
    <div style="margin:0 0 25px 0; border-bottom:1px solid #ccc;">
        <h3 style="margin:0;font-size:1.7em;font-weight:normal;text-transform:none;text-align:left;color:#2f2f2f;">
        Autoload error</h3>
    </div>
    <p>{$e->getMessage()}</p>
</div>
HTML;
    exit(1);
}

$params = $_SERVER;
$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = [
    DirectoryList::PUB => [DirectoryList::URL_PATH => ''],
    DirectoryList::MEDIA => [DirectoryList::URL_PATH => 'media'],
    DirectoryList::STATIC_VIEW => [DirectoryList::URL_PATH => 'static'],
    DirectoryList::UPLOAD => [DirectoryList::URL_PATH => 'media/upload'],
];
$params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE] = 'website_code';
$params[\Magento\Store\Model\StoreManager::PARAM_RUN_TYPE] = 'website';
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
$app = $bootstrap->createApplication('Magento\Framework\App\Http');
$bootstrap->run($app);

In order to clarify:

In my vhost nginx configuration you will find this:

    location /your/subfolder {
        root /your/subfolder;
        if (!-e $request_filename) {
            rewrite ^/(.*)$ /your/subfolder/index.php last;
            break;
        }
        #limit_conn iplimit 50;
    }

where the first "/your/subfolder" can be changed for whatever you want as website url. ex www.mywebsite.com/stack/magento -> /stack/magento

Then in order to define the website code which will be loaded into this url you have to create the index.php writing the website code here:

$params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE] = 'website_code';

I hope this now is clear enough, I've to spend time in a project to get this done so I know it works and it's closer as how we used to do it on M1.

7
  • I don't understand how this will solve my problem. I specifically asked how to use multiple website. Are you suggesting that this code can be also used for websites? Oct 20, 2017 at 11:43
  • You said "We would like to use sub-folders instead of sub-domains." I'll update my answer now clarifying where each Subfolder config is Oct 20, 2017 at 11:58
  • Yes, I said that. I also said that I would like to use multiple websites with sub-folders. I just don't understand what is store-code doing there? Oct 20, 2017 at 12:01
  • That was just a suggestion, if your store codes are good enough you don't need to deal with nginx configuration... have a look now to my explanation Oct 20, 2017 at 12:08
  • So you are saying that if my store code and website code match, this will work. I also have multiple stores for each website. Oct 23, 2017 at 12:21
1

in your domain.conf in "etc/nginx" you need to create a map.

for example:

map $http_host$uri $MAGE_RUN_CODE { 
   ~*^(www\.)?magento-site\.com/website1/.*  website1;
   ~*^(www\.)?magento-site\.com/website2/.*  website2;
}

or

map $request_uri $MAGE_RUN_CODE {
    default default;
    ~^/website1/.*  website1;
    ~^/website2/.*  website2;
}
4
  • 1
    You are describing the sub-domain way. What I want is sub-folder way. I do not want website1.magento-site.com, but I want magento-site.com/website1. Oct 19, 2017 at 19:29
  • you can map your sub-folder the same way, and add regex rewrite for sub-path map $http_host$uri $MAGE_RUN_CODE
    – MagenX
    Oct 20, 2017 at 8:03
  • I tried this method, just gives a 404. Nov 9, 2017 at 21:38
  • @MagenX I've seen you suggest this method on another post, however you never go into detail on the exact directions to get this working properly. Care to share? Nov 10, 2017 at 0:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.