This repository hosts a SaaS application built with FastAPI and Streamlit, providing a blogging platform where users can log in or sign up using their Google accounts, create and manage blog posts, and access personal dashboards. This project is structured to be deployed on Google Cloud Platform (GCP) with Kubernetes and PostgreSQL.
- Part 1: Google OAuth Login and Signup with FastAPI and Streamlit.
- Part 2: PostgreSQL Database Integration and CRUD Operations for User Posts. Deployment of the Backend on Kubernetes.
- Part 3: Deployment of the Frontend on Cloud Run.
- OAuth Authentication: Secure login and signup using Google OAuth.
- Personal Dashboard: Each user can access their dashboard to add, view, and manage blog posts.
- Post Management: CRUD functionality for blog posts stored in PostgreSQL.
- Scalable Deployment: Backend on Kubernetes and frontend on Cloud Run for scalable cloud hosting.
- backend: Contains FastAPI backend with authentication (auth) and API endpoints (api).
- apps: Contains FastAPI backend with authentication (auth) and API endpoints (api).
- database: Models, schemas, and CRUD operations for PostgreSQL integration.
- frontend: Streamlit code for the user interface.
- Python 3.9+
- Docker
- Google Cloud SDK (for deployment)
- GCP Project with billing enabled
- OAuth 2.0 Credentials for Google API
Clone the Repository:
git clone https://github.com/yourusername/fastapi-streamlit-blog.git
cd fastapi-streamlit-blog
Environment Variables: Create a .env file in the root directory with the following:
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
SECRET_KEY=your_session_secret_key
FRONTEND_URL=http://localhost:8501
BACKEND_URL=http://localhost:7000
SQLALCHEMY_DATABASE_URL=your_database_url
Then run the following commands to build and run the application:
docker-compose up -d --build --force-recreate- Create a Postgres Cloud SQL Instance by following these instructions.
Note the connection string, database user, and database password that you create.
- Create a database for your application by following these instructions.
Note the database name.
- Create a service account with the
Cloud SQL ClientIAM role by following these instructions.
Download the JSON key for the service account to authenticate your connection for local development.
To deploy the application locally on your machine:
-
Install the dependencies
pip install -r requirements.txt
-
Fill in the
.envfile with your Cloud SQL specific values and path to service account JSON key.INSTANCE_CONNECTION_NAME="project-id:region:instance-name" DB_USER="my-db-user" DB_PASS="my-db-pass" DB_NAME="my-database" GOOGLE_APPLICATION_CREDENTIALS="path/to/keys.json" -
Run the application
cd backend uvicorn app.main:app --reload
The application is now running locally! Point your web browser at http://127.0.0.1:7000/docs to view the OpenAPI specs for it and to play around with making requests.
Note: Remember to remove the --reload when not in a development environment.
It helps a lot during development, but you shouldn't use it in production.
First we need to create a project in GCP
-
gclound CLI can be installed in the following document
-
Initialize gcloud CLI, and authenticate with GCP
gcloud init-
A pop-up will prompt us to select your Google account. Select the account associated with your GCP registration and click
Allow. -
Go back to your terminal, in which you typed
gcloud init, type 1, and Enter. -
Select the GCE zone corresponding to europe-west4-a (in my case), then Enter.
In the next step, we'll install the GKE Cloud Authentication Plugin for the gcloud CLI tool. This plugin facilitates authentication with GKE clusters using the gcloud cli.
We can install the plugin using the following command:
sudo apt-get install google-cloud-cli-gke-gcloud-auth-plugin
This command will install the necessary plugin for authenticating with GKE clusters.
Terraform is a powerful infrastructure as code tool that allows us to define and provision infrastructure in a declarative manner. It helps to facilitate to automate the creation, modification, and deletion of infrastructure resources across various cloud providers.
To provision a GKE cluster using Terraform, follow these steps:
- We should update the invidual project ID, the corresponding GKE zone and its node machine. In my case, a gke cluster will be deployed in zone
europe-west4-awith its node machine is:
cd terraform
terraform init # Initialize Terraform in the directory
terraform plan # Plan the configuration
terraform apply # Apply the configuration to create the GKE cluster-
A created cluster will be pop up in GKE UI (after 8 to 10 minutes)
-
connect to gke cluster using
gcloud cli
gcloud container clusters get-credentials <PROJECT_ID>-gke --zone europe-west4-a --project <PROJECT_ID>- To view your highlighted cluster ID in the terminal, you can use the
kubectxcommand.
Ensure that we have these tools to manage k8s cluster
What are kubectx and kubens?
- kubectx is a tool to switch between contexts (clusters) on kubectl faster.
- kubens is a tool to switch between Kubernetes namespaces (and configure them for kubectl) easily.
To install these tools, follow the instructions provided in the following section: https://github.com/ahmetb/kubectx#manual-installation-macos-and-linux.
In my case kubens and kubectl cli were saved in usr/local/bin/.
An Ingress controller is a specialized load balancer for k8s enviroment, which accept traffic from outside the k8s platform, and load balance it to application containers running inside the platform.
Deploy Nginx ingress controller in corresponding name space in following commands:
cd helm/nginx-ingress
kubectl create ns nginx-ingress # Create a K8s namespace nginx-ingress
kubens nginx-ingress # switch the context to the newly created namespace 'nginx-ingress'
helm upgrade --install nginx-ingress-controller . # Deploy nginx Ingress Verify if the pod running in the specified namespace nginx-ingress
kubectl get pods -n nginx-ingress- Get IP address of nginx-ingress
kubectl get svc -n nginx-ingressCopy the external IP address to the host in deployment/templates/app-nginx-ingress.yaml file
Deploy the FastAPI application container on GKE within the model-serving namespace. One replica will be created, corresponding to the one pod running the FastAPI application.
cd helm/deployment
kubectl create ns model-serving
kubens model-serving
helm upgrade --install bloggen .- You can access the API in
NGINX_EXTERNAL_IP.nip.io/docs
The front-end can be deployed to Cloud Run through the following steps:
- Build the container image
Replace <PROJECT_ID> with your Google Cloud Project ID.
gcloud builds submit --tag gcr.io/<PROJECT_ID>/bloggen-front
- Deploy the service to Cloud Run Replace environment variables with the correct values for your Cloud SQL instance configuration as well as service account email of previously created service account.
gcloud run deploy bloggen-front --image gcr.io/<PROJECT_ID>/bloggen-frontIf you are deploying for the first time, you will be prompted to enable the Cloud Run API. Enter y to enable the API. Another way to run the command is through the web console by navigating to Cloud Run and clicking on Create Service. Select the container image and click Deploy.
Take note of the URL output at the end of the deployment process.
Fork this repository. Create a feature branch. Commit your changes and open a pull request. License This project is licensed under the MIT License.
Feel free to reach out with questions or feedback. Enjoy building and scaling your blogging application on GCP!
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
