Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 49 additions & 45 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,54 +1,58 @@
#Dockerfile

# syntax=docker/dockerfile:1

# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/go/dockerfile-reference/

# Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7

ARG PYTHON_VERSION=3.13.1
FROM python:${PYTHON_VERSION}-slim AS base

# Prevents Python from writing pyc files.
ENV PYTHONDONTWRITEBYTECODE=1
############################
# 1️⃣ Base Image
############################
FROM python:3.12-slim AS base

# Keeps Python from buffering stdout and stderr to avoid situations where
# the application crashes without emitting any logs due to buffering.
ENV PYTHONUNBUFFERED=1
# Environment settings
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PORT=8080

WORKDIR /app

# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/go/dockerfile-user-best-practices/
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser

# Download dependencies as a separate step to take advantage of Docker's caching.
# Leverage a cache mount to /root/.cache/pip to speed up subsequent builds.
# Leverage a bind mount to requirements.txt to avoid having to copy them into
# into this layer.
RUN --mount=type=cache,target=/root/.cache/pip \
--mount=type=bind,source=requirements.txt,target=requirements.txt \
python -m pip install -r requirements.txt

# Switch to the non-privileged user to run the application.
USER appuser

# Copy the source code into the container.
############################
# 2️⃣ System Dependencies
############################
RUN apt-get update && apt-get install -y \
build-essential \
curl \
&& rm -rf /var/lib/apt/lists/*

############################
# 3️⃣ Install Python Dependencies
############################
COPY requirements.txt .

RUN pip install --upgrade pip \
&& pip install --no-cache-dir -r requirements.txt

############################
# 4️⃣ Create Non-Root User
############################
RUN addgroup --system appgroup && \
adduser --system --ingroup appgroup appuser

############################
# 5️⃣ Copy Application Code
############################
COPY . .

# Expose the port that the application listens on.
EXPOSE 8000

# Run the application.
CMD ["uvicorn", "app.v1.app:app", "--host", "0.0.0.0", "--port", "8000"]
############################
# 6️⃣ Switch to Non-Root User
############################
USER appuser

############################
# 7️⃣ Expose Cloud Run Port
############################
EXPOSE 8080

############################
# 8️⃣ Production Server Command
############################
CMD ["uvicorn", "app.v1.app:app", \
"--host", "0.0.0.0", \
"--port", "8080", \
"--workers", "2"]
2 changes: 1 addition & 1 deletion app/v1/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def rate_limit_key(request: Request):

limiter = Limiter(key_func=rate_limit_key)

app = FastAPI()
app = FastAPI(docs_url=None, redoc_url=None)

app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
Expand Down
2 changes: 1 addition & 1 deletion compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ services:
build:
context: .
ports:
- "8000:8000"
- "8080:8080"
env_file:
- .env
volumes:
Expand Down
2 changes: 1 addition & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
import uvicorn

if __name__ == "__main__":
uvicorn.run("app.v1.app:app", host="0.0.0.0", port=8000, reload=True)
uvicorn.run("app.v1.app:app", host="0.0.0.0", port=8080)
Loading