Scalable Blog with GCP Hosting
Architecture Overview
Frontend & Backend: A web app (e.g., Flask, Node.js, or Django).
Database: Cloud SQL (PostgreSQL or MySQL) to store blog posts, users, comments, etc.
Media: Cloud Storage for hosting images or other static files.
Deployment: Docker container running on Cloud Run.
Set up your project
gcloud projects create blog-project-123
gcloud config set project blog-project-123
gcloud services enable run sqladmin storage.googleapis.com \
compute.googleapis.com artifactregistry.googleapis.com
Design your blog backend
Pick your stack:
- Flask (Python)
- Express (Node.js)
- Django (Python)
- Laravel (PHP)
In this tutorial, we will use Flask + PostgreSQL app.
Example Routes:
- / – List blog posts
- /post/<id> – View a single post
- /admin – Write/edit posts
Example models.py:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(255))
content = db.Column(db.Text)
image_url = db.Column(db.String(255))
created_at = db.Column(db.DateTime, default=datetime.utcnow)
Create Cloud SQL
gcloud sql instances create blog-db \
--database-version=POSTGRES_13 \
--cpu=1 --memory=4GB --region=us-central1 \
--root-password=mysecurepassword
Create the database:
gcloud sql databases create blogdb --instance=blog-db
You can also use Cloud SQL Proxy for local development.
Use Cloud Storage for media files
gsutil mb -l us-central1 gs://your-blog-media-bucket
Configure it to be public or use signed URLs for uploads. Use it to store:
- Blog post images
- Avatars
Dockerize your app
Example Dockerfile:
FROM python:3.10
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
ENV PORT=8080
CMD ["gunicorn", "-b", ":8080", "app:app"]
Deploy to Cloud Run
Build image:
gcloud builds submit --tag gcr.io/blog-project-123/blog-app
Deploy:
gcloud run deploy blog-app \
--image gcr.io/blog-project-123/blog-app \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--set-env-vars DB_USER=postgres,DB_PASS=mysecurepassword,DB_NAME=blogdb,INSTANCE_CONNECTION_NAME=blog-project-123:us-central1:blog-db
Connect to Cloud SQL securely
Use Unix socket or Cloud SQL Auth Proxy. In Flask, you'd connect like:
app.config['SQLALCHEMY_DATABASE_URI'] = \
'postgresql+psycopg2://user:password@/blogdb?host=/cloudsql/blog-project-123:us-central1:blog-db'
Secure and Optimize
Set up Cloud Armor to block suspicious traffic.
Use HTTPS with custom domain via Cloud Run settings.
Implement JWT-based authentication or Firebase Auth for admin access.
# Cloud Armor
gcloud compute security-policies create ...
gcloud compute security-policies rules create ...
gcloud compute backend-services update ... --security-policy=...
# HTTPS Custom Domain
gcloud domains verify yourdomain.com
gcloud run domain-mappings create --service=...
# Auth
gcloud run services update blog-app --no-allow-unauthenticated
Add CI/CD
Use Cloud Build to automate builds from GitHub or GitLab:
.cloudbuild.yaml:
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/blog-app', '.']
- name: 'gcr.io/cloud-builders/gcloud'
args: ['run', 'deploy', 'blog-app', '--image', 'gcr.io/$PROJECT_ID/blog-app', '--region', 'us-central1', '--platform', 'managed']