'How to have docker compose init a SQL Server database
I have a docker compose file which creates a starts SQL Server. This is working fine. I can connect to the database and see the master database.
What I am trying to do is create a new database, add a table and some data to that table. I have been unable to find an example doing this using SQL SEever. All the example I have found are either using PostgreSQL or Mysql.
I have tried to adapt this example Docker Compose MySQL Multiple Database
I have created an init directory with a file called 01.sql and the only thing in it is
CREATE DATABASE `test`;
My docker-compose.yml looks like this
services:
db:
image: "mcr.microsoft.com/mssql/server"
ports:
- 1433:1433
volumes:
- ./init:/docker-entrypoint-initdb.d
environment:
SA_PASSWORD: "password123!"
ACCEPT_EULA: "Y"
When I run docker-compose up
I'm not seeing anything in the logs that implies its even trying to load this file. When I check the database I am not seeing any new database either.
I am at a lost to understand why this isn't working for SQL Server but the tutorial implies that it works for MySql. Is there a different command for SQL Server?
Solution 1:[1]
After quite a bit of Googleing and combining four or five very old tutorials I got this working. Ensuring that you are using Linux line endings is critical with these scripts.
Docker-compose.yml
version: '3'
services:
db:
build: ./Db
ports:
- 1433:1433
Db/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 to have to write them with 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/entrypoint.sh
# Run Microsoft SQl Server and initialization script (at the same time)
/usr/src/app/run-initialization.sh & /opt/mssql/bin/sqlservr
Db/run-initialization.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/create-database.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
Tip: If you change any of the scripts after running in the first time you need to do a docker-compose up --build
to ensure that the container is built again or it will just be using your old scripts.
Connect:
host: 127.0.0.1
Username : SA
Password: password123!
Solution 2:[2]
Docker images for mysql and postgres know about docker-entrypoint-initdb.d directory, and how to process it.
For example, for mysql, here is Dockerfile
It runs script 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"]
And docker-entrypoint.sh runs sql scripts from docker-entrypoint-initdb.d directory:
docker_process_init_files /docker-entrypoint-initdb.d/*
Looks like SQL Server docker image does not have processing for docker-entrypoint-initdb.d, you need to study SQL Server Dockerfile or documentation, probably there is some tools to init DB. If there not - you can create your own Docker image, basing on original:
Dockerfile:
FROM mcr.microsoft.com/mssql/server
# implement init db from docker-entrypoint-initdb.d
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |