在Azure中国区为.NET Core App创建Linux的Web App
本文最早发布于个人的微信公众号内,现在迁移到博客园中。
Microsoft Azure在中国区运营已久,但其云产品和服务相较于国际区的还是有些区别(功能有阉割、有滞后)。
笔者在本次开发完ASP.NET Core的App后,想部署到中国区的Web App上,但在创建Web App资源时发现,在Azure中国区的门户上(Azure China Portal)无法创建Linux的Web App,只能是Windows,为此我特地到国际区做了比较确认,以下是截图:
-
Azure Global Portal,可以为.NET Core 3.1创建系统为Linux的Web App
-
Azure China Portal,截至发文时(2020/7/23),只能创建系统是Windows的Web App(而且目前即使选择其他Runtime stack,也无法选择Linux的Web App)
作为喜欢折腾的程序员,依然希望在中国区能有所突破,为此做了一点小尝试。
幸运的是找到了一个方案,也很简单:放弃在门户上手动创建资源,改为使用ARM template进行资源创建,以下是研究过程和操作步骤(在China East 2上测试成功,在China East上失败,无法创建此类资源):
-
从国际区的资源组中,导出包含Web App(Linux)的ARM template。
通过观察发现,在此template中,创建Service Plan(Service Farms)的JSON内有一个"kind"对象,其值为"linux",如下图:
创建Web App(Sites)的JSON内也有一个"kind"对象,其值为"app,linux",如下图:
-
据此推测,在中国区使用该ARM template进行资源创建,也应该可行。所以,对这个ARM template略加修改(修改location为China East2),并在Azure中国区进行了部署,具体步骤如下:
-
在Azure China Portal上创建一个资源组
-
在资源组内点击"+",添加一个资源
-
在Marketplace中搜索template,并选择"Template deployment",如下图:
-
点击"Build your own template in the editor"
-
将ARM template的内容复制到编辑框中,检查一下确保没有错误(特别注意location,目前在China East2上测试成功)并保存。
-
保存后,自动跳转回上页,勾选同意协议,并点击"Purchase"
-
之后就开始进入部署阶段,等待片刻后,就可以在资源组内看到创建好的云资源,Service Plan带有企鹅图标,是一个Linux的系统,如下图:
-
查看Web App,可以看到,这就是一个服务于.NET Core 3.1的App
-
在向该Web App部署.NET Core的代码前,还需要做额外设置,打开该App的Configuration-->Application settings,新增一个配置,WEBSITE_WEBDEPLOY_USE_SCM: false,如下图:
如果没有进行上述配置,则无法通过Visual Studio手动发布
-
保存配置后,就可以通过下载publish profile,并使用Visual Studio向该Web App部署.NET Core App,如下图:
在Portal上下载publish profile:
在Visual Studio中导入publish profile,点击Publish进行部署
部署成功
成功打开页面
-
最后,附上本次部署时所用的ARM template供各位参考,有兴趣的朋友也可以到China North或China North2上进行尝试(China East无法使用该方案)。
{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "site_name": { "defaultValue": "coreapponlinux_china_webapp", "type": "String" }, "serverfarms_name": { "defaultValue": "coreapponlinux_china_serviceplan", "type": "String" }, "region": { "defaultValue": "China East2", "type": "String" } }, "variables": {}, "resources": [ { "type": "Microsoft.Web/serverfarms", "apiVersion": "2018-02-01", "name": "[parameters('serverfarms_name')]", "location": "[parameters('region')]", "sku": { "name": "B1", "tier": "Basic", "size": "B1", "family": "B", "capacity": 1 }, "kind": "linux", "properties": { "perSiteScaling": false, "maximumElasticWorkerCount": 1, "isSpot": false, "freeOfferExpirationTime": "2020-08-21T08:26:43.8033333", "reserved": true, "isXenon": false, "hyperV": false, "targetWorkerCount": 0, "targetWorkerSizeId": 0 } }, { "type": "Microsoft.Web/sites", "apiVersion": "2018-11-01", "name": "[parameters('site_name')]", "location": "[parameters('region')]", "dependsOn": [ "[resourceId('Microsoft.Web/serverfarms', parameters('serverfarms_name'))]" ], "kind": "app,linux", "properties": { "enabled": true, "hostNameSslStates": [ { "name": "[concat(parameters('site_name'), '.azurewebsites.net')]", "sslState": "Disabled", "hostType": "Standard" }, { "name": "[concat(parameters('site_name'), '.scm.azurewebsites.net')]", "sslState": "Disabled", "hostType": "Repository" } ], "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('serverfarms_name'))]", "reserved": true, "isXenon": false, "hyperV": false, "siteConfig": {}, "scmSiteAlsoStopped": false, "clientAffinityEnabled": false, "clientCertEnabled": false, "hostNamesDisabled": false, "containerSize": 0, "dailyMemoryTimeQuota": 0, "httpsOnly": false, "redundancyMode": "None" } }, { "type": "Microsoft.Web/sites/config", "apiVersion": "2018-11-01", "name": "[concat(parameters('site_name'), '/web')]", "location": "[parameters('region')]", "dependsOn": [ "[resourceId('Microsoft.Web/sites', parameters('site_name'))]" ], "properties": { "numberOfWorkers": 1, "defaultDocuments": [ "Default.htm", "Default.html", "Default.asp", "index.htm", "index.html", "iisstart.htm", "default.aspx", "index.php", "hostingstart.html" ], "netFrameworkVersion": "v4.0", "linuxFxVersion": "DOTNETCORE|3.1", "requestTracingEnabled": false, "remoteDebuggingEnabled": false, "httpLoggingEnabled": false, "logsDirectorySizeLimit": 35, "detailedErrorLoggingEnabled": false, "publishingUsername": "$coreapponlinux", "azureStorageAccounts": {}, "scmType": "None", "use32BitWorkerProcess": true, "webSocketsEnabled": false, "alwaysOn": false, "managedPipelineMode": "Integrated", "virtualApplications": [ { "virtualPath": "/", "physicalPath": "site\\wwwroot", "preloadEnabled": false } ], "loadBalancing": "LeastRequests", "experiments": { "rampUpRules": [] }, "autoHealEnabled": false, "localMySqlEnabled": false, "ipSecurityRestrictions": [ { "ipAddress": "Any", "action": "Allow", "priority": 1, "name": "Allow all", "description": "Allow all access" } ], "scmIpSecurityRestrictions": [ { "ipAddress": "Any", "action": "Allow", "priority": 1, "name": "Allow all", "description": "Allow all access" } ], "scmIpSecurityRestrictionsUseMain": false, "http20Enabled": false, "minTlsVersion": "1.2", "ftpsState": "AllAllowed", "reservedInstanceCount": 0 } } ] }
本文也算抛砖引玉,如果各位大牛有更好的方案,也请指教。当然,等以后Linux Web App在中国区上线后,也就不用这么折腾了。
浙公网安备 33010602011771号