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

Docker Compose创建MySQL卷目录所有者异常的原因与解决方法

问题描述

使用环境

Linux Mint 21.1 Cinnamon + Docker Desktop

docker-compose.yaml 文件内容

version: '3.7'
services:
  backend:
    container_name: admin_api
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      DB_HOST: db
      DB_DATABASE: database_name
      DB_USERNAME: admin_user
      DB_PASSWORD: not_root_password
    ports:
      - 8000:8000
    volumes:
      - .:/app
    networks:
      - app
    depends_on:
      - db

  db:
    container_name: admin_db
    image: mysql:8
    ports:
      - 3306:3306
    volumes:
      - ./db-data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root_password
      - MYSQL_PASSWORD=not_root_password
      - MYSQL_USER=admin_user
      - MYSQL_DATABASE=database_name
    networks:
      - app

networks:
  app:

本地用户ID信息

执行id命令输出:

alex@dell:~/Projects/laravel-admin$ id
uid=1000(alex) gid=1000(alex) groups=1000(alex),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),109(kvm),115(lpadmin),136(sambashare)

异常现象

成功执行docker compose up后,db-data目录被创建且数据正常,但所有者为100998:

alex@dell:~/Projects/laravel-admin$ ls -la
total 392
drwxr-xr-x 14 alex   alex   4096 May 24 23:12 .
drwxrwxr-x  4 alex   alex   4096 May 23 20:11 ..
drwxr-xr-x  7 alex   alex   4096 May 23 20:12 app
-rwxr-xr-x  1 alex   alex   1686 May 16 17:38 artisan
drwxr-xr-x  3 alex   alex   4096 May 23 20:12 bootstrap
-rw-r--r--  1 alex   alex   1853 May 16 17:38 composer.json
-rw-r--r--  1 alex   alex 289022 May 23 21:43 composer.lock
drwxr-xr-x  2 alex   alex   4096 May 23 23:35 config
drwxr-xr-x  5 alex   alex   4096 May 23 20:12 database
drwxr-xr-x  8 100998 alex   4096 May 24 23:12 db-data <------- 此处所有者为异常值100998
-rw-r--r--  1 alex   alex    709 May 24 23:06 docker-compose.yaml
-rw-r--r--  1 alex   alex    351 May 24 21:49 Dockerfile
-rw-r--r--  1 alex   alex    258 May 16 17:38 .editorconfig
-rw-r--r--  1 alex   alex   1156 May 24 21:14 .env
...

尝试解决后的问题

在db服务中添加user: "1000:1000"配置:

...
  db:
    user: "1000:1000" <--- 新增配置
  ...

执行docker compose up时,db服务启动报错:

admin_db   | 2023-05-24 21:20:05+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.33-1.el8 started.
admin_db   | 2023-05-24 21:20:06+00:00 [Note] [Entrypoint]: Initializing database files
admin_db   | mysqld: Can't create/write to file '/var/lib/mysql/is_writable' (OS errno 13 - Permission denied)
admin_db   | 2023-05-24T21:20:06.029099Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
admin_db   | 2023-05-24T21:20:06.029218Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.33) initializing of server in progress as process 41
admin_db   | 2023-05-24T21:20:06.031268Z 0 [ERROR] [MY-010460] [Server] --initialize specified but the data directory exists and is not writable. Aborting.
admin_db   | 2023-05-24T21:20:06.031276Z 0 [ERROR] [MY-013236] [Server] The designated data directory /var/lib/mysql/ is unusable. You can remove all files that the server added to it.
admin_db   | 2023-05-24T21:20:06.031309Z 0 [ERROR] [MY-010119] [Server] Aborting
admin_db   | 2023-05-24T21:20:06.031453Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.33)  MySQL Community Server - GPL.
admin_db exited with code 1

此时db-data目录所有者变为alex,但目录为空:

alex@dell:~/Projects/laravel-admin$ ls -la                 
total 392
drwxr-xr-x 14 alex alex   4096 May 24 23:20 .
drwxrwxr-x  4 alex alex   4096 May 23 20:11 ..
drwxr-xr-x  7 alex alex   4096 May 23 20:12 app
-rwxr-xr-x  1 alex alex   1686 May 16 17:38 artisan
drwxr-xr-x  3 alex alex   4096 May 23 20:12 bootstrap
-rw-r--r--  1 alex alex   1853 May 16 17:38 composer.json
-rw-r--r--  1 alex alex 289022 May 23 21:43 composer.lock
drwxr-xr-x  2 alex alex   4096 May 23 23:35 config
drwxr-xr-x  5 alex alex   4096 May 23 20:12 database
drwxr-xr-x  2 alex alex   4096 May 24 23:20 db-data <-------- 所有者正常
...

疑问

Docker为何会创建所有者为100998的db-data目录?该如何解决这个问题?


问题原因与解决方案

原因分析

  1. 100998用户ID的由来:这是Docker Desktop在Linux上启用的用户命名空间映射导致的。为提升安全性,Docker Desktop会将容器内的用户ID映射到主机上一个非特权的ID区间(通常从100998开始)。MySQL容器默认以mysql用户运行,其容器内UID为999,经过映射后,主机上显示的UID就变成了100998。

  2. 添加user:1000:1000启动失败的原因:MySQL镜像的初始化脚本需要对/var/lib/mysql目录拥有读写权限。指定user:1000:1000后,容器内进程以UID1000运行,但此时挂载目录在容器内的权限对应主机原映射的100998,容器内的1000用户无权限操作该目录,导致初始化失败。

解决方案

方法1:关闭Docker Desktop的用户命名空间映射(最简单)

  1. 打开Docker Desktop设置
  2. 进入Settings > Features in development
  3. 取消勾选Enable user namespace mapping选项
  4. 重启Docker Desktop
  5. 删除现有db-data目录,重新执行docker compose up

此方法会让容器内用户ID直接映射到主机对应ID,MySQL容器内的mysql用户(UID999)会在主机上显示为999;若需要目录属于alex(UID1000),可使用方法2。

方法2:自定义MySQL镜像,适配本地用户ID

  1. 创建Dockerfile.mysql文件:
FROM mysql:8

# 将mysql用户的UID和GID修改为1000(与主机alex用户一致)
RUN usermod -u 1000 mysql && groupmod -g 1000 mysql

# 确保数据目录权限正确
RUN chown -R mysql:mysql /var/lib/mysql
  1. 修改docker-compose.yaml中db服务的配置:
db:
  container_name: admin_db
  build:
    context: .
    dockerfile: Dockerfile.mysql
  ports:
    - 3306:3306
  volumes:
    - ./db-data:/var/lib/mysql
  environment:
    - MYSQL_ROOT_PASSWORD=root_password
    - MYSQL_PASSWORD=not_root_password
    - MYSQL_USER=admin_user
    - MYSQL_DATABASE=database_name
  networks:
    - app
  1. 删除现有db-data目录,执行docker compose build构建镜像,再执行docker compose up启动容器

此方法让容器内mysql用户的UID与主机alex用户一致,挂载目录所有者会是alex,同时MySQL进程可正常读写数据。

方法3:手动调整主机目录权限(临时方案)

  1. 停止容器:docker compose down
  2. 修改db-data目录权限:sudo chown -R 999:999 db-data
  3. 重新启动容器:docker compose up

此方法缺点是每次重新创建目录都需要手动调整权限,缺乏持久性。


内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:17:02