feat: add Dockerfile and supervisord configuration for FastAPI application
This commit is contained in:
37
Dockerfile
Normal file
37
Dockerfile
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS builder
|
||||||
|
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
|
||||||
|
|
||||||
|
# Disable Python downloads, because we want to use the system interpreter
|
||||||
|
# across both images. If using a managed Python version, it needs to be
|
||||||
|
# copied from the build image into the final image; see `standalone.Dockerfile`
|
||||||
|
# for an example.
|
||||||
|
ENV UV_PYTHON_DOWNLOADS=0
|
||||||
|
|
||||||
|
# Install git
|
||||||
|
RUN apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||||
|
--mount=type=bind,source=uv.lock,target=uv.lock \
|
||||||
|
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
|
||||||
|
uv sync --locked --no-install-project --no-dev
|
||||||
|
COPY . /app
|
||||||
|
RUN --mount=type=cache,target=/root/.cache/uv \
|
||||||
|
uv sync --locked --no-dev
|
||||||
|
|
||||||
|
# Then, use a final image without uv
|
||||||
|
FROM python:3.13-slim-bookworm
|
||||||
|
# It is important to use the image that matches the builder, as the path to the
|
||||||
|
# Python executable must be the same, e.g., using `python:3.11-slim-bookworm`
|
||||||
|
# will fail.
|
||||||
|
RUN apt-get update && apt-get install -y supervisor && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Copy the application from the builder
|
||||||
|
COPY --from=builder --chown=app:app /app /app
|
||||||
|
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||||
|
|
||||||
|
# Place executables in the environment at the front of the path
|
||||||
|
ENV PATH="/app/.venv/bin:$PATH"
|
||||||
|
WORKDIR /app
|
||||||
|
# Run the FastAPI application by default
|
||||||
|
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
||||||
@ -14,9 +14,9 @@ dependencies = [
|
|||||||
"python-dotenv>=1.1.1",
|
"python-dotenv>=1.1.1",
|
||||||
"redis[hiredis]>=6.2.0",
|
"redis[hiredis]>=6.2.0",
|
||||||
"sqlalchemy[asyncio]>=2.0.41",
|
"sqlalchemy[asyncio]>=2.0.41",
|
||||||
"uvicorn>=0.35.0",
|
"uvicorn[standard]>=0.35.0",
|
||||||
"fastapi-endpoints @ git+https://github.com/vladNed/fastapi-endpoints.git@main"
|
"fastapi-endpoints @ git+https://github.com/vladNed/fastapi-endpoints.git@main",
|
||||||
|
"uvicorn-worker>=0.3.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
|
|||||||
0
run/.gitkeep
Normal file
0
run/.gitkeep
Normal file
0
static/.gitkeep
Normal file
0
static/.gitkeep
Normal file
10
supervisord.conf
Normal file
10
supervisord.conf
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[supervisord]
|
||||||
|
|
||||||
|
[program:uvicorn]
|
||||||
|
command=/app/.venv/bin/uvicorn main:app --uds /app/run/socket%(process_num)d.sock
|
||||||
|
numprocs=4
|
||||||
|
process_name=uvicorn-%(process_num)d
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
stdout_logfile=/dev/stdout
|
||||||
|
stderr_logfile=/dev/stderr
|
||||||
19
uv.lock
generated
19
uv.lock
generated
@ -241,7 +241,8 @@ dependencies = [
|
|||||||
{ name = "python-dotenv" },
|
{ name = "python-dotenv" },
|
||||||
{ name = "redis", extra = ["hiredis"] },
|
{ name = "redis", extra = ["hiredis"] },
|
||||||
{ name = "sqlalchemy", extra = ["asyncio"] },
|
{ name = "sqlalchemy", extra = ["asyncio"] },
|
||||||
{ name = "uvicorn" },
|
{ name = "uvicorn", extra = ["standard"] },
|
||||||
|
{ name = "uvicorn-worker" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dev-dependencies]
|
[package.dev-dependencies]
|
||||||
@ -262,7 +263,8 @@ requires-dist = [
|
|||||||
{ name = "python-dotenv", specifier = ">=1.1.1" },
|
{ name = "python-dotenv", specifier = ">=1.1.1" },
|
||||||
{ name = "redis", extras = ["hiredis"], specifier = ">=6.2.0" },
|
{ name = "redis", extras = ["hiredis"], specifier = ">=6.2.0" },
|
||||||
{ name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0.41" },
|
{ name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0.41" },
|
||||||
{ name = "uvicorn", specifier = ">=0.35.0" },
|
{ name = "uvicorn", extras = ["standard"], specifier = ">=0.35.0" },
|
||||||
|
{ name = "uvicorn-worker", specifier = ">=0.3.0" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata.requires-dev]
|
[package.metadata.requires-dev]
|
||||||
@ -1088,6 +1090,19 @@ standard = [
|
|||||||
{ name = "websockets" },
|
{ name = "websockets" },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uvicorn-worker"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = { registry = "https://pypi.org/simple" }
|
||||||
|
dependencies = [
|
||||||
|
{ name = "gunicorn" },
|
||||||
|
{ name = "uvicorn" },
|
||||||
|
]
|
||||||
|
sdist = { url = "https://files.pythonhosted.org/packages/37/c0/b5df8c9a31b0516a47703a669902b362ca1e569fed4f3daa1d4299b28be0/uvicorn_worker-0.3.0.tar.gz", hash = "sha256:6baeab7b2162ea6b9612cbe149aa670a76090ad65a267ce8e27316ed13c7de7b", size = 9181 }
|
||||||
|
wheels = [
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f7/1f/4e5f8770c2cf4faa2c3ed3c19f9d4485ac9db0a6b029a7866921709bdc6c/uvicorn_worker-0.3.0-py3-none-any.whl", hash = "sha256:ef0fe8aad27b0290a9e602a256b03f5a5da3a9e5f942414ca587b645ec77dd52", size = 5346 },
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uvloop"
|
name = "uvloop"
|
||||||
version = "0.21.0"
|
version = "0.21.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user