Building a FastAPI or Flask app in Coolify with UV

Ray BergerRay Berger
3 min read

So, you want to start a new Python app for Coolify with the latest and greatest tools? Here’s how to do it.

At the end of the day, the process is relatively simple. However, despite having worked with all of these tools on existing projects, I hadn’t really set up new projects with them and didn’t find a complete guide so here goes.

Tools Involved

  • uv - the replacement for pip that has been skyrocketing in popularity. It takes away a lot of the pain points.
  • fastapi or flask - two popular web frameworks for Python. Flask is very barebones and time tested. fastapi is more full featured with batteries included.
  • coolify - a very simple and easy tool for self hosting apps. Similar to Heroku or Vercel. (This tutorial assumes you already have coolify setup)
  • nixpacks - this automatically generates docker images for you based on your repo’s structure.
  • GitHub - hosted version control. Mentioning this here because we’ll have a push-to-deploy setup.

Steps to Deploy Your App

  1. Initialize your uv project: This command sets up your Python project structure, creating essential files like pyproject.toml to manage dependencies.

    uv init hello-world && cd hello-world
    
  2. Add your web framework dependency: Use uv add to install either fastapi (with optional extras like standard for uvicorn and pydantic) or the classic flask.

    # For FastAPI
    uv add "fastapi[standard]"
    
    # Or for Flask
    uv add flask
    
  3. Create your application code: Add starter code to main.py. Here's the example from the FastAPI documentation:

    # main.py
    from typing import Union
    from fastapi import FastAPI
    
    app = FastAPI()
    
    @app.get("/")
    def read_root():
        return {"Hello": "World"}
    
    @app.get("/items/{item_id}")
    def read_item(item_id: int, q: Union[str, None] = None):
        return {"item_id": item_id, "q": q}
    
  4. Configure the start command for Nixpacks: Create a nixpacks.toml file. This tells Nixpacks (and therefore Coolify) how to run your application inside the container.

    touch nixpacks.toml
    

    Add the following content. We use port 3000 as it's the default Coolify expects.

    For FastAPI (using uvicorn):

    # nixpacks.toml
    [start]
    cmd = "fastapi run main.py --port 3000"
    

    For Flask (using gunicorn):

    # nixpacks.toml
    [start]
    cmd = "gunicorn -w 4 -b 0.0.0.0:3000 main:app"
    
  5. Commit your code:

    git add .
    git commit -m "Initial project setup"
    # Push to your GitHub repository
    git push origin main
    
  6. Configure the application in Coolify:

    • Go to your Coolify dashboard and create a new application.
    • Select "GitHub" as the source and choose the repository you just pushed.
    • Coolify should automatically detect Nixpacks as the build pack and 3000 as the port based on your nixpacks.toml.
  7. Deploy:

    • Click the "Deploy" button.
    • After the initial deployment, Coolify will automatically redeploy your application every time you push changes to your configured GitHub branch.

Final Notes

If you’re not using GitHub you can also configure webhooks in Coolify.

You probably want to add a .gitignore file for the __pycache__ directory

This is written for Coolify v4. Since v5 was just announced by the time you read this things on the Coolify side may have changed.

The source code for the Flask version is available here.

Thanks for reading!

10
Subscribe to my newsletter

Read articles from Ray Berger directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ray Berger
Ray Berger

MSc Candidate in Urban Studies, Software Engineer