You need a server for your application without managing hardware or paying lifetime subscriptions. Google Cloud Platform (GCP) is a solid choice. The problem? People often jump straight to deployment and forget to set up accounts, budgets, and permissions properly. Result: a hefty bill at month-end and overly broad access to sensitive resources.
At Meteora Web, we come from accounting – balance sheets, double-entry bookkeeping, VAT filings. When we work on cloud, the first question is always: how much does it cost and what does it return? Everything else follows.
This guide takes you from zero to a deployed application on GCP with IAM configured correctly. No abstract theory – ready-to-copy commands, decisions to make, mistakes to avoid.
Account and Billing: get it right from the start
A GCP account without budget constraints is a blank check. We see it often: clients activate services, forget to stop them, and end up with thousands of euros to pay. We always start with cost control.
Create a GCP account and set up budget alerts
Go to console.cloud.google.com and follow the guided setup. After entering billing information, the first thing to do is configure a budget alert:
# Enable the billing API either in the console or via gcloud
gcloud services enable billingbudgets.googleapis.com
# Create a €100 budget with thresholds at 50%, 80% and 100%
gcloud billing budgets create \
--billing-account=BILLING_ACCOUNT_ID \
--display-name="Monthly €100 budget" \
--budget-amount=100 \
--threshold-rules=percent=0.5,percent=0.8,percent=1.0
Note: replace BILLING_ACCOUNT_ID with the ID you find under Billing > Account management. We recommend starting with a low budget and only increasing after you have tested the loads.
Costs: enable billing alerts with email notifications
To receive notifications, you must attach a communication channel:
# Create an email channel for notifications
gcloud alpha monitoring channels create \
--display-name="Email alert" \
--type=email \
--channel-labels=email_address=your@email.com
# Link the channel to the budget you just created
gcloud billing budgets update BUDGET_NAME \
--notifications-pubsub-topic=projects/PROJECT_ID/topics/billing-alerts \
--email-recipients=your@email.com
Why is this important? A client once told us they left a VM with a GPU running over the weekend – €1,200 surprise. With alerts, you can stop it in time.
IAM: who does what in the cloud
IAM (Identity and Access Management) is GCP's permission system. A common mistake: giving everyone the Owner role for convenience. We call it “the fastest path to a security incident”.
Users, roles and service accounts: the differences
- User – a human (you or a colleague) logging in with a Google account.
- Service Account – an identity for applications or processes (e.g., a backend reading from a database).
- Role – a set of permissions (e.g., roles/storage.objectViewer).
Golden rule: never use a human user's credentials in an application. Always use a service account.
The principle of least privilege
Assign only the permissions strictly required. Do you want an application to write logs? Give it roles/logging.logWriter, not roles/editor.
Create a service account for your application
# Create a service account with ID and description
PROJECT_ID="your-project-id"
SA_NAME="my-app-sa"
gcloud iam service-accounts create $SA_NAME \
--display-name="Service Account for my application" \
--project=$PROJECT_ID
# Assign the Cloud Run Invoker role (if you deploy there later)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/run.invoker"
# Create and download the JSON key (handle with care!)
gcloud iam service-accounts keys create ./my-app-key.json \
--iam-account=$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com
Warning: do not commit my-app-key.json into your Git repository. Use environment variables or a secret manager.
Common mistake: service account key in plain sight in the repository
We performed an audit for a company where the service account JSON key was in a public GitHub repo. Anyone could spin up instances at their expense. Quick fix: rotate the key and use Secret Manager or workload identity federation (more advanced).
Your first application on Cloud Run
Cloud Run lets you deploy a container without managing servers. You pay only for requests and execution time – ideal for starting with no financial commitment.
A Node.js Hello World app
Create an app.js file:
const express = require('express');
const app = express();
const PORT = process.env.PORT || 8080;
app.get('/', (req, res) => {
res.send('Hello from Meteora Web on GCP!');
});
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});
Create a Dockerfile:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 8080
CMD ["node", "app.js"]
And a package.json:
{
"name": "gcp-hello",
"version": "1.0.0",
"dependencies": {
"express": "^4.18.2"
}
}
Deploy with gcloud
# Enable Cloud Run API
gcloud services enable run.googleapis.com
# Build the image with Cloud Build
PROJECT_ID="your-project-id"
IMAGE_NAME="gcr.io/$PROJECT_ID/hello-meteora"
gcloud builds submit --tag $IMAGE_NAME .
# Deploy to Cloud Run using the service account you created
gcloud run deploy hello-meteora \
--image $IMAGE_NAME \
--platform managed \
--region europe-west1 \
--service-account=$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com \
--allow-unauthenticated \
--memory=256Mi \
--concurrency=80
# Get the URL
gcloud run services describe hello-meteora --region europe-west1 --format='value(status.url)'
Note: --allow-unauthenticated makes the endpoint public. For production, consider using IAP or an API Gateway.
Custom domain and managed HTTPS
Cloud Run automatically provides a managed SSL certificate. Simply map a custom domain from the console or with gcloud:
gcloud beta run domain-mappings create \
--service hello-meteora \
--domain your-app.meteoraweb.it \
--region europe-west1
Follow the instructions to add the DNS records. No extra cost for the SSL certificate.
Monitoring and logs
View live logs:
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=hello-meteora" --limit 10
# Continuous stream
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=hello-meteora" --freshness=10m
We recommend setting up an alert on error logs – when the application crashes, you get notified. Configure it in Logging > Log-based Metrics.
Summary: what to do now
- Enable budget alerts before starting any service. An unexpected cost is enemy number one.
- Create a service account for the application – do not use your own user account.
- Assign only the necessary roles – start with the minimum and add if needed.
- Deploy to Cloud Run with a simple container to test the flow.
- Protect your keys – never on Git, never in Docker images without caution.
The cloud is powerful, but without discipline it becomes a cost. At Meteora Web, we work every day to turn technology into an investment, not an expense. If you want to dive deeper into monitoring and analytics, check out our guide on Google Tag Manager – because data also needs governance.
Sponsored Protocol