SPA on GAE. Best way to host frontend - google-app-engine

I'm developing a Single Page Application on Google App Engine.
The backend will be in Go and the frontend in React.
For the backend I would like to use Google Endpoints.
This can't be used with a custom domain so I will use CORS:
https://code.google.com/p/googleappengine/issues/detail?id=9384
But now the question is how should I host the frontend. These are just static files. Should I use a separate GAE project for this? Is there a better solution?

GAE can easily serve static files, just mark them as static in your app.yaml.
https://cloud.google.com/appengine/docs/go/config/appconfig#Go_app_yaml_Static_file_pattern_handlers
For efficiency, App Engine stores and serves static files separately
from application files. Static files are not available in the
application's file system.
Example:
handlers:
# All URLs ending in .gif .png or .jpg are treated as paths to static files in
# the static/ directory. The URL pattern is a regexp, with a grouping that is
# inserted into the path to the file.
- url: /(.*\.(gif|png|jpg))$
static_files: static/\1
upload: static/.*\.(gif|png|jpg)$
I believe they are served from Google's general infrastructure, from a datacenter near to the end user. So it seems like a good idea to do it like this.
In fact for a SPA you will find instances will not spin up if you just serve static files :)
CORS support details also available on that link.

Related

How to direct www to non-www domain on Google App Engine (GAE)

How do I direct the www. subdomain to just domain.tld without www? I'm used to firebase doing this automatically. Should I look into configuring the app.yaml, dispatch.yaml, or another method?
What you're describing is called a "naked domain", and this is described in the documentation on Custom Domains. The documentation provides the steps for mapping a custom domain to your app and updating the DNS records at your domain registrar once your service has already been mapped to your custom domain in App Engine.
To redirect your requests, you can use wildcard mappings with services in App Engine by using the dispatch.yaml file. You can find instructions on how to do that here. If you would like to know more about routing requests, you can take a look at this documentation as well which also highlights creating a dispatch file. Handlers are limited to handle URLs by executing application code, or by serving static files uploaded with the code, such as images, CSS, or JavaScript. Therefore, they cannot directly redirect one URL to another.
You would need to handle your URL by running a script that executes code that will redirect your URL.
The comment shows a complete example as the script runs main.py which then redirects the URL

Which parts of a built NextJS app should I protect?

I'm running a NextJS app from an Express server and I have authentication set up. The Express server will forward most requests to the NextJS app with some preprocessing. In the NextJS app, there are the explicit routes and api routes that I set up myself in the /pages directory of the source code, but there are also a lot of assets being requested from paths starting with /_next/.
When running an authenticated service, it is clear that you normally don't have to protect ALL of your assets. For example robots.txt and favicon.ico belong to the category of assets that do not need authentication and the same goes for many static assets.
My question is, which ones of NextJS's own routes should I protect? It seems that /_next/static/* mostly contain static source files that do not need any custom input data and that /_next/data/* contains personalized information that should be protected, thus it seems reasonable to protect the latter but not the former.
Are there other routes that NextJS serves from a built app (other than routes to assets in the /public folder and routes in the pages directory) that I should know about and is it reasonable to only protect /_next/data/* or should I protect all of /_next/*?

app engine dispatch static files to a CDN url

We want all our static requests to an CDN, and the CDN is a Google Storage Object.
expamle.come/static/file.js => cdnurl.com/example-bucket/file.js
And since we're using Storage Objects from the same platform ( Google obviously), we thought this should be a piece of cake, but I couldn't find any doc in Google.
here's our current dispatch.yaml.
dispatch:
# Default service serves simple hostname request.
- url: "*/example.com"
service: default
# Send all api traffic to the api backend.
- url: "*/api/*"
service: backend
We want this :
# Send all api traffic to the static CDN.
- url: "*/static/*"
ourbound: https://cdn/our-bucket/static/*
On a side note, is it a good idea to have another service that uses an NGINX in front of our app that does this?
The purpose of the dispatch.yaml file is to route requests to different services rather than to define url to serve the static files. You can nonetheless define which service will take care of serving the static files. The, to define where and how the static files are retrieved you should modify the app.yaml of the service that will handle the requests, in this case the app.yaml for the default service.
One option would be to serve the static files directly from the application. For this you just need to put the files in the ./public folder and set your handlers as explained in the following part of the documentation.
Second option would be to let Google Cloud Storage serve the static files. This would require creating a bucket, putting the assets therein and allowing public access to the files. This might be done through the urls provided by Cloud Storage as could be seen here.
Regarding your question of load balancing, I don't think it makes sense to put another service for GAE service for load balancing as it is not the intended use for such product.

How do you undeploy 'helloworld.go' from App Engine Quickstart, and instead point to a html in bucket?

I'm trying to learn about hosting websites on GCP, and have just finished the App Engine Quickstart, which gave me a working appspot.com domain which runs off helloworld.go.
But now I want to try a pre-made html template (contains .html, .DS_STORE, and css/fonts/images/js folders) that I have tested to be working locally.
Following the "Hosting a Static Website" tutorial, I have uploaded the html template folder into my bucket "... .appspot.com", and enabled the entire bucket to be publicly viewable/readable. Then I disabled and re-enabled the App Engine session to try and get it to reset.
However, the URL still loads the default "Hello, world" plaintext used in the Quickstart.
I may have a pretty fundamental misunderstanding of how web hosting on App Engine works. Could someone please check if what I'm trying to do is reasonable, and if so, how do I actually do it?
EDIT: I have also had success deploying other code samples included with Quickstart, but still haven't figured out how to ignore those and deploy directly from bucket.
I understand that you have a static HTML page in your Google Cloud Storage bucket and you want that app your App Engine application points to that html page.
It is possible to do that, just taking the files from the bucket and then printing the content, but if you just want a static page, the best option could be the following:
Create a bucket and upload ONLY the static template in that bucket, please, don't upload sensitive information there.
click in the three dots at the right to edit the permissions of the bucket.
give the "Storage Object Viewer" role to the member "allUsers"
enter into your bucket and click into the the public link of your index.html
The link will be something like: https://storage.googleapis.com/< YOUR_BUCKET >/index.html
EDIT
As requested by the OP, the link https://storage.googleapis.com/< YOUR_BUCKET >/index.html it's really long and not too friendly, for that reason this is a small tutorial of how to attach a custom domain to your Google Cloud Storage bucket.
Create a domain, you can use Google Domains or if you just want a free domain, you can use something like Freenom and get your domain for free.
Go to Google Search Console and follow the small tutorial, this is just to verify that your domain it is actually yours. It will ask you to upload a file into your domain. To do this it's as simple as
2.1. pointing your domain to the external IP of a Compute Engine Instance
that you own with apache installed and the file in there.
2.2. You can use the pre-made Compute Engine instance with lamp in the
Marketplace.
2.3. Just upload the file provided by Google in
/var/www/html/ inside of your new instance.
2.4. Once your verification is done, delete this Compute Engine instance to
not to waste money.
3.Create a bucket with the same name as your verified domain, that means, if your domain is "larrycai.tk", your bucket should be called "larrycai.tk". If the "2." was made correctly it will let you create that bucket, if not, it will show you an error message saying that you need to verify that you are the owner of that domain.
4.Go again to your domain provider (in my case, freenom) and in the DNS menu add this record:
as you see, you need to add a CNAME record and the target will be c.storage.googleapis.com, if it ask you to set a name, just add your domain "larrycai.tk".
5.(Optional) If you want to redirect your bucket url to a main file (like index.html for example), just run this command:
gsutil web set -m index.html gs://[your_bucket]
Now, with all theses steps, you should be able to see your static web page in your own domain.
There are different ways in deploying a site using Google Cloud Platform. The "Hosting a Static Website" tutorial refers to hosting a static website using Cloud Storage only.
To host a static website using App Engine, you will need to edit the app.yaml file of your application and create request handlers that will point to your static website.
As you are using the go qwikstart tutorial, I'm going to assume that your directory looks something like this:
helloworld
|-- app.yaml
|-- helloworld.go
|-- helloword_test.go
Create a new folder within the helloworld directory, in this example, I'm calling it www
Move your static files to the folder you just created, in my case the www folder
In the app.yaml file, add the following, replacing www with your folder name:
handlers:
- url: /
static_files: www/index.html
upload: www/index.html
- url: /(.*)
static_files: www/\1
upload: www/(.*)
Deploy your application using gcloud app deploy.
For more info, Google provided documentation on serving static content for:
Go
Python
PHP
Node.js
Java
.NET
Ruby

Deployment of static directory contents to google app engine

I've deployed my first GAE application and I am getting "TemplateDoesNotExist" exception at my main page. It feels like my static directory content is not uploaded to GAE.
Isn't it possible that I update (appcfg.py update myapp/) all my files including the static ones and run it standalone on myappid.appspot.com ?
by the way here you can see the problem:
http://pollbook.appspot.com
PS: my app works perfect locally
Your templates should not be stored in a directory that you refer to as "static" in app.yaml. Static directories are for literally static files that will be served to end users by the CDN without changing. These files cannot be read by the templating engine. It works locally because the dev_appserver does not precisely emulate the production server.
Put your templates in a different directory like /templates or something. You do not need to refer to this directory in your app.yaml.

Resources