将基于Actix-web、Diesel.rs的Rust项目部署到TrueNAS Scale遇MySQL问题
解决Rust项目(Diesel+Actix-web)部署到TrueNAS Scale时MySQL连接失败问题
你的核心问题是Docker镜像构建阶段执行diesel migration run,此时MySQL容器尚未启动,且构建环境中的localhost指向backend容器自身,而非db服务容器。同时depends_on仅保证启动顺序,无法确保MySQL完全就绪,以下是具体修复方案:
1. 调整Dockerfile,移除构建阶段的迁移命令
构建镜像时没有可用的MySQL服务,必须把迁移命令移到容器启动阶段。修改后的Dockerfile:
FROM rust:latest # Install system dependencies RUN apt-get update && \ apt-get install -y --no-install-recommends \ pkg-config \ libssl-dev \ ffmpeg \ && rm -rf /var/lib/apt/lists/* RUN mkdir /app WORKDIR /app # 复制项目文件 COPY . . # 预构建项目(可选,减少启动时间) RUN cargo build --release # 启动时先执行迁移,再启动服务(替换your_app_name为实际可执行文件名) CMD ["sh", "-c", "diesel migration run && ./target/release/your_app_name"]
2. 修正数据库连接配置
确保Diesel配置文件(Diesel.toml)或环境变量中的数据库URL指向db服务容器,而非localhost:
[production] database_url = "mysql://root:root@db/movies"
这里的db是docker-compose中定义的服务名,Docker会自动解析该域名到对应的容器IP。
3. 完善Docker Compose配置
3.1 增加健康检查与初始化文件挂载
depends_on需要配合健康检查,确保MySQL服务完全就绪后再启动backend;同时挂载初始化脚本到MySQL容器的默认初始化目录:
version: '3.8' services: db: image: mysql:latest command: --default-authentication-plugin=mysql_native_password restart: always environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: movies # 提前创建目标数据库,避免迁移报错 ports: - 3306:3306 volumes: # 挂载本地init.sql到容器初始化目录,自动执行 - ./init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: # 检查MySQL服务是否就绪 test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot"] interval: 5s timeout: 5s retries: 5 backend: depends_on: db: condition: service_healthy # 等待db健康检查通过再启动 build: context: ./backend dockerfile: Dockerfile ports: - 8080:8080 environment: # 传递数据库URL到容器环境变量(可选,用于覆盖Diesel.toml配置) DATABASE_URL: "mysql://root:root@db/movies"
3.2 规范init.sql内容
如果需要额外初始化权限或数据,init.sql示例如下(放在docker-compose.yml同级目录):
-- 授予root用户远程访问权限(根据实际需求调整) GRANT ALL PRIVILEGES ON movies.* TO 'root'@'%' IDENTIFIED BY 'root'; FLUSH PRIVILEGES;
4. 验证部署
执行以下命令启动服务,查看日志确认迁移和服务启动成功:
docker-compose up --build
内容的提问来源于stack exchange,提问作者filif96770
相关产品推荐
相关产品推荐

