I have two very simple services set up (in python) on google app engine. I have a site which has been up for a while as the defualt service of my example project, and I just deployed another service, lets call it foo. I have dns forwarding working for the default service, so I can go to example.com (which I own in this hypothetical scenario) and see my default service. I can also go to foo.example.appspot.com and see my foo service, which works at the url.
I have also registered another domain, let's call it foo.com. What I want is for foo.com to use my foo.example.appspot.com service. To make matters trickier, foo.com has a bunch of sub-domains of it's own, so I need x.foo.com to go to my foo service as well (and even x.y.foo.com would be ideal, but if that is hard I can work around that one easily enough by just substituting out another character so it would be x-y.foo.com or something along those lines).
I'm pretty new to web dev (which is honestly a generous description for this simple project), but Iv'e spent a while reading and googling and haven't found a solution to this, so any advice would be helpful. My last resort would be to un-service-ify (if you will) the two services, and just bundle it all up into one big main.py which routes differently depending on the domain, and then point both domains at the default service. The big downside to this is that I already have everything working with services (which seems like a better approach).
I expect to get very few users so scaling isn't really an issue (though it's always interesting to learn about).
EDIT:
attempted to create a dispatch.yaml file to solve this as follows:
dispatch:
- url: "foo.com"
module: foo
- url: "*.foo.com"
module: foo
but when I run appcfg.py -A <project_id_here> update_dispatch . it says
Error parsing yaml file:
Unable to assign value 'foo.com' to attribute 'url':
invalid url 'foo.com'
in "./dispatch.yaml", line 3, column 10
Yes, it should be possible. I didn't actually use 2 different top-level domains, but the development console appears to be ready to accept a second one (I can't actually check as I don't own a 2nd domain). Follow the Adding a custom domain for your application procedure.
Pay special attention to the Wildcard mappings section - since your foo.com domain already has sub-domains in use you can't use wildcards at/above those sub-domains, you'll have to specify the desired subdomains.
The procedure only maps (sub)domains to the app as a whole, not to individual services/modules. You'll also have to use a dispatch file, to route the specific subdomains to the corresponding modules/services. You can find examples here: https://stackoverflow.com/a/32103486/4495081 and https://stackoverflow.com/a/34111170/4495081 (the last one has rules to allow the module to work on the custom domain, on appspot.com and on the local development server).
I got it to work following The links in the answer. My dispatch file wound up looking like this:
dispatch:
- url: "foo.com/*"
module: foo
- url: "*.foo.com/*"
module: foo
Related
Having multiple languages to deploy under appengine; I wonder if some kind of private approach could be applied; in order to have it all resides only under a single domain
For example, given xyz.com domain setup as wildcard; having a default service, services svc1 and svc2; and a dispatch.yaml mapping */svc1/* to svc1 service and */svc2* to svc2 service; how to :
hide all the *.appspot domain ?
hide the automatic setup of svc1.xyz.com and svc2.xyz.com ?
It could be easy for a given service to check the host and redirect to the desired one; but it would have to be done for every services; feels like there a better way
It feels a bit messy to have all those auto enopoints opened and unused, the idea would be to have it all under xyz.com/
-
There is no way of hiding all the routes of the .appspot domain. As you probably are aware the dispatch.yaml, only works as a redirect. Probably, you cannot just disable the default domain, since there are a lot of tools like Cloud Tasks, Cron Jobs etc.. that uses that default domain, hitting those endopoints.
As for the second question, you cannot hide them, but in case you don't need them, you can overwrite them in the dispatch.yaml to point to some custom made "not found" page.
I have this:
- url: "awesome.com/*"
service: awesome
- url: "www.awesome.com/*"
service: awesome
Is possible to do this? to achieve same as above?
- url: "*.awesome.com/*"
service: awesome
No, what that last option you mentioned would do is map all subdomains of awesome.com to the service awesome, as you can see in this example corresponding to mapping subdomains in the documentation.
Here you have more information about mapping custom domains.
Yes, it's possible to do that. But it won't be equivalent with what you have now:
it won't match your top-level domain awesome.com which is matched by your current 1st rule
it'll match any <blah>.awesome.com subdomain, your current set of rules only matches the www.awesome.com subdomain
If indeed you want to send requests for both the full domain as well as all its subdomains to the awesome service you can achieve that simply by the custom domain mapping/config itself (which you need to do explicitly for the domain and each subdomain anyways), no need for a dispatch file.
Note that you'd still need to deploy a default service, see Why do I need to deploy a "default" app before I can deploy multiple services in GAE?. Might as well just let the awesome service be the default one in this case, less confusing and less room for trouble IMHO.
I'm looking at various pages about dispatch.yaml, most of which contain similar information and examples:
https://cloud.google.com/appengine/docs/flexible/nodejs/how-requests-are-routed#routing_with_a_dispatch_file
https://cloud.google.com/appengine/docs/python/config/dispatchref
https://cloud.google.com/appengine/docs/go/config/dispatchref
etc.
I happen to be using node.js on GAE Flexible Environment, but I think it would be the same for every language and environment.
The problem is that these pages don't really specify how dispatch.yaml works. In particular:
Are rules applied in the order given? I'm assuming that the first matching rule is the one used, but nothing seems to say so.
Do leading glob (wildcard) characters match only the domain name, or could they match the first part of the URL's path? If the rule is */hello, would that match myapp.appspot.com/path/hello? I'm guessing not, based on some vague hints in the docs, but it isn't very clear.
If no rule in dispatch.yaml matches the URL, will it be routed to the default service? I would think it would have to, but again, these pages don't say.
Do URLs get rewritten based on the rules before they're sent to the service? If the rule is */path/* and the URL is https://myapp.appspot.com/path/hello, will the service see it as /path/hello or as /hello? I'm guessing the former.
I'm doing some trial and error now, so I may be able to answer my own question soon. I'm also submitting this to Google through their documentation feedback system.
Things I know so far:
Yes, rules are tried in order. So for example, if you want one URL to go to a specific service, and all other URLs to go to another service, you should specify the specific one first:
dispatch:
- url: "*/specific"
module: specific
- url: "*/*"
module: general
If you put those rules in the opposite order, module specific will never be used, because the URL /specific will be caught by the wildcard rule.
Unknown
Yes. You can test this by making a request not matching any dispatch.yaml rule and watching the default's service logs.
No rewriting. If the rule is */path/* and the actual URL is https://myapp.appspot.com/path/hello, your service should still handle /path/hello, not /hello.
Just to fill in the blank (feel free to paste this into the accepted answer):
No. It only matches the start of the path.
I created two apps with the following resources:
default -> /abc/def/test.html -> <h1>default</h1>
other -> /abc/def/test.html -> <h1>other</h1>
And 1 route:
<dispatch>
<url>*/def/*</url>
<module>other</module>
</dispatch>
When I hit {app engine}/abc/def/test.html I got "default"
I actually asked this question before, but I cannot get my account details back, so I'm asking again:
I have a series of different domain names that I would like to all point (via URL forwarding from my domain host) to a google app engine application that reads what the forwarding URL is. So if the domain typed in was original XYZ.com, then when I am forwarded to my application, I can return what that original domain name was. I'm using the python variant. How best can I do this without coding for each and every variant?
So for example I might have aaa.com and bbb.com and ccc.com that all should point to the same appspotdomain, and I wish to somehow determine what the referring URL was. I have thousands of domains and I have URL forwarding set-up. So unless I put something in the header is there a smart way to pull out the referring URL. I have tried the os.environ["SERVER_NAME"] route but this just gives the app-engine domain.
Try
os.environ['HTTP_REFERER']
or
self.request.headers['Referer']
Be careful though, it might not always be available.
Here is what I'd like to achieve
http://foo.somedomain.com gets handled by
http://myapp.appspot.com/foo (google appengine app myapp)
and the underlying url is masked.
Note the following:
somedomain.com is a third party domain that would like to add foo.somedomain.com
mydomain.com would be CNAME'd to myapp.appspot.com
mydomain.com/foo would point to myapp.appspot.com/foo
other scenarios
can foo.mydomain.com be made to point to myapp.appsot.com/foo
can foo.somedomain.com point directly to myapp.appspot.com/foo
Added: myapp.appspot.com is developed using django w/ app-engine-patch
You can't do this in the way described. In order to do this, you need to:
CNAME foo.somedomain.com to ghs.google.com (not to myapp.appspot.com)
Set up Google Apps for your Domain on somedomain.com, if it's not already
Add the app 'myapp' to foo.somedomain.com through the Apps control panel
Once that's done, your app can check self.request.host to determine which hostname was sent, and route requests appropriately.
You can parse the sub-domain from the Host header, then call the webapp.RequestHandler appropriate for the path /[sub-domain], assuming *.yourdomain.com is directed to the Google App Engine application.
Have a look at webapp.WSGIApplication and see if there's a way to get the mapped webapp.RequestHandler for a path. Alternatively, you might be able to modify the request object to change the requested path (this I'm not sure about, however.)
This question was asked in one of the 2009 Google I/O app engine talks. Unfortunately the answer given was along the lines of not supported at this time but the possibilities of some workarounds may exist. 2009 Google I/O videos