如何让 docker compose 初始化 SQL Server 数据库

问题描述 投票:0回答:4

我有一个 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 docker docker-compose
4个回答
34
投票

这里是一个带有 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

28
投票

经过大量谷歌搜索并结合四五个非常旧的教程后,我成功了。确保您使用 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!

0
投票

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!";
      '

备注:

  1. 如果您在与 SQL-Server (SSMS) 共存的计算机上运行,请停止这些服务。
  2. 添加“-C”作为参数“sqlcmd”以避免与证书相关的问题

-1
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.