我有一个 docker-compose 文件,用于创建启动 SQL Server。这工作正常。我可以连接到数据库并查看主数据库。
我想做的是创建一个新数据库,并向该表添加一个表和一些数据。 我一直无法找到使用 SQL Server 执行此操作的示例。我见过的所有示例都是使用 PostgreSQL 或 Mysql。
我尝试改编这个示例Docker Compose MySQL Multiple Database
我创建了一个 init 目录,其中包含一个名为 01.sql 的文件,其中唯一的内容是
CREATE DATABASE `test`;
我的 docker-compose.yml 看起来像这样
services:
db:
image: "mcr.microsoft.com/mssql/server"
ports:
- 1433:1433
volumes:
- ./init:/docker-entrypoint-initdb.d
environment:
SA_PASSWORD: "password123!"
ACCEPT_EULA: "Y"
当我运行 docker-compose up 时
我在日志中没有看到任何表明它甚至试图加载此文件的内容。 当我检查数据库时,我也没有看到任何新数据库。
我不明白为什么这不适用于 SQL Server,但教程暗示它适用于 MySql。 SQL Server 有不同的命令吗?
这里是一个带有 SQL Server Microsoft 映像(没有构建)的 docker-compose.yml 示例,它不依赖于延迟(我不确定这是否是等待 SQL Server 实例启动的可靠方法)。
此方法使用额外的安装容器,一旦主 SQL Server 容器初始化,该容器就会执行初始化 SQL 脚本。
我使用了相同的
mcr.microsoft.com/mssql/server:2019-latest
图像,因为它包含 SQL Server 工具,但您可以随意使用其中安装了 SQL Server 工具的任何您喜欢的图像。
version: '3.8'
volumes:
sqlserver_data:
services:
sqlserver:
image: mcr.microsoft.com/mssql/server:2019-latest
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=${Sa_Password:-password123}
- MSSQL_PID=Developer
ports:
- 1433:1433
volumes:
- sqlserver_data:/var/opt/mssql
restart: always
healthcheck:
test: ["CMD-SHELL", "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P ${Sa_Password:-password123} -Q 'SELECT 1' || exit 1"]
interval: 10s
retries: 10
start_period: 10s
timeout: 3s
sqlserver.configurator:
image: mcr.microsoft.com/mssql/server:2019-latest
volumes:
- ./init:/docker-entrypoint-initdb.d
depends_on:
sqlserver:
condition: service_healthy
command: >
bash -c '
/opt/mssql-tools/bin/sqlcmd -S sqlserver -U sa -P ${Sa_Password:-password123} -d master -i docker-entrypoint-initdb.d/init.sql;
echo "All done!";
'
此撰写文件需要您将 init.sql 文件添加到 init 子文件夹中。这是创建新用户的示例:
USE [master];
GO
IF NOT EXISTS (SELECT * FROM sys.sql_logins WHERE name = 'newuser')
BEGIN
CREATE LOGIN [newuser] WITH PASSWORD = 'password123', CHECK_POLICY = OFF;
ALTER SERVER ROLE [sysadmin] ADD MEMBER [newuser];
END
GO
经过大量谷歌搜索并结合四五个非常旧的教程后,我成功了。确保您使用 Linux 行结尾对于这些脚本至关重要。
Docker-compose.yml
version: '3'
services:
db:
build: ./Db
ports:
- 1433:1433
数据库/DockerFile
# Choose ubuntu version
FROM mcr.microsoft.com/mssql/server:2019-CU13-ubuntu-20.04
# Create app directory
WORKDIR /usr/src/app
# Copy initialization scripts
COPY . /usr/src/app
# Set environment variables, not have to write them with the docker run command
# Note: make sure that your password matches what is in the run-initialization script
ENV SA_PASSWORD password123!
ENV ACCEPT_EULA Y
ENV MSSQL_PID Express
# Expose port 1433 in case accessing from other container
# Expose port externally from docker-compose.yml
EXPOSE 1433
# Run Microsoft SQL Server and initialization script (at the same time)
CMD /bin/bash ./entrypoint.sh
Db/入口点.sh
# Run Microsoft SQl Server and initialization script (at the same time)
/usr/src/app/run-initialization.sh & /opt/mssql/bin/sqlservr
Db/运行初始化.sh
# Wait to be sure that SQL Server came up
sleep 90s
# Run the setup script to create the DB and the schema in the DB
# Note: make sure that your password matches what is in the Dockerfile
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P password123! -d master -i create-database.sql
Db/创建数据库.sql
CREATE DATABASE [product-db]
GO
USE [product-db];
GO
CREATE TABLE product (
Id INT NOT NULL IDENTITY,
Name TEXT NOT NULL,
Description TEXT NOT NULL,
PRIMARY KEY (Id)
);
GO
INSERT INTO [product] (Name, Description)
VALUES
('T-Shirt Blue', 'Its blue'),
('T-Shirt Black', 'Its black');
GO
提示:如果您在第一次运行后更改任何脚本,您需要执行
docker-compose up --build
以确保再次构建容器,否则它将仅使用您的旧脚本。
连接:
host: 127.0.0.1
Username: SA
Password: password123!
在answer之后,我遇到了一些与访问和环境变量相关的问题,纠正了这些问题并分享了以下 docker-compose.yml 的工作版本
volumes:
sqlserver_data1:
services:
sqlserver:
image: mcr.microsoft.com/mssql/server:2022-latest
environment:
- ACCEPT_EULA=Y
- MSSQL_SA_PASSWORD=1StrongPwd!!
- MSSQL_PID=Developer
user: root
ports:
- 1433:1433
volumes:
- sqlserver_data1:/var/opt/mssql
restart: always
healthcheck:
test: ["CMD-SHELL", "/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P 1StrongPwd!! -C -Q 'SELECT 1' || exit 1"]
interval: 10s
retries: 10
start_period: 10s
timeout: 3s
sqlserver.configurator:
image: mcr.microsoft.com/mssql/server:2022-latest
user: root
volumes:
- ./init:/docker-entrypoint-initdb.d
depends_on:
sqlserver:
condition: service_healthy
command: >
bash -c '
/opt/mssql-tools18/bin/sqlcmd -S sqlserver -U sa -P 1StrongPwd!! -C -d master -i docker-entrypoint-initdb.d/init.sql;
echo "All done!";
'
备注:
mysql 和 postgres 的 Docker 镜像了解 docker-entrypoint-initdb.d 目录,以及如何处理它。
例如,对于mysql,这里是Dockerfile
它运行脚本 docker-entrypoint.sh:
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]
并且 docker-entrypoint.sh 从 docker-entrypoint-initdb.d 目录运行 sql 脚本:
docker_process_init_files /docker-entrypoint-initdb.d/*
看起来SQL Server docker镜像没有对docker-entrypoint-initdb.d进行处理,你需要研究SQL Server Dockerfile或文档,可能有一些工具来初始化DB。如果没有 - 您可以基于原始镜像创建自己的 Docker 镜像:
Dockerfile:
FROM mcr.microsoft.com/mssql/server
# implement init db from docker-entrypoint-initdb.d