5

I'm trying to set up a Magento 2 site that will run with http://www.example.com/store/ as its home page, but Magento's router is treating that subdirectory path as a frontend module name, and trying to run a module called store that doesn't exist.

My base URLs are configured as such:

mysql> select * from core_config_data where path like '%url';
+-----------+---------+----------+-----------------------+-------------------------------+
| config_id | scope   | scope_id | path                  | value                         |
+-----------+---------+----------+-----------------------+-------------------------------+
|         2 | default |        0 | web/unsecure/base_url | http://www.example.com/store/ |
|         3 | default |        0 | web/secure/base_url   | http://www.example.com/store/ |
+-----------+---------+----------+-----------------------+---------- --------------------+

With this setup, I updated the Nginx config, altering the location declarations to include /store at the beginning. Once that was done I was able to access the site and static assets were loading properly, however any page I tried to access resulted in Magento's fancy 404 page.

Since I knew the request was making it into the Magento app, I had a hunch that Magento's routing was causing the issue. To test, I created a new module with a simple controller at /app/code/MyModules/Store/Controllers/Index/Index.php, and gave it a router with a frontName of store. Once I activated that module and reloaded the page, instead of a 404 I got the simple JSON output I had set up in my custom controller. So I know that Magento is getting the request and thinks the initial subdirectory that is part of its base URL is actually a frontName route.

So at this point I have two questions:

  1. Is it even possible to run a Magento 2 store in a subdirectory like this, or do I have to resort to using a subdomain?
  2. Assuming the answer to 1 is "yes, it is possible", what am I missing to make this work? I feel like there must be some setting somewhere that will resolve this, but I simply don't know where to look anymore.

Update with more details:

Since several people have made suggestions related to the actual location of the Magento application files on my server, I want to clarify that I'm running the Magento site on its own server, and using Nginx to proxy requests matching the /store path from my base server to this one. I don't think that this setup is causing any problems, but I suppose it's possible.

I also went through another diagnostic attempt, to make sure the problem is indeed where I think it is. I'll detail those steps and their results below.

  1. I updated my proxy server to send all traffic on store.example.com to the server running Magento.
  2. I updated the base URLs in core_config_data to http://store.example.com. Once this was done, I was able to access the Magento site and it behaved normally.
  3. I logged in to the Magento admin area and updated the URLs via the UI, changing both the secure and unsecure URLs to http://store.example.com/store/.
  4. Once I clicked "save" on the settings, the page reloaded and the URL changed from store.example.com/admin/admin/system_config/edit/... to store.example.com/purchase/admin/admin/system_config/edit/..., and 404ed.
  5. The basic module that I'd created earlier (with a frontName of store) still worked, and was the only page I was able to load without a 404.
  6. Further attempts to access the site on store.example.com/ were redirected to store.example.com/store/

What this tells me is Magento understands that it has a new base URL (thus the redirects to /store/), but that there is still some additional setup or configuration somewhere that must be missing, since the router is still trying to interpret that part of the URL path. Is there a separate setting for the router base path that's different from the website base URL maybe?

Update 2: The Second

I got this working in a way that feels much more like a "hack" than a solution. I've detailed that method in an answer below.

6

If you are trying to create a store only then you need to copy index.php and .htaccess from main website and then change path of

require __DIR__ . '/app/bootstrap.php';

To

require '../app/bootstrap.php';

Then change $params value

$params = $_SERVER;

$params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE] = '<store_name>';

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

.htaccess :

## path relative to web root

#RewriteBase /magento/

SetEnvIf Host .*<store_name>.* MAGE_RUN_CODE=<store_name>

SetEnvIf Host .*<store_name>.* MAGE_RUN_TYPE=website

OR

Update index.php from pub folder

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

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

try {
    require realpath(__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'],
];

switch($_SERVER['HTTP_HOST']) {
    case "<domain>":
        $params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE] = '<store_code>';
        $params[\Magento\Store\Model\StoreManager::PARAM_RUN_TYPE] = 'website';
        break;
}


$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $params);
/** @var \Magento\Framework\App\Http $app */
$app = $bootstrap->createApplication('Magento\Framework\App\Http');
$bootstrap->run($app);
  • It works fine but media files not loaded after this, can you please describe the process of adding symlinks – mjdevloper Aug 11 '17 at 18:41
4

Thanks to everyone who answered, I kept throwing your suggestions and other changes at the system and eventually arrived at a configuration that worked. I'm not in love with this solution, and I really don't know why it works, so if anyone has suggestions for how to do this better (or even just an explanation for why it works this way) I'd love to hear it.

Anyway, I left the configuration exactly the same as in my original post, with the following changes:

  1. Moved the entire contents of the /pub directory in the Magento code (which contains the index.php application entrypoint) into a new directory, /pub/store.
  2. In the following files, /pub/store/(index|get|static|cron).php, changed this line:

     require realpath(__DIR__) . '/../app/bootstrap.php';
    

    to this:

     require realpath(__DIR__) . '/../../app/bootstrap.php';
    
  3. Changed all lines in the Nginx config that looked like this:

     try_files $uri $uri/ /SOMEFILE.php?$args;
    

    to this:

     try_files $uri $uri/ /store/SOMEFILE.php?$args;
    

And... that's it. I'm still not sure how much of this is brought on by Magento and how much is Nginx. After I got this far, I tried changing the root nginx variable from $MAGE_ROOT/pub to $MAGE_ROOT/pub/store and undoing all of my Nginx config changes detailed in step 3, but that just made everything go back to the same broken behavior I saw before.

The two possible causes I can think of for this behavior are the try_files directive in Nginx behaving differently when there's a path in front of the final filename, or the Magento application actually reading the directory structure in which it resides and altering its behavior based on that. The first seems much more likely, but I still can't fathom what actual difference it's making.

As I said above, I really don't like this solution, and would prefer something better if it exists. The biggest reason I want to avoid this method is that it requires manual editing of Magento application code, which (A) is dangerous and (B) breaks future updates. If I ever want to update Magento with this setup, I'll have to go through the same process of moving the contents of the /pub directory and editing all of the .php files within with the new path to bootstap.php.

  • 1
    This was extremely helpful in getting me through a current integration I'm working on. I... didn't think it would be this difficult, as Magento2 is a fairly mature framework, but apparently I was wrong. Thank you! – colefner Dec 21 '16 at 23:49
2

My Experience
The short answer to your question is yes. Magento 2 works fine with subdirectories. I actually just pulled our website off a sub directory /store and went back to not having one. Well adding a sub directory and removing one are two different things I still ran into issues similar to what you are having. Here is what I did to debug/ fix the issue. Heads up I was not using an NGINX server.

I moved the entire Magento installation into the /store directory and then did the following; I was not aware as some of your other answers mention that there was another way to do this.

  1. From the dashboard check your configuration settings to see if it really is pulling in the correct web/unsecure/base_url and web/secure/base_url, this is under Stores > Configuration > Web. It sounds like it is but if not debug and fix this first.
  2. Through your hosting terminal or over SSH completely delete (remove) the var/di directory and var/view_processed directory.
  3. Again through your hosting terminal or over SSH run the following commands which assume you are at the root directory of your Magento installation. You may or may not need the php part and I did add extra commands because I don't know what you have done so far. None of these should harm anything.

php bin/magento cache:flush
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy
php bin/magento indexer:reindex

You may need to follow this by manually running the Full Page Cache in the admin dashboard under System > Cache management. After that make sure you hit F5 when you first check the front-end of your website so your browser refreshes its own cache of the site and everything should be working now.

The Main Problem
Magento 2 has done some amazing things to improve the user experience and speed up page load times. One of these things is improvements in caching which as you can see can cause a lot of problems for developers. When in doubt just refresh everything with the commands I posted and it usually resolves a lot of issues.

  • Thanks for your help. It's encouraging knowing that this should be theoretically possible, but unfortunately nothing listed here worked. I'm still having the same issue where Magento treats the store in the URL path as a module. I'll update my original question with more details about be specific setup and the behaviors I'm seeing. – Ben Nov 13 '16 at 18:59
  • @Ben ya I was afraid of that. So many things can go wrong with Magento. You made sure to delete the var/di and var/view_processed directories right? If not all the pages and links Magento has generated will stay the old ones without /store – Blizzardengle Nov 13 '16 at 19:53
1

Try to create subdirectory and copy index.php and .htaccess file there. Then you try to set your base url with the directory name suffix.

  • If you are trying to create a store only then you need to copy index.php and .htaccess from main website and then change path of – Ronak Chauhan Nov 12 '16 at 5:02
0

Ben, I'm extremely new to this, so this isn't really an answer, but I'm just as interested in this as you, because I named my subdirectory install "store" as well. I'm sure many have.

Have you tried changing the directory name, i.e. from "store" to "shop" or "mystore".

The difference is that I'm on a shared hosting environment and I don't believe my NGINX setup is the same.

But with my install on subdirectory /store as long as I access everything from mydomain.com with /store appended, it works fine.

0

I wrote a post about this. In Magento 2 everything goes through the /pub/ folder, so if you don't have the '/' domain in your server, you need to follow these steps https://jokiruiz.com/magento-2/how-to-run-magento-2-from-a-subdirectory/ It worked fine to me with a subfolder domain with Nginx and Magento 2.2.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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