Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation for additional domains #37

Merged
merged 2 commits into from
Nov 15, 2019

Conversation

erikhansen
Copy link
Contributor

I created this readme based on #14

I didn't explicitly test each of the exact commands that I added, but I believe they should work based on running them for different domains locally.

@molotovbliss
Copy link

@erikhansen Thanks for this, I was just digging into how to go about doing multi-store subdomain setup with warden.

@mandatoryhashtags
Copy link

@erikhansen I can confirm this works. I just tested it. Great work as always my friend.

@davidalger davidalger merged commit 7db2233 into wardenenv:master Nov 15, 2019
@davidalger
Copy link
Collaborator

Thanks for the contribution @erikhansen!

@erikhansen
Copy link
Contributor Author

@mandatoryhashtags and @molotovbliss If either of you spend time figuring out how to configure Nginx to route specific domains to specific MAGE_RUN_CODE values, feel free to submit a PR to add that to the documentation. :) I have yet to make time to do that.

@erikhansen erikhansen deleted the patch-3 branch November 16, 2019 15:22
@davidalger
Copy link
Collaborator

@erikhansen What I've done to set those env vars based on domains is add a file at app/etc/stores.php with the following contents:

<?php

use \Magento\Store\Model\StoreManager;
$serverName = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : null;

switch ($serverName) {
    case 'exampledomain1.clnt.test':
        $runCode = 'examplecode1';
        $runType = 'website';
        break;
    case 'exampledomain2.clnt.test':
        $runCode = 'examplecode2';
        $runType = 'website';
        break;
    default:
        return;
}

if ((!isset($_SERVER[StoreManager::PARAM_RUN_TYPE])
        || !$_SERVER[StoreManager::PARAM_RUN_TYPE])
    && (!isset($_SERVER[StoreManager::PARAM_RUN_CODE])
        || !$_SERVER[StoreManager::PARAM_RUN_CODE])
) {
    $_SERVER[StoreManager::PARAM_RUN_CODE] = $runCode;
    $_SERVER[StoreManager::PARAM_RUN_TYPE] = $runType;
}

Then in composer.json add this to list of files which are auto loaded:

{
    "autoload": {
        "files": [
            "app/etc/stores.php"
        ]
    }
}

This is similar to using magento-vars.php on Magento Commerce Cloud, but using composer to load the file:
https://devdocs.magento.com/guides/v2.3/cloud/project/project-multi-sites.html

@erikhansen
Copy link
Contributor Author

@davidalger Great, thanks. Want me to submit a PR to add this to the readme? If you don't think it belongs embedded in the readme, I could link to your comment from the readme?

This was referenced Dec 7, 2019
@vbuck
Copy link
Contributor

vbuck commented Jan 6, 2020

@davidalger would you say that the stores.php include is production-safe? I get that Magento Cloud is using a similar approach, but I'm not sure it's clear to developers who will commit changes to composer.json that running composer install from that state during a build will generate an autoloader which runs this file.

And therefore, they must decide whether to manage run codes here, or in the traditional host/vhost configuration for their web services, across environments.

@davidalger
Copy link
Collaborator

davidalger commented Jan 6, 2020

@vbuck I would consider this production safe. My personal preference is to enforce and specify these codes via an Nginx map in production environments, but I've seen a similar file to the above used successfully in production on some large scale projects for routing of the production names. I have high-traffic projects running an almost near copy of the above for local dev, but utilizing map on production for routing with no issues encountered.

As-written the example above should not impact execution unless the switch case matches a host name, falling back to a simple return doing effectively nothing. With OpCache enabled and used on production, the performance impact of this will be no more than a few additional CPU instructions to execute the switch. If you wanted to use the stores.php file for production configuration as well, simply add the hostnames to the switch case.

Why I like this for local development use is because it allows configuring the environment for multiple hostnames without requiring a developer to customize Nginx configuration (which in context of Warden, would require mounting a config file into the container, and be more configuration heavy).

It's not documented in an issue yet, but Warden 0.2.0 will essentially make inclusion of the stores.php file the only configuration required for multi-domain to work as long as sub-domains of the same domain (i.e. sub1.clnt.test and sub2.clnt.test are used vs site1.test and site2.test):

Added native support for multi-domain projects without requiring per-project routing configuration. This is accomplished using wildcard rules in the new Traefik labeling configuration allowing Warden to automatically route any sub-domain of the TRAEFIK_DOMAIN value in .env to the nginx and/or varnish container for handling by the application.

@vbuck
Copy link
Contributor

vbuck commented Jan 6, 2020

Great, thanks for weighing in on it. It makes sense to run it this way, but as an extension to #37 it would still be good to see some documentation about how this could affect/benefit projects in production.

@davidalger
Copy link
Collaborator

Quick note: An updated version including all of the above and which is Warden 0.2.0 compliant has been added here: https://docs.warden.dev/configuration/multipledomains.html

@norgeindian
Copy link
Contributor

@davidalger , I followed your documentation about multiple domains, but somehow it does not work in my case.
So I have two urls, which I want to handle in the app/etc/stores.php like you advised.
Let's call them app.base.test and app.alternative.test.
base is my WARDEN_ENV_NAME.
My warden-env.yml now looks like this:

version: "3.5"
services:
  varnish:
    labels:
      - traefik.http.routers.${WARDEN_ENV_NAME}-varnish.rule=
        HostRegexp(`{subdomain:.+}.${TRAEFIK_DOMAIN}`)
        || Host(`${TRAEFIK_DOMAIN}`)
        || HostRegexp(`{subdomain:.+}.alternative.test`)
        || Host(`alternative.test`)
  nginx:
    labels:
      - traefik.http.routers.${WARDEN_ENV_NAME}-nginx.rule=
        HostRegexp(`{subdomain:.+}.${TRAEFIK_DOMAIN}`)
        || Host(`${TRAEFIK_DOMAIN}`)
        || HostRegexp(`{subdomain:.+}.alternative.test`)
        || Host(`alternative.test`)
  php-fpm:
    extra_hosts:
      - alternative.test:${TRAEFIK_ADDRESS:-0.0.0.0}
      - sub1.alternative.test:${TRAEFIK_ADDRESS:-0.0.0.0}

  php-debug:
    extra_hosts:
      - alternative.test:${TRAEFIK_ADDRESS:-0.0.0.0}
      - sub1.alternative.test:${TRAEFIK_ADDRESS:-0.0.0.0}

Now I try to handle the requests from the two domains differently in my app/etc/stores.php using $_SERVER['HTTP_HOST'].
Unfortunately the host is always app.base.test, no matter which URL I initially call.
So any calls to app.alternative.test are directly redirected and as soon as I reach my stores.php I have no option to find out which URL was initially called.
So I expect something to be wrong in my warden-env.yml. Could you shortly give me a hint what I do wrong?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants