GCP App Engine - How to serve newest files - google-app-engine

I'm using GCP App Engine with auto scaling.
If I deploy a new version of the app code (Python 3 Flask app) with a simple change for control and test purposes, lets say I add a comment to one of the .js files I am not seeing that change to the file in the browser after it has been deployed.
I have 100% of traffic being served by the new version of the app. When I look at the source code for the version I can see the comment in there, but when I clear my browser cache and visit the page I only ever get the old version of the page (without the comment in the .js).
I have tried using the --promote and --no-cache values in the app deploy command, but no use. I have added:
default_expiration: "0d 0h 0m 0s"
To the app.yaml
I have also turned on object versioning of the storage account which app engine uses to try to ensure that only a single version of the file is available to be served - still no use.
The command I'm using to deploy is:
run: "gcloud app deploy app.yaml --quiet --promote --no-cache"
I can't understand why it should be so difficult to simply deploy a new version of the app and have the app engine serve the latest files; I must be doing something wrong but cannot see what.
Would appreciate any pointers.

The files are cached (even if for a short while and sometimes it takes time to clear it).
The trick is to make the urls (for the static files) unique for each deployment. This way, the browser is loading a 'distinct' url after each deployment. For example, you could append the environment variable, CURRENT_VERSION_ID to the url for all static elements. This means having something like (assuming Python/Jinja2)
src="/static/js/my_js_file.js?{{CURRENT_VERSION_ID}}"
os.environ['CURRENT_VERSION_ID'] changes for each deployment. There's a possibility this attribute is not available in newer runtimes. If so, just dump the environment variables and look for an attribute that is always present but the value changes (e.g. GAE_INSTANCE).
You could also just generate a random number each time your App is deployed and use that instead i.e.
src="/static/js/my_js_file.js?{{RANDOM_NUMBER}}"

Related

How can you pass environment variables to google app engine via app.yaml?

I am using Google App Engine to deploy a node app (nextjs, node-12).
To deploy the app, I run:
gcloud app deploy
My app.yaml is as follows (minus variable substitutions):
runtime: nodejs12
env_variables:
NEXT_PUBLIC_FRONTEND_URL: "A"
In my code is the following line:
const url = `${process.env.NEXT_PUBLIC_FRONTEND_URL}/login/callback`;
When this code runs in app engine, url evaluates to B/login/callback
I don't understand this behavior. The documentation here (https://cloud.google.com/appengine/docs/standard/nodejs/config/appref) seems to indicate to me that this should work, but it does not.
Is there a reason for this? I've unset the variables from my local computer, just in case they were somehow getting passed, and I removed the .env file in case nginx was sourcing it or something like that.
What you have done looks correct. Try the following troubleshooting steps
Confirm you are not directly setting the value somewhere in your code e.g. say you call a child process and pass an env to it and you have explicitly set the value there
Check your deployed versions (you can do this via cloud console, see path below). Do you have multiple versions of the app? Which one are you running?
To check your versions and which one is running
console.cloud.google.com > App Engine > Versions
To view the configuration for each of the deployed versions,
select the version and click on 'View' under the 'config' column . This will display the deployed app.yaml file for that version

GAE: No longer able to update my Gaelyk project due to appcfg losing support

Recently tried to update my Gaelyk project (yes, it's old, but it works well and I still use it), but Google App Engine will no longer accept the update. The error message returned is "Deployments using appcfg are no longer supported. See https://cloud.google.com/appengine/docs/deprecations". The thing is, I never used appcfg to deploy my application; I used Gaelyk and Gradle. But obviously Gaelyk must have used appcfg under the covers.
I did download the replacement Google Cloud SDK, but this new tool is not similar at all to how Gaelyk and Gradle worked. Is there anything I can do to get Gaelyk to work anymore? Or is Gaelyk just dead and I need to rewrite my application (like in Node.js or something instead of Groovy).
This will be hard, however I will try to help you as possible. I think you may try to migrate it somehow to app.yaml configuration of GAE.
I am not sure what plugins are used in the project. From Gaelyk temple project I can see that it's using appengine-geb which, according to the documentation, behind the scenes, is using gradle-appengine-plugin (there is wrong link on this doc, but proper is bellow).
On the github of gradle-appengine-plugin I have found following.
There is a note:
NOTE: All App Engine users are encouraged to transition to the new
gradle plugin for their projects.
And in FAQ part there is following information:
How do I deploy with gcloud?
If you're using gcloud to deploy your application, the newest version of app deploy > doesn't support war
directories, you will need to provide it with an app.yaml OR you can
use the appengineStage task to create a directory that is deployable
in /build/staged-app
$ ./gradlew appengineStage
$ gcloud app deploy build/staged-app/app.yaml --project [app id]
--version [some version]
NOTES:
You must explicitly define all config files your want to upload
(cron.yaml, etc)
This does not work with EAR formatted projects.
I think the best option will be to migrate to new appenine plugin or if not possible try to implement is with gcloud app deploy command crating the config files manually (at least app.yaml). And for this migration I can provide you this document.
I hope you will manage somehow...
I can confirm that Serge's answer on the Gaelyk Groups site works; the same procedure that he figured out also worked for me. To summarize:
Run gradlew appengineRun as run previously with Gaelyk.
Copy all jar files inside the build\exploded-app\WEB-INF\lib folder into a \src\main\webapp\web-inf\lib folder (for me the new lib folder did not exist previously).
To deploy, use the new required gcloud tool, and instead of running gradlew appengineUpdate (which fails now), instead run
gcloud app deploy appengine-web.xml where that XML file can be found in your webapp/WEB-INF directory. I navigated to that directory to run the gcloud command, but you can use a relative path there if your working directory is elsewhere. (There are a number of optional flags associated with the gcloud app deploy command, but I didn't need any of them.)
Serge needed to use these instructions to convert datastore-indexes.xml to index.yaml and run gcloud app deploy index.yaml, however, I didn't need to do this because I had no datastores.

php7 routing in app engine fails in local environment

According to the docs found here:
https://cloud.google.com/appengine/docs/standard/php7/runtime#application_startup
My app, is able to serve up index.php, without defining any handlers in my app.yaml file, which it does. Great! However, that same app.yaml file fails to serve up index in my local environment (dev_appserver.py) That seems less than ideal...
The path to the file is public/index.php
Here's the error I see in my local when I go with the very same app.yaml that works perfectly in production:
The url "/" does not match any handlers.
The dev_appserver.py only works with the first generation App Engine runtimes.
As you can see on the documentation, to test locally your PHP 7 app, you have to use the development tools that you usually use.
On this thread from the Google’s Public Issue Tracker there is a similar issue, and there is posted a solution for locally test PHP 7 apps. Basically, you have to set up a front controller on a web server locally. You can do it following this tutorial, for example.

Can I have application versions in python27 and python37 in Google App Engine Standard (both types)

I want to test Python 3.7 on Google App Engine Standard.
I am afraid if I upload application with python37 old application will stop working and will be no revert to previous python27.
Can you share some experience if it possible to keep both runtime versions?
It is not clear for me.
I read Python 3.7 on Google App Engine - documentation but not found information.
You have 3 main options, ranked from easier to 'harder' to do:
Just deploy this test you want to do in a new project, and you don't have to worry about your old application getting replaced.
Deploy this test to a new service. Just add the line service: whatevername to the app.yaml file of your test, and deploy it as usual with $gcloud app deploy. Voilà, you have a new service.
You can deploy this test in your default service, but to avoid stopping the previous one, add the --no-stop-previous-version flag to your $ gcloud app deploy command. After that, you can split traffic between this test and your actual app.
To be honest, I would go with options 1 or 2, as they are far more simple to deploy, and you can later on delete the test project or delete the new service if you wish to.

How is my GAE app able to run without app.yaml?

Although I started development for Google App Engine using Endpoints a while ago, I hadn't noticed this - Google's ref. page for Project structure says this:
Your development file hierarchy should look like this:
MyDir/
[pom.xml]
[build.gradle]
[index.yaml]
[cron.yaml]
[dispatch.yaml]
src/main/
appengine/
app.yaml
docker/
[Dockerfile]
java/
com.example.mycode/
MyCode.java
webapp/
[index.html]
[jsp.jsp]
WEB-INF/
[web.xml]
You'll need to define an app.yaml file that looks like this:
...
Note that the app.yaml is deemed compulsory as per the docs. In my case, I spawned a backend module(through the Wizard) in Android Studio that builds on Gradle. I have been able to build and deploy this module on GAE successfully but now I needed to switch from automatic scaling to basic/manual scaling, I found this to be done through app.yaml file.
Here is the thing: I don't have an app.yaml in place and it works fine. Where is then the config info. that GAE requires to deploy the App.
Specifically,
app.yaml specifies the environment - Java. But, I found the java plugin in build.gradle for that. Aren't 2 config places for the same thing confusing?
Is it possible to ditch app.yaml entirely for equivalent config. in build.gradle?
Why is Google claiming app.yaml to be compulsory when I am able to do without it?
The App Engine Java runtime uses its own configuration schema in XML, while others are YAML.
To set the scaling elements, follow the official reference.

Resources