本文主要描述如何让传统ASP.NET网站在Docker 中运行,侧重Docker image 搭建。 使用条件:
Docker for windows 用户切换到Windows 容器模式
Windows Server 2016 用户 开启 Windows Container
关于Docker for windows,nanoserver,Windows Container 一些概念区分
Docker for windows 在 win10 和 Windows Server 2016 上都能安装,但使用Docker for windows 开启Windows Container本质上都是在Hyper-v上运行。所以效率肯定没有原生的高,同时win10家庭版用户也跑不了Windows Container。
在Windows Server 2016上开启的Windows Container 是“原生”的,Windows Container与主机共享内核(博主未验证),用于企业生产环境
nanoserver是超简版Windows Server 2016,目前微软只允许它作为在容器中运行,由于是超简版,没有IIS,但是可以手工部署,好像也没有framework,自然也跑不了ASP.NET ,但是正是由于它的精简,特别适合作为ASP.NET Core的 windows 生产运行环境!详情 docs.microsoft.com
MSSQL Docker 1.1 Dockerfile方式 参考Github Microsoft/mssql-docker 以下内容microsoft/windowsservercore处与Github略有不同,仅供参考
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 FROM microsoft/windowsservercore:ltsc2016 LABEL maintainer "Perry Skountrianos" # Download Links: ENV sql_express_download_url "https://go.microsoft.com/fwlink/?linkid=829176" 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 / WORKDIR / RUN Invoke-WebRequest -Uri $env:sql_express_download_url -OutFile sqlexpress.exe ; \ Start-Process -Wait -FilePath .\sqlexpress.exe -ArgumentList /qs, /x:setup ; \ .\setup\setup.exe /q /ACTION=Install /INSTANCENAME=SQLEXPRESS /FEATURES=SQLEngine /UPDATEENABLED=0 /SQLSVCACCOUNT='NT AUTHORITY\System' /SQLSYSADMINACCOUNTS='BUILTIN\ADMINISTRATORS' /TCPENABLED=1 /NPENABLED=0 /IACCEPTSQLSERVERLICENSETERMS ; \ Remove-Item -Recurse -Force sqlexpress.exe, setup RUN stop-service MSSQL`$SQLEXPRESS ; \ set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql14.SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpdynamicports -value '' ; \ set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql14.SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpport -value 1433 ; \ set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql14.SQLEXPRESS\mssqlserver\' -name LoginMode -value 2 ; CMD .\start -sa_password $env:sa_password -ACCEPT_EULA $env:ACCEPT_EULA -attach_dbs \"$env:attach_dbs\" -Verbose
start.ps1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 # 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 MSSQL`$SQLEXPRESS if($sa_password -eq "_") { $secretPath = $env:sa_password_path if (Test-Path $secretPath) { $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 }
1 docker build -t yourname/mssql:2017-CU1 .
1.2 Docker pull方式 1 docker pull microsoft/mssql-server-windows-express:2017-CU1
2 生成Container SQLServer 密码规则 请点击 Password Policy 有关SQL Server 2016 Express Edition in Windows Containers 请点击 SQL Server 2016 Express Edition in Windows Containers 注意:虽然SQL Server是Express版本的,但连接实例名中没有”\SQLEXPRESS”
1 2 3 4 # 非必需 docker tag microsoft/mssql-server-windows-express:2017-CU1 microsoft/mssql:latest # 运行实例 docker run -d -p 1433:1433 --name mssql01 -e sa_password=Jsdfk237 -e ACCEPT_EULA=Y --restart=always microsoft/mssql
MySQL Docker (MySQL Container on Windows) 尚未实践,仅供参考
1 docker pull dnikolayev/sonarqube-mysql-windows
1.1 Dockerfile方式 参考 Github Microsoft/aspnet-docker
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # escape=` FROM microsoft/dotnet-framework:4.7.2-runtime-windowsservercore-ltsc2016 SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] RUN Add-WindowsFeature Web-Server; ` Add-WindowsFeature NET-Framework-45-ASPNET; ` Add-WindowsFeature Web-Asp-Net45; ` Remove-Item -Recurse C:\inetpub\wwwroot\*; ` Invoke-WebRequest -Uri https://dotnetbinaries.blob.core.windows.net/servicemonitor/2.0.1.3/ServiceMonitor.exe -OutFile C:\ServiceMonitor.exe #download Roslyn nupkg and ngen the compiler binaries RUN Invoke-WebRequest https://api.nuget.org/packages/microsoft.net.compilers.2.8.2.nupkg -OutFile c:\microsoft.net.compilers.2.8.2.zip ; ` Expand-Archive -Path c:\microsoft.net.compilers.2.8.2.zip -DestinationPath c:\RoslynCompilers ; ` Remove-Item c:\microsoft.net.compilers.2.8.2.zip -Force ; ` &C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe update ; ` &C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe update ; ` &C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe install c:\RoslynCompilers\tools\csc.exe /ExeConfig:c:\RoslynCompilers\tools\csc.exe | ` &C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe install c:\RoslynCompilers\tools\vbc.exe /ExeConfig:c:\RoslynCompilers\tools\vbc.exe | ` &C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ngen.exe install c:\RoslynCompilers\tools\VBCSCompiler.exe /ExeConfig:c:\RoslynCompilers\tools\VBCSCompiler.exe | ` &C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe install c:\RoslynCompilers\tools\csc.exe /ExeConfig:c:\RoslynCompilers\tools\csc.exe | ` &C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe install c:\RoslynCompilers\tools\vbc.exe /ExeConfig:c:\RoslynCompilers\tools\vbc.exe | ` &C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen.exe install c:\RoslynCompilers\tools\VBCSCompiler.exe /ExeConfig:c:\RoslynCompilers\tools\VBCSCompiler.exe ; ENV ROSLYN_COMPILER_LOCATION c:\\RoslynCompilers\\tools EXPOSE 80 ENTRYPOINT ["C:\\ServiceMonitor.exe", "w3svc"]
注意:2018/06/08 访问 https://api.nuget.org/packages/microsoft.net.compilers.2.8.2.nupkg 地址时 CDN 会转换成
https://nuget.cdn.azure.cn/packages/microsoft.net.compilers.2.8.2.nupkg 但这个网址并不存在此文件
1 docker build -t yourname/websitename:version .
1.2 Docker pull方式 1 docker pull microsoft/aspnet:4.7.2-windowsservercore-ltsc2016
2 更换Tag(非必需) 个人习惯 1 docker tag microsoft/aspnet:4.7.2-windowsservercore-ltsc2016 microsoft/aspnet:latest
有两种方式运行网站 直接使用ASPNET镜像运行网站 1 2 3 4 5 6 7 8 docker run ` -d ` --link mssql01 ` --name siteserver01 ` -v C:/Users/Administrator/Desktop/Web/SiteServer01:C:/inetpub/wwwroot ` -p 80:80 ` --restart=always ` microsoft/aspnet
将网站封装进容器 Dockerfile 其中”.”代表网站根目录
1 2 3 FROM microsoft/aspnet COPY . /inetpub/wwwroot EXPOSE 80
1 docker build -t yourname/website:version .
1 docker run --link mssql01 -d -p 80:80 --name website01 --restart=always yourname/website:version
容器互联(可选 除link的另外一种方式) 1 2 3 docker network create website01_network docker network connect website01_network website01 docker network connect website01_network mssql01
清理孤立的数据卷 1 docker volume ls -qf dangling=true
参考 将旧版整体式 .NET Framework 应用程序迁移到 Windows 容器
将 ASP.NET MVC 应用程序迁移到 Windows 容器