Why Do I Need to Deploy a "Default" App Before I Can Deploy Multiple Services in Gae

Why do I need to deploy a default app before I can deploy multiple services in GAE?

The reason is that there are also several app-level configs, applicable to all services/modules:

  • dispatch.yaml
  • index.yaml
  • queue.yaml
  • cron.yaml

Some of these configs can have trouble if not deployed after/together with the default service. And some services may have dependencies on the app-level configs.

The requirement of deploying default first is simply a measure to reduce the risk of initial deployment problems. Subsequent deployments no longer have this restriction (since default is already deployed)

Yes, the default service is mandatory (sort of like a kitchen sink for all kinds of stuff, for example requests not matching any dispatch rule are sent to the default service). So just declare one of your non-web apps the default one (it doesn't matter what the default service actually does).

Somehow related (mostly for the examples): Can a default service/module in a Google App Engine app be a sibling of a non-default one in terms of folder structure?

What purpose does the default service serve in Google's app engine

Here would be some roles/reasons for the default service (I'm fairly sure the list is not exhaustive):

  • the fallback destination for routing a request using a dispatch.yaml file if none of the routing rules is matched
  • the fallback destination for cron jobs if they aren't specifically configured to target a specific service
  • for initial deployment of app-level configs, see Why do I need to deploy a "default" app before I can deploy multiple services in GCP?

Practically I'd consider such differences just extra functionality (mostly infra-related) compared to the named services, otherwise they're very similar.

Google App Engine does not deploy two services (seem to be overriding each other)

It is happening because in your app.yaml file, you have not provided the service tag. If service tag is not provided, the service will be deployed as default service. For e.g. when you deploy your frontend, it is getting deployed as default service. And then you deploy your backend, it is also getting deployed as default service overriding the existing default service. or the vice versa.

Add the service tag in your frontend's app.yaml:

service: frontend
runtime: nodejs10

You may keep the backend as default service i.e. no service tag in backend's app.yaml

Can a default service/module in a Google App Engine app be a sibling of a non-default one in terms of folder structure?

The modules can all be side by side. The <module>.yaml for each one can be inside the module dir.

The note about app.yaml file is misleading, it really applies just to single-module apps (many pieces of the documentation weren't updated for multi-module apps).

The default module's config file doesn't even have to be called app.yaml (or its dir called default). I'd keep the app-level config files (cron.yaml, dispatch.yaml, queue.yaml and index.yaml) at the top level, eventually symlinking them into the default (or other) module(s) as needed (some tools may complain otherwise).

Here's, for example, the structure I got to for one of my apps (the main dir contains the default module):

cron.yaml
dispatch.yaml
queue.yaml
index.yaml
main/cron.yaml -> ../cron.yaml
main/index.yaml -> ../index.yaml
main/main.yaml
main/queue.yaml -> ../queue.yaml
buildin/buildin.yaml
buildin/index.yaml -> ../index.yaml
buildin/queue.yaml-> ../queue.yaml

You just need to pay attention when invoking the related tools. This is my cheat-sheet for that app, executed from the app's dir, some of it is also reflected in the pycharm project config (I'm running the development server inside pycharm):

appcfg.py update main/main.yaml buildin/buildin.yaml
appcfg.py update_dispatch .
appcfg.py update_indexes -A <app-name> main
appcfg.py update_cron -A <app-name> .
appcfg.py update_queues -A <app-name> .

To run the devserver:

dev_appserver.py --host 0.0.0.0 --log_level=debug dispatch.yaml main/main.yaml buildin/buildin.yaml

Update: added some of my config files, as requested.

The dispatch.yaml file, taking care of the buildin module routing on both the appspot domain and my custom domain (everything else is automatically routed to the default module):

application: <my_app>
dispatch:
- url: "buildin.my_domain.com/*"
module: buildin
- url: "buildin-dot-my_app.appspot.com/*"
module: buildin
- url: "*/buildin/*"
module: buildin

The main.yaml file:

application: my_app
module: default
version: 1
runtime: python27
api_version: 1
threadsafe: true

handlers:

- url: /(.*\.min\.css)$
static_files: stylesheets/\1
upload: stylesheets/.*\.min\.css$
secure: always

- url: /(.*\.(ico|gif|png|jpg|svg))$
static_files: images/\1
upload: images/.*\.(ico|gif|png|jpg|svg)$
secure: always

- url: .*
script: main.app
secure: always

libraries:
- name: webapp2
version: "2.5.2"
- name: jinja2
version: "2.6"
- name: pycrypto
version: "2.6"

The buildin.yaml file:

application: my_app
module: buildin
version: 1
runtime: python27
api_version: 1
threadsafe: true
instance_class: B2

handlers:

- url: /(.*\.min\.js)$
static_files: scripts/\1
upload: scripts/.*\.min\.js$
secure: always

- url: /(.*\.min\.css)$
static_files: stylesheets/\1
upload: stylesheets/.*\.min\.css$
secure: always

- url: /(.*\.(ico|gif|png|jpg|svg))$
static_files: images/\1
upload: images/.*\.(ico|gif|png|jpg|svg)$
secure: always

- url: /buildin/cron*
script: buildin.app
login: admin

- url: .*
script: buildin.app
secure: always

libraries:
- name: webapp2
version: "2.5.2"
- name: jinja2
version: "2.6"
- name: pycrypto
version: "2.6"

How can I deploy new service to the existing app in Google App Engine?

While it might be possible to use the existing app.yaml to deploy a new service by specifying different deployment command arguments, I wouldn't recommend it as it's IMHO too brittle, you'd risk affecting of the existing app (technically the default service of your existing single-service app). It's also rather unlikely you want to deploy the exact same code in the new service (the code being deployed is the one from the directory where the .yaml file exists).

I'd highly recommend (re-)structuring your app taking your services into account:

  • the app's top level directory contains app-level config files, not service-level files
  • each service has its own sub-directory under the app's top level dir, each with its own code and .yaml file (which doesn't even have to be called app.yaml
  • services would be deployed independently, each from its own sub-directory

Getting there from a single-service app directory is relatively simple: just create a sub-directory (for the default service) and move the existing app.yaml and the code into it, check that the functionality is unaffected and re-deploy from the new location. Then create sub-directories for additional services and their code.

See also:

  • Configuration Files:

Typically, you create a directory for each service, which contains the
service's YAML files and associated source code. Optional
application-level configuration files (dispatch.yaml, cron.yaml,
index.yaml, and queue.yaml) are included in the top level app
directory. The example below shows three services. In service1 and
service2, the source files are at the same level as the YAML file.
In service3, there are YAML files for two versions.

Sample Image

  • Can a default service/module in a Google App Engine app be a sibling of a non-default one in terms of folder structure?)

Is there possibility to host multiple applications with Google App Engine?

This is easily done with services. When you deploy to App Engine define your app.yaml file with a line like: service: my-second-app

Complete app.yaml file for another Node.js service:

service: my-second-app
runtime: nodejs
env: flex
automatic_scaling:
min_num_instances: 1

When you deploy, do it from the directory containing your app.yaml file:

gcloud app deploy

Or if you want to define your configuration in a yaml file just for your seond app:

gcloud app deploy my-second-app.yaml

The new service will be deployed along side your default service and will get it's own URL like:

https://my-second-app-dot-my-project-name.appspot.com

Deploying a service to a subdomain Google App Engine

In case this helps anyone, the issue was that my updated dispatch.yaml file was inside of an undeployed version of the app.yaml file in the betaversion service.

If editing the dispatch.yaml file - make sure you also re-deploy the location containing that dispatch file. In my case, deploying it using

gcloud app deploy service-folder/dispatch.yaml 

did not work unless I also deployed the service as well

gcloud app deploy service-folder/app.yampl service-folder/dispatch.yaml


Related Topics



Leave a reply



Submit