I have a FastAPI+SQLAlchemy+MariaDB application, which works fine when running local or in docker compose docker compose up
. But when I run it in swarm mode (docker stack deploy -c docker-compose.yml issuetest
), it creates an connection error after exactly 15 minutes of idle:
sqlalchemy.exc.OperationalError: (asyncmy.errors.OperationalError) (2013, 'Lost connection to MySQL server during query ([Errno 104] Connection reset by peer)')
The default MariaDB timeout should be 8 hours. I can avoid this issue by defining pool_recycle=60*10
(or any other value less than 15 minutes), but would like to understand, what went wrong.
To reproduce, here a minimalistic code sample of app/main.py
import uvicorn
from fastapi import FastAPI
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlmodel import Field, SQLModel, select
engine = create_async_engine("mysql+asyncmy://root:pw@mariadbhost/somedb", future=True)
app = FastAPI()
class Car(SQLModel, table=True):
id: int = Field(nullable=True, primary_key=True)
name: str
@app.on_event("startup")
async def on_startup():
async with engine.begin() as conn:
await conn.run_sync(SQLModel.metadata.create_all)
async def get_db_cars():
async with AsyncSession(engine) as session:
statement = select(Car)
result = await session.execute(statement)
cars = result.scalars().all()
return cars
@app.get("/dbcall")
async def dbcall():
return await get_db_cars()
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
And the docker-compose.yml file:
version: '3.1'
services:
mariadbhost:
image: mariadb:10.7
environment:
MYSQL_ROOT_PASSWORD: pw
MYSQL_DATABASE: somedb
mybackend:
image: myimage
ports:
- 8089:80