Mohamed KEITA
Deploying Your Flask App on Cloud Run: A Journey from Code to Cloud
July 30, 2024

Deploying to Cloud Run

Building a personal website is a rewarding experience, especially when it involves deploying a Flask application to the cloud. In this article, I'll walk you through the steps I took to deploy my Flask app using Google Cloud's Cloud Run. I'll share what went right, what went wrong, and some tips to make your deployment smoother.

Setting the Stage: The Flask Application

Before diving into the Dockerfile, let's quickly introduce the Flask application folder and its structure. Here's a typical layout of my Flask app:

my_flask_app/

├── app.py
├── requirements.txt
├── templates/
│   └── index.html
├── static/
│   ├── css/
│   ├── img/
│   ├── js/
│   └── pdf_files/
├── Dockerfile
└── .dockerignore

Breaking Down the Structure

  • app.py: The main Flask application file where the routes and logic are defined.
  • requirements.txt: Lists the dependencies required for the application.
  • templates/: Contains HTML templates for the application.
  • static/: Contains static files like CSS, JavaScript, images, and PDFs.
    • css/: Stylesheets for the website.
    • img/: Images used in the website.
    • js/: JavaScript files for added functionality.
    • pdf_files/: PDFs that are available for download or viewing.
  • Dockerfile: The file used to create the Docker image for containerizing the application.
  • .dockerignore: Specifies files and directories to ignore when building the Docker image.

Why Containerize Your Application?

Containerizing your application means packaging it along with all its dependencies, configurations, and libraries into a single, consistent unit. This approach offers several benefits:

  • Portability: Containers ensure that your application runs the same way, regardless of the environment.
  • Isolation: Each container operates independently of other containers, avoiding conflicts.
  • Scalability: Containers can be easily scaled up or down based on demand.
  • Simplified Deployment: Containers encapsulate everything your app needs, reducing deployment issues.

Creating the Dockerfile

The Dockerfile is a crucial part of containerizing your application. Here's what my Dockerfile looks like:

FROM python:3
ENV PYTHONUNBUFFERED True
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./
RUN pip install -r requirements.txt
RUN pip install Flask gunicorn
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 app:app

Breaking Down the Dockerfile

  • Base Image: Official Python 3 image.
  • Environment Variable: PYTHONUNBUFFERED=True ensures logs appear immediately.
  • Working Directory: Set to /app and local files are copied in.
  • Dependencies: Installed via requirements.txt and pip.
  • Running the App: Gunicorn is used to serve the Flask app in production.

The Gunicorn Gotcha

Initially, I omitted the gunicorn line. Without it, my deployment failed. Adding gunicorn solved the issue because it’s designed for production and handles multiple requests. You can also add gunicorn to requirements.txt and remove the install line in the Dockerfile.

Pushing to GitHub

Once the Dockerfile was ready, I pushed my changes to a private GitHub repository to safely store my code for deployment.

Deploying on Cloud Run

Now, the fun part begins — deploying to Cloud Run. GCP’s Cloud Run is a fully managed compute platform that runs stateless containers. It scales automatically and simplifies infrastructure management.

Step-by-Step Deployment

  1. Create a Cloud Run Project: Log into GCP and create a new project.
  2. Open Cloud Shell: Click the Cloud Shell button to open a terminal.
  3. Clone the Repository: Clone your GitHub repo and switch to the right branch.
  4. Deploy the App:
    • Use "Cloud Code" → "Deploy to Cloud Run".
    • Choose your settings: service name, region, etc.
    • Initially, I used europe-west9 (Paris) but had issues with my custom domain, so I switched to europe-west1 (Belgium).
    • Select "Allow unauthenticated invocations".
    • Click Deploy and wait 3–5 minutes.

The Domain Dilemma

Choosing the right region is important. I couldn’t use a custom domain with europe-west9 (Paris), but it worked with europe-west1 (Belgium). This might be due to regional limitations on domain features.

Custom Domain and CI/CD

After deployment, I connected a custom domain and set up CI/CD so the site auto-updates on GitHub pushes. I’ll cover this setup in a future article.

Conclusion

Deploying a Flask app on Cloud Run involves several steps, but the process is straightforward once you get the hang of it. Remember to configure your Dockerfile correctly and choose the right region for your deployment. With these tips, you'll have your Flask app running in the cloud in no time. Happy deploying!

Stay tuned for more articles where I'll dive deeper into CI/CD and other exciting topics related to web development and cloud deployment.