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

DaI*_*mTo 13 sql-server docker docker-compose

我有一个 docker-compose 文件,用于创建启动 SQL Server。这工作正常。我可以连接到数据库并查看主数据库。

我想做的是创建一个新数据库,并向该表添加一个表和一些数据。我一直无法找到使用 SQL Server 执行此操作的示例。我见过的所有例子要么使用 PostgreSQL,要么使用 Mysql。

我尝试改编这个示例Docker Compose MySQL Multiple Database

我创建了一个 init 目录,其中包含一个名为 01.sql 的文件,其中唯一的内容是

CREATE DATABASE `test`;
Run Code Online (Sandbox Code Playgroud)

我的 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"
Run Code Online (Sandbox Code Playgroud)

当我运行 docker-compose up 时

我在日志中没有看到任何暗示它甚至试图加载此文件的内容。当我检查数据库时,我也没有看到任何新数据库。

我不明白为什么这不适用于 SQL Server,但教程暗示它适用于 MySql。SQL Server 有不同的命令吗?

DaI*_*mTo 23

经过相当多的谷歌搜索并结合四五个非常旧的教程后,我得到了这个工作。确保使用 Linux 行结尾对于这些脚本至关重要。

Docker-compose.yml

version: '3'

services:
  db:
    build: ./Db
    ports:
        - 1433:1433
Run Code Online (Sandbox Code Playgroud)

数据库/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
Run Code Online (Sandbox Code Playgroud)

数据库/入口点.sh

# Run Microsoft SQl Server and initialization script (at the same time)
/usr/src/app/run-initialization.sh & /opt/mssql/bin/sqlservr
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

提示:如果您在第一次运行后更改任何脚本,则需要执行以下操作docker-compose up --build以确保再次构建容器,否则它将仅使用旧脚本。

连接:

host:  127.0.0.1
Username: SA
Password:  password123!
Run Code Online (Sandbox Code Playgroud)


小智 15

这是一个带有 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!";
      '
Run Code Online (Sandbox Code Playgroud)

此撰写文件要求您将 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
Run Code Online (Sandbox Code Playgroud)