如何调整Docker Compose使容器化FastAPI连接本地Ubuntu的MariaDB
将容器化MariaDB迁移到本地Ubuntu主机的配置指南
步骤1:修改Docker Compose文件
直接移除原配置中的mariadb服务块,同时删除两个FastAPI服务里的depends_on: - mariadb项——现在数据库不在容器内,无需依赖容器启动顺序。
给每个FastAPI服务添加extra_hosts配置,对应docker run中的--add-host=host.docker.internal:host-gateway参数,让容器能访问本地主机。
修改后的完整Docker Compose如下:
version: '3' services: traefik: image: traefik:v2.5 network_mode: "host" container_name: traefik command: - "--api.insecure=true" - "--providers.docker=true" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.myresolver.acme.tlschallenge=true" - "--certificatesresolvers.myresolver.acme.email=myemail@mydomain.com" - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" volumes: - "./letsencrypt:/letsencrypt" - "/var/run/docker.sock:/var/run/docker.sock:ro" labels: - 'traefik.http.services.traefik.loadbalancer.server.port=443' fastapi-api1: build: context: ./API1/ dockerfile: Dockerfile volumes: - "./files_user:/files" # 添加配置让容器访问本地主机 extra_hosts: - "host.docker.internal:host-gateway" labels: - 'traefik.enable=true' - 'traefik.http.routers.fastapi-api1.rule=Host(`ap1.mydomain.com`) && PathPrefix(`/`)' - 'traefik.http.routers.fastapi-api1.entrypoints=websecure' - "traefik.http.routers.fastapi-api1.tls.certresolver=myresolver" - 'traefik.http.routers.fastapi-api1.tls=true' - 'traefik.http.services.fastapi-api1.loadbalancer.server.port=8000' container_name: fastapi-api1 # 移除依赖容器的配置 command: bash -c "uvicorn app.main:app --host 0.0.0.0 --port 8000 --timeout-keep-alive 240" restart: "on-failure:5" fastapi-api2: build: context: ./API2/ dockerfile: Dockerfile volumes: - "./files:/files" # 添加配置让容器访问本地主机 extra_hosts: - "host.docker.internal:host-gateway" labels: - 'traefik.enable=true' - 'traefik.http.routers.fastapi-api2.rule=Host(`api2.mydomain.com`) && PathPrefix(`/`)' - 'traefik.http.routers.fastapi-api2.entrypoints=websecure' - "traefik.http.routers.fastapi-api2.tls.certresolver=myresolver" - 'traefik.http.routers.fastapi-api2.tls=true' - 'traefik.http.services.fastapi-api2.loadbalancer.server.port=8001' container_name: fastapi-api2 # 移除依赖容器的配置 command: bash -c "uvicorn app.main:app --host 0.0.0.0 --port 8001" restart: "on-failure:5"
步骤2:调整数据库连接配置
把环境变量DB_Container_Name的值改为host.docker.internal,FastAPI就能通过这个地址访问本地主机上的MariaDB。修改后的连接代码示例:
connection_url_api = URL.create( "mariadb+mariadbconnector", username=DB_Username_API, password=DB_Password_API, host=DB_Container_Name, # 该变量值现在为"host.docker.internal" port=3306, database=DB_Name_For_Api_Tables, query=dict(charset="utf8mb4") )
步骤3:配置本地MariaDB允许外部连接
默认MariaDB仅允许本地访问,需做以下修改:
- 编辑配置文件
/etc/mysql/mariadb.conf.d/50-server.cnf,将bind-address改为0.0.0.0,保存后重启服务:sudo systemctl restart mariadb - 创建允许容器访问的数据库用户(替换为你的实际信息):
CREATE USER 'api_user'@'%' IDENTIFIED BY 'your_password'; GRANT ALL PRIVILEGES ON your_api_db.* TO 'api_user'@'%'; FLUSH PRIVILEGES;
关于启动延迟(sleep 10)
本地MariaDB是常驻服务,无需等待容器启动,可直接删除sleep 10。若担心MariaDB偶尔重启导致连接失败,建议在FastAPI代码中添加数据库连接重试逻辑(比如SQLAlchemy的pool_pre_ping参数),比固定延迟更可靠。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

