#Docker 遇到的报错信息汇总

390 阅读3分钟

记录一下在项目中遇到的Docker报错信息

MySQL数据库和Prisma相关

docker-compose.yml文件

mysql:
  container_name: mysql_container # 容器名称
  image: mysql:8.0.32 # 使用官方镜像
  ports:
    - 3306:3306 # 本机端口:容器端口
  restart: on-failure # 在失败时重启
  environment:
    - MYSQL_ROOT_PASSWORD=888888 # root用户密码
    - MYSQL_DATABASE=mysql_database # 初始化时创建的数据库
  volumes:
    - ./deploy/mysql/db:/var/lib/mysql # 本地路径:容器内路径 -> 用来存放数据库表文件
    - ./deploy/mysql/conf/my.cnf:/etc/my.cnf # 存放自定义的配置文件
    # 我们在启动MySQL容器时自动创建我们需要的数据库和表
    # mysql官方镜像中提供了容器启动时自动docker-entrypoint-initdb.d下的脚本的功能
    - ./deploy/mysql/init:/docker-entrypoint-initdb.d/ # 存放初始化的脚本

server:
  # 容器名称
  container_name: server_container
  # 构建目录
  build:
    context: .
    dockerfile: prod.Dockerfile
  # 重启规则
  restart: on-failure # 设置自动重启,这一步必须设置,主要是存在mysql还没有启动完成就启动了node服务
  # 暴露端口
  expose:
    - 3000
  ports:
    - 3000:3000
  # 构建依赖
  depends_on:
    - mysql
  env_file:
    - .env
  # 环境变量
  environment:
    - RUN_TIME_ENV=local

.env文件

DATABASE_URL="mysql://root:888888@localhost:3306/mysql_database"

报错信息

无法连接到本地3306端口的MySQL服务

 PrismaClientInitializationError: Can't reach database server at `localhost`:`3306`
原因

在进行本地开发的时候,使用Prisma作为ORM工具,Prisma需要在本地创建一个.env文件并在文件中指明需要连接的数据库信息(文件内容就是上面的.env);

这样的写法在本地开发时没有问题,因为就算你在本地用容器单独跑了一个MySQL的服务,那也是在本地环境暴露3306端口,所以对于不是在容器中的项目来说,自然可以连接;

但是现在当我们把项目MySQL服务放在同一个容器内时,对于项目中的Prisma来说,就找不到localhost这个地址了;

解决办法

docker-compose中,如果多个服务是通过同一个docker-compose启动的话,就可以通过yml文件中配置的几个服务的名称进行通信,所以我们需要在本地项目中

  1. 新建一个.env.prod文件用于Docker构建
# env.prod
DATABASE_URL="mysql://root:888888@mysql:3306/mysql_database"
  1. 然后修改docker-compose.yml
# ...
env_file:
    - .env # 改成 .env.prod
# ...

即可。

Prisma连接MySQL服务之后提示数据库不存在

 PrismaClientInitializationError: Database `mysql_database` does not exist on the database server at `mysql:3306`.
原因

出现这个问题的原因一般有两个

  1. 没有在MySQL初始化的时候指定需要自动创建的数据库
  2. 数据库的自动创建操作尚未完成
解决办法
  1. 针对第一种情况,我们需要在docker-compose.yml文件的mysql部分添加
environment:
    - MYSQL_DATABASE=mysql_database # 初始化时创建的数据库
  1. 针对第二种情况,只需要等待数据库创建完成即可,创建完成后Prisma就不会再有这个错误提示了。

包管理工具相关(npm & pnpm)

报错信息

提示文件冲突

error: failed to solve: cannot replace to directory /var/lib/docker/overlay2/*/*/folder_a with file
原因

出现这个问题,有一个可能的原因是在本地项目中使用的包管理工具与在Dockerfile构建中使用的包管理工具不同。例如我的项目中就有这个问题,本地使用的是pnpm,而在Dockerfile中只拷贝了package*.json,并且使用npm ci进行依赖安装。所以当本地的依赖发生更新之后,Dockerfile中拿到的依然是旧的依赖文件,所以就会出现问题。

解决办法
  1. 删除本地的node_modulespackage.lock.json
  2. 使用Dockerfile中指定的包管理工具(对我来说就是npm)安装本地依赖,从而生成新的package.lock.json
  3. 即可。

如果还有更好的方法,欢迎评论👏🏻