自学内容网 自学内容网

Docker Compose vs Docker Run:一个数据访问问题的排查与解决

问题背景

最近在部署一个前后端分离的应用时遇到了一个有趣的问题:使用 Docker Compose 部署时一切正常,但当使用独立的 Docker Run 命令部署时,后端无法正确访问数据。本文将详细讲解问题的排查过程和最终解决方案。

初始配置

Docker Compose 配置

services:
  backend:
    build: ./backend
    ports:
      - "8000:8000"
    volumes:
      - ./backend:/backend
    environment:
      - DATABASE_URL=sqlite:///./test.db
    networks:
      - app-network

  frontend:
    build:
      context: ./frontend
    ports:
      - "3000:3000"
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

独立的 Docker Run 命令

docker run -d -p 8000:8000 --name backend --network app-network backend-image
docker run -d -p 3000:3000 --name frontend --network app-network frontend-image

问题表现

当使用独立的 Docker Run 命令启动时,后端服务返回错误:

Number of stations with data: 0
Station coordinates shape: (0,)
Latest flows: []
Error: too many indices for array: array is 1-dimensional, but 2 were indexed

问题排查过程

1. 网络连接排查

首先确认是否是容器间网络通信问题。通过创建自定义网络解决:

docker network create app-network

2. 数据库连接排查

检查数据库连接配置:

SQLALCHEMY_DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./test.db")

发现默认配置是正确的。

3. 文件系统对比

对比两种部署方式下的文件系统差异:

# Docker Compose (正常工作)
-rwxrwxrwx 1 root root 800MB ... test.db

# Docker Run (不工作)
-rw-r--r-- 1 root root 106KB ... test.db

这个关键的发现揭示了问题的本质:

  • Docker Compose 通过 volume 挂载使用了宿主机的完整数据库文件
  • Docker Run 使用的是镜像中的数据库文件,而这个文件明显不完整

4. 根本原因分析

检查项目的 .dockerignore 文件,发现其中包含:

*.db

这导致构建镜像时忽略了数据库文件。

解决方案

  1. 修改 .dockerignore,移除 *.db 配置

  2. 重新构建镜像,确保数据库文件被正确打包

  3. 使用简化的部署命令:

# 创建网络
docker network create app-network

# 启动后端
docker run -d -p 8000:8000 --name backend --network app-network backend-image

# 启动前端
docker run -d -p 3000:3000 --name frontend --network app-network frontend-image

关键经验总结

  1. Docker Compose vs Docker Run 的关键差异

    • Compose 可以通过 volume 轻松挂载宿主机文件
    • Run 命令依赖镜像中打包的文件
    • 使用 Run 命令时需要确保镜像包含所有必要文件
  2. 文件打包注意事项

    • 注意 .dockerignore 的配置
    • 大文件也需要考虑是否打包进镜像
    • 权衡文件打包和外部挂载的利弊
  3. 最佳实践建议

    • 开发环境可以使用 volume 挂载以提高灵活性
    • 生产环境最好将所有必要文件打包进镜像
    • 提供清晰的部署文档,说明所有必要步骤

结论

这个案例展示了 Docker 不同部署方式的细微差别。虽然 Docker Compose 提供了更便捷的开发体验,但在生产环境中,我们需要确保镜像的完整性和独立性。最终的解决方案 - 将数据库文件打包进镜像 - 不仅解决了问题,还提供了更好的可移植性和部署简便性。


原文地址:https://blog.csdn.net/m0_37609579/article/details/144372071

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!