503 errors when trying to login on local Google AppEngine server - google-app-engine

I have a functional Go app which I've been running locally for months. Got setup with Google Cloud, did a test run to a live domain, everything works.
Looking back at my local machine, I want to run a local Google AppEngine server (instead of running my Go app directly). It runs, however I'm trying to use the "login: required" parameter in app.yaml, and I see the login form at localhost:8080, however no matter what email I input, it keeps timing out with 503 errors.
My app.yaml:
application: myapp-dev
env: flex
runtime: go
api_version: go1
handlers:
- url: /
script: _go_app
login: required
Command I use to run the local app:
dev_appserver.py app.yaml

Flexible environment doesn't support 'login' features via app.yaml (external to whatever regular login you'd do in your app).
Standard environment app.yaml doc DOES list 'login' features: https://cloud.google.com/appengine/docs/standard/go/config/appref
Flexible environment app.yaml doc DOES NOT list 'login' features: https://cloud.google.com/appengine/docs/flexible/go/configuring-your-app-with-app-yaml
But more specifically, a page talking about upgrading from Standard-to-Flex, mentions that the login handlers for flex have been deprecated:
https://cloud.google.com/appengine/docs/flexible/go/upgrading
The login setting under handlers is now deprecated for the App Engine
flexible environment. You should follow the guidance for User service
migration.
So basically, with flex environment, there is no project-wide login controls possible outside of your app. You have to let the app initialize and then do normal authentication/authorization.
For my own project, I wanted a quick app-wide level of security so I could provide guest accounts and have them see what a public not-logged-in view of my app would be. Yes I can do the same within my app, I just wanted to save some work.

Related

App Engine matching any "subdomain" to my service

I have a Strapi application on Google App Engine as the Default service.
The default URL App Engine generates is https://my-project.uc.r.appspot.com
When I create any other version for my default service or deploy another service, the new URLs would be something like: https://[identifier]-dot-my-project.uc.r.appspot.com
My problem is that if I replace [identifier] with anything at all it opens my Strapi Application root page.
I don't think this has anything to do with Strapi at all, it's probably a feature of App Engine.
My question is: How do I stop this from happening? I want only proper URLs to be matched. That is, if I create a "dev" version, I should be able to access it with the following URL: https://dev-dot-my-project.uc.r.appspot.com, but I don't want any other URL to be matched, like: https://12345-dot-my-project.uc.r.appspot.com
I am using a Standard Environment with the default app.yaml from Strapi docs
runtime: nodejs16
instance_class: F2
env_variables:
HOST: '0.0.0.0'
NODE_ENV: 'production'
DATABASE_NAME: 'strapi'
DATABASE_USER: 'postgres'
DATABASE_PASSWORD: '<password>'
INSTANCE_CONNECTION_NAME: '<instance_identifier>'
beta_settings:
cloud_sql_instances: '<instance_identifier>'
When the app is deployed to App Engine, the app.yaml is automatically modified to add some default params.
runtime: nodejs16
env: standard
instance_class: F2
handlers:
- url: .*
script: auto
I thought maybe this url: .* was the cause of this and tried to change it to url: /.* (Docs), but App Engine still add the url: .* again anyway at the end and it will have both handlers.
This is expected behavior. Per the documentation
If a request matches the PROJECT_ID.REGION_ID.r.appspot.com portion of the hostname, but includes a service, version, or instance name that does not exist, then the request is routed to the default service.
In your example, when you hit the url - https://12345-dot-my-project.uc.r.appspot.com and it turns out '12345' is not a valid version, the default service - https://my-project.uc.r.appspot.com will take over.
If you really want to block it, you'll have to write code to read the incoming url (i.e. the original url that came in), determine the version and if it's not in your list of versions, you raise an error (maybe return 404). This is basically what you'd do if you were offering a service built on GAE where each of your users had their own custom domain (version of your app) e.g. a blog hosting platform, an ecommerce site (like Shopify)

Where are the requests to `/nginx_metrics` coming from in Google App Engine

I'm running a webservice on Google App Engine. It's a simple webserver which has a few routes. none of these are /nginx_metrics. This is my app.yaml file:
runtime: custom
env: flex
automatic_scaling:
min_num_instances: 1
max_num_instances: 2
cool_down_period_sec: 180
cpu_utilization:
target_utilization: 0.6
resources:
cpu: 4
memory_gb: 4
disk_size_gb: 10
I run this and I see a constant stream of requests which seem to be hitting /nginx_metrics, and the logs say that it's responded with a 200 status. I'm not sure where this is coming from since I've not given my application any sort of nginx instance. It doesn't really bother me, but I'd like to read my logs without this, and I'm unable to do so.
I get a stream of this:
2022-03-28 04:00:37 default[20220328t092456] "GET /nginx_metrics" 200
2022-03-28 04:00:52 default[20220324t171711] "GET /nginx_metrics" 200
And even my app logs seem to be prefixed with default. How do I fix this?
The /nginx_metrics endpoint is called by GAE to retrieve the metrics from the customer Flex VMs. That endpoint is not exposed publicly, it's exposed on the docker bridge network 172.17.0.1 but you can't send requests to /nginx_metrics from the appspot URL (you may want to check this)
That path is targeting one of the sidecar containers that are deployed along with your app (which is on another container on each instance). That container is the opentelemetry-collector one, you can check it by SSHing into a flex instance. If you want to check the source of the container it should be running something similar to : https://github.com/GoogleCloudPlatform/appengine-sidecars-docker/tree/main/opentelemetry_collector.
Google is aware of this issue and that the /nginx_metrics is logged in nginx request logs, ( which is not an intended behavior) and we are working on it. You can expect the fix to be resolved on the next Flex runtime update.
Coming to your second question, default service being prefixed for every logs :
If you do not specify any service name while deploying your app or while entering the gcloud command like : gcloud app deploy instead of gcloud app deploy service-name-app.yaml your app will get deployed in another version of the default service. That is why you would see default[some-numbers] prefixed to each of your successful logs where default is the service and [20220328t092456] is the version-name that tells you have deployed this version on 28th March,2022.

Is there a way to import environment variables in Google App Engine's app.yaml?

I know you can declare env_variables in your app.yaml as described in the app.yaml documentation. However, is it possible to include environment variables from your local environment into app.yaml when deploying.
As an example of what I'm trying to accomplish
# in app.yaml
runtime: python27
api_version:1
threadsafe: true
service: {{ $AN_ENVIRONMENT_VARIABLE }}
Yes, you can use includes: to specify an array of files to be included. And in the included file, you can specify env_variables: just like you do in app.yaml.
Example: app.yaml:
runtime: go
api_version: go1
env_variables:
FIST_VAR: myFirstVar
includes:
- credentials.yaml
credentials.yaml:
env_variables:
SECOND_VAR: mySecondVar
No, no such templating support exists for the app.yaml configuration files.
Side note: the app.yaml file is not only used to extract deployment instructions information, it's also used to configure the operation of the respective service on GAE. Making the service name configurable in such manner doesn't make a lot of sense unless the services being deployed are identical in every aspect (other than their name) - highly unlikely.
One possible approach for environment-specific deployment would be to have different version control branches for the app code, one for each environment, each having the desired app.yaml content.
Another one would be to wrap the deployment command in a script and perform the enviroment substitutions inside that script.
As for passing credentials info to the app a clean, straight-forward solution is not yet available. But approaches exist:
GAE: best practices for storing secret keys?
How to set environment variables/app secrets in Google App Engine
Google app engine: Best practice for hiding Rails secret keys?
How to handle sensitive configuration information when deploying app-engine applications?

App Engine - subdomain pointing to particular service

I have two subdomains registered in my App Engine application:
service-a.my-app.com
service-b.my-app.com
I have added all the records (CNAME, A) on the server.
I have three services in my GAE:
default
service-a
service-b
And I want each subdomain to point to the correct service. However, each time I access them, only the default service is used.
Side note: the GAE is running a flexible environment for laravel 5.4 and my dispatch.yaml (located in default service is as follows:
dispatch:
-url: "service-a.my-app.com/*"
service: service-a
-url: "service-b.my-app.com/*"
service: service-b
This worked for me. Hope this helps someone.
GAE Standard:
I have an angular project which will load for any subdomain except one subdomain "api".
The backend is written in Go and all services are under a service named "api"
STEP1: Setting local env
Angular project has the following app.yaml
runtime: python27
api_version: 1
instance_class: F1
handlers:
- url: /
static_files: default/index.html
upload: default/index.html
- url: /
static_dir: default
My service.yaml file resides in a separate directory and has the following
runtime: go
api_version: go1
instance_class: F1
service: api
handlers:
- url: /.*
script: _go_app
secure: always
My dispatch.yaml has the following
dispatch:
- url: "api.MYDOMAINNAME.com/*"
service: api
//Add more subdomain : services mapping here
I deployed all these files using gcloud app deploy command
Step 2 - Configure Custom domains in GAE.
In GAE Console, goto Project Settings > Custom Domains
Add your domain
Verify your domainusing one of the methods provided by Google.
Update CNAME, A and AAA records in your domain service provider's DNS Settings
Step 3 - Configure Sub Domain
Add a subdomain api.MYDOMAINNAME.com
Add the CNAME in your domain service provider's settings.
// add more subdomains if required
Add a Wildcard subdomain *.MYDOMAINNAME.com
Add the CNAME in your domain service provider's settings to redirect * to google.
Finally:
Wait for few minutes for the settings to be applied.
Now your application will redirect MYDOMAINNAME.com, www.MYDOMAINNAME.com , *.MYDOMAINNAME.com to the Angular code
and
api.MYDOMAINNAME.com to your api service
Please note that dispatch.yaml is an app-level configuration, not a service-level one and occasionally updating the service containing it doesn't automatically update the app-level configs.
You should use the specific deployment commands for dispatch.yaml, executed from the directory containing the file:
gcloud app deploy dispatch.yaml if you're using the Cloud SDK
appcfg.py update_dispatch . if you're still using the GAE SDK
See also dispatch.yaml not getting updated.
The same is true for other app-level .yaml config files as well, which is probably one reason for each having its own update/deploy command (and also to allow deploying them independently of any particular app service. Somehow related: Why do I need to deploy a "default" app before I can deploy multiple services in GCP?
Actually the answer was really easy: You just need to map a wildcard subdomain and GAE would the use the service corresponding to the prefix.

Google Apps Engine app.yaml file not correct? "This webpage has a redirect loop"

I'm getting an error "This webpage has a redirect loop" when loading my Google Apps Engine url: http://my-application-id.appspot.com (my real application ID in the url of course)
Google Apps Engine requires an app.yaml file in the root of the application directory to work correctly. Here are the contents of my file....
application: my-application-id
version: 1
runtime: php
api_version: 1
handlers:
- url: /.*
script: install.php
Is my app.yaml file setup correctly? The install.php file for my application works much the same way as a wordpress install.php file. You access it from a web browser and go through the basic setup. If my app.yaml file is correct, why am I still getting the "This webpage has a redirect loop" error displayed in my browser?
Also tried other browsers, clearing cookies, etc. The application installation screen loads perfectly in my SDK but not live on Google Apps Engine. What am I doing wrong?
I figured it out. There were 2 problems.
On app.yaml, in my case, the last line needed to say "index.php" instead of "install.php" Second, in my case, my configuration.ini file had port "80" set for MYSQL when in fact it needed to be "3306"

Resources