Microsoft have removed support for ‘Windows’ based images of MS SQL server. Opting only to support Linux versions. Because of this we need to manually create our own MSSQL Server Base Image. The Dockerfile below can be used to create this image.
Credit to Perry and Elton here: https://github.com/microsoft/mssql-docker/blob/master/windows/mssql-server-windows-developer/start.ps1
Dockerfile
# SQL Server 2019 Windows container dockerfile
## Warning: Restarting windows container causes the machine key to change and hence if you have any encryption configured then restarting SQL On Windows containers
## breaks the encryption key chain in SQL Server.
# Download the SQL Developer from the following location https://go.microsoft.com/fwlink/?linkid=866662 and extract the .box and .exe files using the option: "Download Media"
FROM mcr.microsoft.com/windows/servercore:ltsc2019
ENV sa_password="_" \
attach_dbs="[]" \
ACCEPT_EULA="_" \
sa_password_path="C:\ProgramData\Docker\secrets\sa-password"
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
# make install files accessible
COPY start.ps1 /
COPY SQLServer2019-DEV-x64-ENU.box /
COPY SQLServer2019-DEV-x64-ENU.exe /
WORKDIR /
RUN Start-Process -Wait -FilePath .\SQLServer2019-DEV-x64-ENU.exe -ArgumentList /qs, /x:setup ; \
.\setup\setup.exe /q /ACTION=Install /INSTANCENAME=MSSQLSERVER /FEATURES=SQLEngine /UPDATEENABLED=0 /SQLSVCACCOUNT='NT AUTHORITY\NETWORK SERVICE' /SQLSYSADMINACCOUNTS='BUILTIN\ADMINISTRATORS' /TCPENABLED=1 /NPENABLED=0 /IACCEPTSQLSERVERLICENSETERMS ; \
Remove-Item -Recurse -Force SQLServer2019-DEV-x64-ENU.exe, SQLServer2019-DEV-x64-ENU.box, setup
RUN stop-service MSSQLSERVER ; \
set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.MSSQLSERVER\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpdynamicports -value '' ; \
set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.MSSQLSERVER\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpport -value 1433 ; \
set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.MSSQLSERVER\mssqlserver\' -name LoginMode -value 2 ;
HEALTHCHECK CMD [ "sqlcmd", "-Q", "select 1" ]
CMD .\start -sa_password $env:sa_password -ACCEPT_EULA $env:ACCEPT_EULA -attach_dbs \"$env:attach_dbs\" -Verbose
Save the above as a file called “Dockerfile“ in a directory, then create a second file called start.ps1 and copy in the following content:
# The script sets the sa password and start the SQL Service
# Also it attaches additional database from the disk
# The format for attach_dbs
param(
[Parameter(Mandatory=$false)]
[string]$sa_password,
[Parameter(Mandatory=$false)]
[string]$ACCEPT_EULA,
[Parameter(Mandatory=$false)]
[string]$attach_dbs
)
if($ACCEPT_EULA -ne "Y" -And $ACCEPT_EULA -ne "y")
{
Write-Verbose "ERROR: You must accept the End User License Agreement before this container can start."
Write-Verbose "Set the environment variable ACCEPT_EULA to 'Y' if you accept the agreement."
exit 1
}
# start the service
Write-Verbose "Starting SQL Server"
start-service MSSQLSERVER
if($sa_password -eq "_") {
if (Test-Path $env:sa_password_path) {
$sa_password = Get-Content -Raw $secretPath
}
else {
Write-Verbose "WARN: Using default SA password, secret file not found at: $secretPath"
}
}
if($sa_password -ne "_")
{
Write-Verbose "Changing SA login credentials"
$sqlcmd = "ALTER LOGIN sa with password=" +"'" + $sa_password + "'" + ";ALTER LOGIN sa ENABLE;"
& sqlcmd -Q $sqlcmd
}
$attach_dbs_cleaned = $attach_dbs.TrimStart('\\').TrimEnd('\\')
$dbs = $attach_dbs_cleaned | ConvertFrom-Json
if ($null -ne $dbs -And $dbs.Length -gt 0)
{
Write-Verbose "Attaching $($dbs.Length) database(s)"
Foreach($db in $dbs)
{
$files = @();
Foreach($file in $db.dbFiles)
{
$files += "(FILENAME = N'$($file)')";
}
$files = $files -join ","
$sqlcmd = "IF EXISTS (SELECT 1 FROM SYS.DATABASES WHERE NAME = '" + $($db.dbName) + "') BEGIN EXEC sp_detach_db [$($db.dbName)] END;CREATE DATABASE [$($db.dbName)] ON $($files) FOR ATTACH;"
Write-Verbose "Invoke-Sqlcmd -Query $($sqlcmd)"
& sqlcmd -Q $sqlcmd
}
}
Write-Verbose "Started SQL Server."
$lastCheck = (Get-Date).AddSeconds(-2)
while ($true)
{
Get-EventLog -LogName Application -Source "MSSQL*" -After $lastCheck | Select-Object TimeGenerated, EntryType, Message
$lastCheck = Get-Date
Start-Sleep -Seconds 2
}
Finally download the required media files from https://go.microsoft.com/fwlink/?linkid=866662 and extract the .box and .exe files using the option: "Download Media".
To create the image, navigate to that directory and run the command:
docker build -t deanobrien/sql2019:empty .
Where 'deanobrien' is the name of the repository where we will store the resulting image.
To push the image to the registry, you need to:
- login to azure
- Set subscription
- Login to Azure container registry (ACR)
- Push to registry
az login
az account set --subscription xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx
az acr login
docker push deanobrien/sql2019:empty
/