Windows 10上のWindows 18.03のDockerを実行します。私はMicrosoft/mssql-server-windows-express(Windows Serverから)のイメージをdocker compose fileから自分のVS 2017プロジェクトで使用しています。ここで達成しようとしているのは、スクリプトからデータベースを初期化することです。 docker.compose.ymlで「コマンド」スイッチを使用してみましたが、あまり成功しませんでした...
これがdocker composeファイルです:
myscustomservice:
image: myscustomservice
build:
context: .\myscustomservice
dockerfile: Dockerfile
db:
image: Microsoft/mssql-server-windows-express
volumes:
- ".\\data:C:\\data"
#command: --init-file C:\\data\\CreateLocalDB.sql
#command: "sqlcmd -U sa -P sUper45!pas5Word -i C:\\data\\CreateLocalDB.sql"
restart: always
ports:
- "1533:1433"
environment:
- "sa_password=sUper45!pas5Word"
- "ACCEPT_EULA=Y"
volumes:
db-data:
コメントされている2つのコマンドラインを試したことに注意してください。 1つ目はファイルが見つからないと言って失敗し、2つ目は通常のコマンドラインをそのコマンドラインに置き換えるだけなので、コンテナは起動しません(または起動しません)。
私のローカルドライブには、CreateLocalDB.sqlファイルを含むC:\ myscustomservice\dataドライブがあります。 C:\ dataフォルダーのコンテナーにマウントされています(コンテナー内でPowerShellを実行すると表示されます)。
Sqlファイルは次のようになります。
USE MASTER
CREATE DATABASE [customDB_test]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'customDB_test', FILENAME = N'C:\data\customDB_test.mdf' , SIZE = 1594752KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'customDB_test_log', FILENAME = N'C:\data\customDB_test.ldf' , SIZE = 3584KB , MAXSIZE = 2048GB , FILEGROWTH = 10240KB )
GO
誰がどのようにこれを行うことができますか?ネット上のすべての例はLinuxコンテナーからのものであり、このイメージはWindows Serverコンテナーからのものです。
わかりましたが、データベースの存在を確認するPowerShellスクリプトを呼び出すには、 "db"に依存する別のサービスを作成する必要がありました。存在しない場合は、mssqlスクリプトを呼び出して作成します。
これがdockerfileです:
FROM Microsoft/wcf:4.7.1
ARG source
# Creates a directory for custom application
RUN mkdir C:\MyCustomService
COPY . c:\\MyCustomService
# Remove existing default web site
RUN powershell -NoProfile -Command \
Import-module WebAdministration; \
Remove-WebSite -Name "'Default Web Site'"
# Configure the new site in IIS. Binds it to port 80 otherwise it won't work because it needs a default app listening on this port
RUN powershell -NoProfile -Command \
Import-module IISAdministration; \
New-IISSite -Name "MyCustomService" -PhysicalPath C:\MyCustomService -BindingInformation "*:80:";
# Add net.tcp support on the new site and change it to web aplication.
RUN Import-Module WebAdministration; Set-ItemProperty "IIS:\\Sites\\MyCustomService" -name bindings -value (@{protocol='net.tcp';bindingInformation='808:*'},@{protocol='http';bindingInformation='*:80:'});
RUN windows\system32\inetsrv\appcmd.exe set app 'MyCustomService/' /enabledProtocols:"http,net.tcp"
# This instruction tells the container to listen on port 83.
EXPOSE 80
EXPOSE 808
これが新しいdocker-composeファイルです。
myscustomservice:
image: myscustomservice
build:
context: .\myscustomservice
dockerfile: Dockerfile
ports:
- "83:80"
- "1010:808"
depends_on:
- db
- db-init
db:
image: Microsoft/mssql-server-windows-express
volumes:
- ".\\data:C:\\data"
ports:
- "1533:1433"
environment:
- "sa_password=sUper45!pas5Word"
- "ACCEPT_EULA=Y"
- 'attach_dbs=[{"dbName":"customDB_test","dbFiles":["C:\\data\\customDB_test.mdf","C:\\data\\customDB_test.ldf"]}]'
volumes:
db-data:
db-init:
image: Microsoft/mssql-server-windows-express
volumes:
- ".\\data:C:\\data"
command: powershell -executionpolicy bypass "C:\\data\\initialize_db.ps1 -insertTestData"
environment:
- "sa_password=sUper45!pas5Word"
- "ACCEPT_EULA=Y"
depends_on:
- db
Dbサービスの「attach_dbs」環境変数に注意してください。この方法では、既存のファイルにバインドしようとするため、db_initサービスによって実行されるスクリプトはデータベースを検出し、再作成しません。
PowerShellスクリプト "initialize_db.ps1":
param([switch]$insertTestData)
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null
$server = New-Object ("Microsoft.SqlServer.Management.Smo.Server") "db\SQLEXPRESS"
$database = "customDB_test"
$dbs = $server.Databases
$exists = $false
#This sets the connection to mixed-mode authentication
$server.ConnectionContext.LoginSecure=$false;
#This sets the login name
$server.ConnectionContext.set_Login("sa");
#This sets the password
$server.ConnectionContext.set_Password("sUper45!pas5Word")
try
{
foreach ($db in $dbs)
{
Write-Host $db.Name
if($db.Name -eq $database)
{
Write-Host "Database already exist"
$exists = $true
}
}
}
catch
{
Write-Error "Failed to connect to $server"
}
if(-not $exists)
{
Write-Host "Database doesn't exist"
$StopWatch = [System.Diagnostics.Stopwatch]::StartNew()
sqlcmd -S 'db' -U sa -P 'sUper45!pas5Word' -i 'C:\\data\\CreateLocalDB_schema.sql'
Write-Host "Database created"
$StopWatch.Elapsed
if($insertTestData)
{
Write-Host "Begining data insertion..."
sqlcmd -S 'db' -U sa -P 'sUper45!pas5Word' -i 'C:\\data\\CreateLocalDB_data.sql'
Write-Host "Data inserted"
$StopWatch.Elapsed
}
$StopWatch.Stop()
}
sqlcmd -S 'db' -U sa -P 'sUper45!pas5Word' -i 'C:\\data\\CreateLocalDB_user.sql'
このスクリプトは、少なくとも1つから3つまでのSQLスクリプトを実行します。
サービスのdockerfileはhttpのポート80とnet.tcpのポート808を公開し、 "myscustomservice"のweb.configファイルは次のようにwcfサービスを公開します。
<Host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:1010/myscustomservice/Customer.svc"/>
</baseAddresses>
</Host>