Docker Compose中Flask应用无法连接SQL Server容器问题求助
问题分析与解决方法
一、init.sql脚本未执行(数据库未创建)
官方SQL Server Docker镜像不支持/docker-entrypoint-initdb.d/目录自动执行脚本(这是MySQL镜像的特性),这是脚本未生效的核心原因。同时你的Flask连接的数据库是recipes,但init.sql创建的是TestDB,两者不匹配,需统一。
解决步骤:
- 修改初始化脚本执行方式
创建自定义启动脚本entrypoint.sh,等待SQL Server服务就绪后执行初始化脚本:
#!/bin/bash # 启动SQL Server后台进程 /opt/mssql/bin/sqlservr & # 等待服务启动(根据实际情况调整等待时间) sleep 30s # 执行初始化脚本 /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "YourStrong@Passw0rd" -i /init.sql # 保持容器运行 wait
给脚本添加执行权限:
chmod +x entrypoint.sh
- 调整docker-compose.yml配置
挂载自定义启动脚本和init.sql,替换SQL Server容器的entrypoint:
sqlserver: image: mcr.microsoft.com/mssql/server:2019-latest environment: SA_PASSWORD: YourStrong@Passw0rd ACCEPT_EULA: Y volumes: - ./init.sql:/init.sql - ./entrypoint.sh:/entrypoint.sh entrypoint: /bin/bash /entrypoint.sh ports: - "14500:1433" networks: - app_network
- 统一数据库名称
修改init.sql创建Flask需要的recipes数据库:
USE master; IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = 'recipes') CREATE DATABASE recipes;
二、Flask应用登录超时
depends_on仅保证容器启动顺序,不保证SQL Server服务已完全就绪,Flask启动时SQL Server可能还在初始化,导致连接超时。
解决方法(二选一):
方法1:在Flask中添加连接重试逻辑
修改app.py的连接代码,增加重试机制:
import pyodbc import time # SQL Server连接配置 server = 'sqlserver' database = 'recipes' username = 'SA' password = 'YourStrong@Passw0rd' # 重试连接逻辑 conn = None cursor = None max_retries = 10 retry_count = 0 while retry_count < max_retries: try: conn = pyodbc.connect(f'DRIVER=ODBC Driver 17 for SQL Server; SERVER={server};DATABASE={database};UID={username};PWD={password}') cursor = conn.cursor() print("SQL Server连接成功") break except pyodbc.OperationalError: print(f"连接失败,重试中 ({retry_count+1}/{max_retries})...") time.sleep(5) retry_count += 1 if not conn: raise Exception("多次重试后仍无法连接SQL Server") # 检查表是否存在,避免重复创建 cursor.execute("IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'recipes') CREATE TABLE recipes (id INT IDENTITY(1,1) PRIMARY KEY, name VARCHAR(100), instructions VARCHAR(1000))")
方法2:使用wait-for-it脚本等待端口就绪
- 下载
wait-for-it.sh脚本到项目目录,添加执行权限:chmod +x wait-for-it.sh - 修改Flask的Dockerfile,添加等待逻辑:
FROM python:3.9-slim WORKDIR /app # 安装ODBC驱动(必须步骤,否则Flask找不到SQL Server驱动) RUN apt-get update && apt-get install -y \ unixodbc-dev \ && curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \ && curl https://packages.microsoft.com/config/debian/10/prod.list > /etc/apt/sources.list.d/mssql-release.list \ && apt-get update \ && ACCEPT_EULA=Y apt-get install -y msodbcsql17 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY wait-for-it.sh . COPY app.py . # 等待SQL Server 1433端口开放后再启动Flask CMD ["./wait-for-it.sh", "sqlserver:1433", "--", "python", "app.py"]
三、额外注意事项
- 确保Flask镜像中安装了ODBC Driver 17 for SQL Server(上述Dockerfile已包含该步骤)
- 验证SA密码符合SQL Server复杂度要求(你的密码
YourStrong@Passw0rd符合要求,需保持配置一致) - 启动容器前先清理旧容器:
docker-compose down -v,避免残留数据影响测试
内容的提问来源于stack exchange,提问作者Christian Sugarol
相关产品推荐
相关产品推荐

