I have a question and I'm not sure if anyone can help me.

I found out that I have to set webroot to the pub/ folder.

So what I did was basically change the document root for my domain in my cpanel - addon domains to /public_html/magento2/pub.

I know that it is pointing to the pub and my website works.

However when the email for product alert sends out the email. All the pictures are broken links. When I inspect the pictures on my browser, the link adds the /pub/media.....

However my domain should be pointing to the pub folder and should not add the pub again.

Can anyone let me know if it is normal and also the way I change the document root to /pub is the correct way?

I have a the managed cloud hosting with Siteground.

Thank you


2 Answers 2


What if you try adding the following to the end of your app/etc/env.php, then doing the usual cache flush and static content deploy:

'directories' => [
    'document_root_is_pub' => true,

I've had to add this flag to two clients of mine now in order to get sitemap.xml and robots.txt files to be generated in the pub folder. The clients are running the following versions of Magento:

  • Client 1: Magento Commerce 2.2.4
  • Client 2: Magento Commerce 2.3.2

I wonder if that might also affect the urls for content like emails generated from crons (Product Alerts, etc.).

Cron/Cli Processes vs Web Requests

Processes that run via cron or cli are a little different than ones that happen as a result of web requests hitting the web server. They are not processed as web requests, so there isn't really a concept of DOCUMENT_ROOT and in turn no request hitting pub/index.php.

When the web server's document root is set to the pub folder, web requests WILL hit pub/index.php which is actually where the media path is configured differently to exclude pub from it:


$params[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] = array_replace_recursive(
    $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'],

As opposed to serving from MAGENTO_ROOT/index.php where the default config below ends up being used that includes pub in the various paths:


public static function getDefaultConfig()
    $result = [
        self::ROOT => [parent::PATH => ''],
        self::APP => [parent::PATH => 'app'],
        self::CONFIG => [parent::PATH => 'app/etc'],
        self::LIB_INTERNAL => [parent::PATH => 'lib/internal'],
        self::VAR_DIR => [parent::PATH => 'var'],
        self::CACHE => [parent::PATH => 'var/cache'],
        self::LOG => [parent::PATH => 'var/log'],
        self::DI => [parent::PATH => 'generated/metadata'],
        self::GENERATION => [parent::PATH => Io::DEFAULT_DIRECTORY],
        self::SESSION => [parent::PATH => 'var/session'],
        self::MEDIA => [parent::PATH => 'pub/media', parent::URL_PATH => 'pub/media'],
        self::STATIC_VIEW => [parent::PATH => 'pub/static', parent::URL_PATH => 'pub/static'],
        self::PUB => [parent::PATH => 'pub', parent::URL_PATH => 'pub'],
        self::LIB_WEB => [parent::PATH => 'lib/web'],
        self::TMP => [parent::PATH => 'var/tmp'],
        self::UPLOAD => [parent::PATH => 'pub/media/upload', parent::URL_PATH => 'pub/media/upload'],
        self::TMP_MATERIALIZATION_DIR => [parent::PATH => 'var/view_preprocessed/pub/static'],
        self::TEMPLATE_MINIFICATION_DIR => [parent::PATH => 'var/view_preprocessed'],
        self::SETUP => [parent::PATH => 'setup/src'],
        self::COMPOSER_HOME => [parent::PATH => 'var/composer_home'],
        self::GENERATED => [parent::PATH => 'generated'],
        self::GENERATED_CODE => [parent::PATH => Io::DEFAULT_DIRECTORY],
        self::GENERATED_METADATA => [parent::PATH => 'generated/metadata'],
    return parent::getDefaultConfig() + $result;

Update #1

After doing a little more digging, it does look like the CLI checks that directories/document_root_is_pub flag mentioned above to alter directory path configs based on the value. Since the cron technically runs from calling a cli command (php bin/magento cron:run), it does look like this might be affecting the urls:


private function documentRootResolver(array $config = []): array
    $params = [];
    $deploymentConfig = $this->serviceManager->get(DeploymentConfig::class);
    if ((bool)$deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_DOCUMENT_ROOT_IS_PUB)) {
        $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'],

    return array_merge_recursive($config, $params);

I've just set the docroot to pub following the Magento documentation but I also had to run

bin/magento setup:upgrade
bin/magento setup:di:compile

and redeploy static content to get the files to serve from the correct path.

Your Answer

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

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