You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose中Flask应用无法连接SQL Server容器问题求助

问题分析与解决方法

一、init.sql脚本未执行(数据库未创建)

官方SQL Server Docker镜像不支持/docker-entrypoint-initdb.d/目录自动执行脚本(这是MySQL镜像的特性),这是脚本未生效的核心原因。同时你的Flask连接的数据库是recipes,但init.sql创建的是TestDB,两者不匹配,需统一。

解决步骤:

  1. 修改初始化脚本执行方式
    创建自定义启动脚本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
  1. 调整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
  1. 统一数据库名称
    修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:53:14