Skip to content

Commit 8a1b3e3

Browse files
committed
Template for FastAPI + Docker + uv + direnv + Cloud Run
1 parent 51ece88 commit 8a1b3e3

File tree

9 files changed

+328
-0
lines changed

9 files changed

+328
-0
lines changed

fastapi-docker-cloudrun/.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.venv
2+
__pycache__

fastapi-docker-cloudrun/.envrc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# this function is from https://github.com/direnv/direnv/issues/1338
2+
# maybe one day there will be a more official version
3+
4+
layout_uv() {
5+
if [[ -d "$UV_PROJECT_ENVIRONMENT" ]]; then
6+
log_status "Existing project virtual environment \'$UV_PROJECT_ENVIRONMENT\'"
7+
else
8+
log_status "No project virtual environment exists."
9+
10+
if [[ ! -f "pyproject.toml" ]]; then # No project in-place
11+
log_status "Initializing a new Python project via \`uv init\`."
12+
uv init --no-readme
13+
else
14+
log_status "Python project already initialized. Skipping \`uv init\`."
15+
fi
16+
[[ -f "hello.py" ]] && rm hello.py # a file created by `uv init`
17+
18+
if [[ ! -z "$UV_PROJECT_ENVIRONMENT" ]]; then
19+
log_status "Project virtual environment path set to : $UV_PROJECT_ENVIRONMENT"
20+
uv venv "$UV_PROJECT_ENVIRONMENT"
21+
else
22+
uv venv
23+
UV_PROJECT_ENVIRONMENT="$(pwd)/.venv"
24+
fi
25+
fi
26+
27+
PATH_add "$UV_PROJECT_ENVIRONMENT/bin"
28+
export UV_ACTIVE=1 # or VENV_ACTIVE=1
29+
export UV_PROJECT_ENVIRONMENT
30+
}
31+
32+
export UV_PROJECT_ENVIRONMENT=.venv
33+
dotenv
34+
layout uv

fastapi-docker-cloudrun/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.venv
2+
__pycache__
3+
.env
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.11

fastapi-docker-cloudrun/Dockerfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM python:3.13.2-slim-bookworm
2+
COPY --from=ghcr.io/astral-sh/uv:0.6.8 /uv /uvx /bin/
3+
4+
# StreamHandler in CPython already flushes after each emit/line, not entirely sure if this is really necessary
5+
ENV PYTHONUNBUFFERED=1
6+
ENV PORT=1234
7+
8+
WORKDIR /app
9+
ADD . /app
10+
RUN uv sync --frozen
11+
12+
# As an example here we're running the web service with one worker on uvicorn.
13+
CMD ["uv", "run", "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "${PORT}", "--workers", "1", "--app-dir", "src"]

fastapi-docker-cloudrun/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
FastAPI + Docker + uv + direnv + Cloud Run
2+
==========================================
3+
4+
Local without docker:
5+
=====================
6+
7+
install uv
8+
9+
install direnv:
10+
11+
https://github.com/direnv/direnv/blob/master/docs/installation.md
12+
13+
add direnv hook:
14+
15+
https://github.com/direnv/direnv/blob/master/docs/hook.md
16+
17+
uvicorn server:app --host 0.0.0.0 --port 1234 --workers 1 --app-dir src
18+
19+
Local with docker
20+
===================
21+
22+
Create .env, and add:
23+
24+
PROJECT_ID=<YOUR_UNIQUE_LOWER_CASE_PROJECT_ID>
25+
APP=<app name>
26+
PORT=1234
27+
TAG="gcr.io/$PROJECT_ID/$APP"
28+
REGION="europe-west1"
29+
30+
Then:
31+
32+
```
33+
export TAG="gcr.io/$PROJECT_ID/$APP"
34+
```
35+
36+
docker build -t $TAG .
37+
docker run --rm -dp $PORT:$PORT -e PORT=$PORT $TAG
38+
39+
Cloud run:
40+
==========
41+
42+
Set up project, billing project etc (some hints at https://github.com/sekR4/FastAPI-on-Google-Cloud-Run)
43+
44+
To build
45+
46+
```
47+
gcloud builds submit --tag $TAG
48+
```
49+
50+
To deploy:
51+
52+
``
53+
gcloud run deploy $APP --image $TAG --platform managed --region $REGION
54+
```
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[project]
2+
name = "fastapi-docker-cloudrun"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
readme = "README.md"
6+
requires-python = ">=3.11"
7+
dependencies = [
8+
"fastapi>=0.115.11",
9+
"uvicorn>=0.34.0",
10+
]

fastapi-docker-cloudrun/src/server.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from fastapi import FastAPI
2+
3+
app = FastAPI()
4+
5+
6+
@app.get("/")
7+
async def root():
8+
return {"message": "Hello World"}

fastapi-docker-cloudrun/uv.lock

Lines changed: 203 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)