Linux Mint Cinnamon 22下Docker部署SQL Server无法自定义目录建库
环境背景
- 采用Docker运行Microsoft SQL Server(Linux环境)
- 主要使用Dbeaver工具学习操作,曾尝试Azure Data Studio但偏好前者
- 使用Microsoft SQL Server驱动
错误信息
执行建库语句时触发权限报错:
SQL Error [5123] [S0001]: CREATE FILE encountered operating system error 5(Access is denied.) while attempting to open or create the physical file '/home/blank/Documentos/Cursos/SQL MaxiPrograma/Unidad 3 - Construccion Dbs/MundoPokemon2.mdf'.
执行的SQL语句
USE MASTER; GO CREATE database MundoPokemon2 ON( NAME='MundoPokemon2-data', FILENAME='/home/blank/Documentos/Cursos/SQL MaxiPrograma/Unidad 3 - Construccion Dbs/MundoPokemon2.mdf', SIZE=10mb, MAXSIZE=500mb, FILEGROWTH=10mb ) LOG ON( NAME='MundoPokemon2-log', FILENAME='/home/blank/Documentos/Cursos/SQL MaxiPrograma/Unidad 3 - Construccion Dbs/MundoPokemon2.ldf', SIZE=10mb, MAXSIZE=500mb, FILEGROWTH=10mb )
已尝试的无效操作
- 创建组并为目标目录分配wrx权限
- 将目录设为共享资源,勾选允许其他用户创建/删除文件
- 将目录所有者改为
mssql用户
额外疑问
Azure Data Studio显示数据库文件路径为admin:///var/opt/mssql/data,但该目录实际为空,不清楚原因。
核心原因:Docker容器权限映射不匹配
直接修改宿主机目录权限无效,因为SQL Server进程在容器内部运行,容器内的mssql用户UID/GID和宿主机的mssql用户不对应,导致容器进程无法访问宿主机路径。
正确操作步骤
宿主机创建目标目录(若未创建):
mkdir -p /home/blank/Documentos/Cursos/SQL MaxiPrograma/Unidad 3 - Construccion Dbs匹配容器内用户的UID/GID
Docker中SQL Server默认以UID=10001、GID=10001的用户运行,需将宿主机目录权限改为对应ID:chown 10001:10001 /home/blank/Documentos/Cursos/SQL MaxiPrograma/Unidad 3 - Construccion Dbs测试阶段可临时开放全局读写权限(不推荐生产环境):
chmod 777 /home/blank/Documentos/Cursos/SQL MaxiPrograma/Unidad 3 - Construccion Dbs启动容器时挂载宿主机目录
必须通过-v参数将宿主机目录映射到容器内部,否则SQL Server无法识别宿主机路径。示例启动命令:docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=你的数据库密码" \ -v /home/blank/Documentos/Cursos/SQL MaxiPrograma/Unidad 3 - Construccion Dbs:/container-db-folder \ -p 1433:1433 --name sqlserver -d mcr.microsoft.com/mssql/server:latest注意:SQL语句中的
FILENAME需改为容器内部的路径,即/container-db-folder/MundoPokemon2.mdf和/container-db-folder/MundoPokemon2.ldf。关于Azure Data Studio显示的路径
admin:///var/opt/mssql/data是容器内部的默认数据库存储路径,宿主机无法直接查看该目录内容,除非你将容器的这个目录挂载到宿主机。若未挂载,容器重启后数据会丢失,建议挂载默认目录或自定义目录。
简化方案:使用容器内部默认路径
如果不想折腾挂载配置,直接将SQL语句中的FILENAME改为容器默认路径:
FILENAME='/var/opt/mssql/data/MundoPokemon2.mdf'
FILENAME='/var/opt/mssql/data/MundoPokemon2.ldf'
SQL Server默认拥有该目录的写入权限,无需额外配置。
内容的提问来源于stack exchange,提问作者EzequieLakodey

