Many startups fall into the trap of premature optimization, investing excessive resources in complex infrastructure like microservices before validating their business model. This misalignment of priorities diverts precious engineering time away from customer acquisition and revenue generation, often leading to technically impressive but commercially unsuccessful ventures.
Google App Engine (GAE) offers a compelling alternative as a serverless platform that handles scalability, security, and reliability concerns automatically. GAE enables organizations to focus primarily on their business logic and core value proposition, rather than operational complexities by abstracting away infrastructure management.
The challenge becomes particularly evident in polyglot architectures where applications are developed using different programming languages and frameworks. Traditional approaches might require manually managing containers or virtual machines for each component, adding significant operational overhead and complexity.
GAE provides an elegant solution by allowing multiple applications—such as a Vue.js client interface, React dashboards, Python analytics and Node.js backendl, to be deployed within a single project. This approach maintains technological flexibility while dramatically reducing the operational burden, even as the architecture expands to include recommendation engines, analytics services, and other specialized components.
For early-stage businesses, the priority should be building "extensible enough" infrastructure that supports rapid iteration and learning until the business model is proven. Only after achieving product-market fit and sustainable revenue does it make sense to invest heavily in more sophisticated technical foundations—and even then, managed platforms often remain the most efficient solution.
Let us start by virtualizing our client project tree:
.
├── README.md
├── app.yaml
├── index.html
├── node_modules
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
├── src
└── vite.config.js
The node_modules
directory is redacted to maximize space. If we are looking at the project tree, there is an app.yaml
file that contains the GAE commands and required application parameters as shown below:
# Runtime engine nodejs 18 LTS
runtime: nodejs18
service: default
handlers:
# Serve all static files with urls ending with a file extension
- url: /(.*\..+)$
static_files: dist/\1
upload: dist/(.*\..+)$
# catch all handler to index.html
- url: /.*
static_files: dist/index.html
upload: dist/index.html
It has the runtime
, service
and handler
for routing request. It is worth mentioning that the first deployed application takes default as it's service name and might throw an error if this is skipped. You can read documentation for more information.
Navigate to the google cloud console and configure the cloudbuild service account xxxxxxxxxxxxxx@cloudbuild.gserviceaccount.com
by add App Engine Deployer
, App Engine Deployer
, and Storage Object Viewer
roles.
Next, let's build our Vue.js project by running the command npm run build
. Then, we will deploy the application by running the following command gcloud app deploy --project <project-name>
from the root directory. Once the deploy is successful, navigate to https://<project-name>.<region_id>.r.appspot.com/
to access the default application.
To deploy the node.js server service within the same project, we follow the same process. First, the project tree looks like the following:
.
├── README.md
├── app.yaml
├── controllers
│ └── user.js
├── database
│ └── index.js
├── index.js
├── lib
│ └── auth.js
├── migrate.js
├── node_modules
├── package-lock.json
├── package.json
└── routes
└── user.js
This is a simple and typical Node.js application and our interest is the app.yaml
file which contains the following key-value pairs runtime: nodejs18
and service: server
. As above, we will deploy the application by running the following command gcloud app deploy --project <project-name>
from the root directory. And visit the application by navigating to https://<service-name>-dot-<project-name>.<region_id>.r.appspot.com/
.
One final thing that we might need to add is mapping a domain name to these services. To do that, we can a dispatch.yaml
file to either the client or server application.
dispatch:
- url: "www.client.com/*"
service: default
- url: "client.com/*"
service: default
- url: "server.com/*"
service: server
Client application is preferable as it is the default application. Worthy to mention is that we can separate the content of the dispatch file into respective application, the choice is yours. Ensure that you have added all the domain and subdomain in the custom domain
tab of the App Engine.
Then deploy the dispatch.yaml
file by running the command gcloud app deploy dispatch.yaml
. If all deployments are successful, visiting any of the urls in the dispatch file should open any of the mapped application.
Again, we just deployed only two services, but it could have been more to fit our peculiarities. The repository for this tutorial is on GitHub.
If you like the article, do like and share with friends.
Top comments (0)