Blazor WASM托管应用(.NET 6)结合SQL Server的Docker容器发布全流程求助
兄弟,我完全懂你作为Docker新手的迷茫——刚接触容器化的时候,光是搞清楚文件位置、依赖关联就够头疼的了。咱们一步一步来拆解你的问题,把这个Blazor WASM托管+SQL Server的容器化发布流程彻底捋明白。
一、先搞清楚Dockerfile的正确位置
你之前的疑问是“Dockerfile放Server文件夹还是主目录?”——答案是放在包含Server、Client、Shared三个子文件夹的项目根目录(就是你打开解决方案时的那个最外层文件夹)。
为什么?因为你的Dockerfile里需要复制三个项目的.csproj文件(Server、Client、Shared),如果把Dockerfile放在Server文件夹里,就没法方便地访问到Client和Shared的文件了。你现在看到Visual Studio生成的Dockerfile其实就是默认放在根目录的,只是你可能没注意到构建上下文的问题。
二、解决本地Docker Desktop运行失败的问题
你说VS里用Docker选项能跑,但直接在Docker Desktop里启动镜像不行?这很正常——因为VS在启动时帮你做了两件关键的事:
- 自动配置了容器网络,让你的Blazor后端容器能访问到本地的SQL Server(或者自动启动了一个SQL Server容器);
- 注入了正确的数据库连接字符串环境变量。
要在Docker Desktop里正常运行,咱们得用docker-compose来编排两个容器(Blazor后端 + SQL Server),确保它们在同一个网络里,并且配置好连接信息。
步骤1:在项目根目录创建docker-compose.yml文件
version: '3.9' services: blazor-server: build: . ports: - "80:80" - "443:443" environment: - ASPNETCORE_ENVIRONMENT=Production - ConnectionStrings__DefaultConnection=Server=sql-server;Database=RestaurantManagerDb;User=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=True; depends_on: - sql-server networks: - app-network sql-server: image: mcr.microsoft.com/mssql/server:2022-latest environment: - ACCEPT_EULA=Y - SA_PASSWORD=YourStrong!Passw0rd ports: - "1433:1433" volumes: - sql-data:/var/opt/mssql networks: - app-network volumes: sql-data: networks: app-network: driver: bridge
步骤2:修正你现有的Dockerfile(解决换行问题)
你提供的Dockerfile里有几行换行错误(比如RUN dotnet build那行没写完),修正后的版本如下:
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build ARG BUILD_CONFIGURATION=Release WORKDIR /src COPY ["Server/RestaurantManager.Server.csproj", "Server/"] COPY ["Client/RestaurantManager.Client.csproj", "Client/"] COPY ["Shared/RestaurantManager.Shared.csproj", "Shared/"] RUN dotnet restore "./Server/RestaurantManager.Server.csproj" COPY . . WORKDIR "/src/Server" RUN dotnet build "./RestaurantManager.Server.csproj" -c $BUILD_CONFIGURATION -o /app/build FROM build AS publish ARG BUILD_CONFIGURATION=Release RUN dotnet publish "./RestaurantManager.Server.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "RestaurantManager.Server.dll"]
步骤3:本地测试运行
在项目根目录打开终端,执行:
docker-compose up --build
这样Docker会自动构建Blazor后端镜像,启动SQL Server容器,并且让它们互通。等启动完成后,你就能通过http://localhost访问你的应用了。
三、处理EF Core迁移和数据初始化
要让你的应用自动创建数据库并执行迁移,有两种常用方式:
方式1:在应用启动时自动执行迁移
在Server项目的Program.cs里添加以下代码(在builder.Build()之后):
using Microsoft.EntityFrameworkCore; // ... 其他代码 ... var app = builder.Build(); // 添加迁移执行逻辑 using (var scope = app.Services.CreateScope()) { var dbContext = scope.ServiceProvider.GetRequiredService<YourDbContext>(); dbContext.Database.Migrate(); } // ... 后续的app.Run()等代码 ...
把YourDbContext换成你实际的DbContext类名,这样每次容器启动时,都会检查并执行未完成的迁移,非常适合新手。
方式2:在Dockerfile中添加迁移命令(可选)
如果你想在构建镜像时就执行迁移,可以在publish阶段之后添加:
# 在publish阶段之后,final阶段之前 FROM build AS migrate WORKDIR "/src/Server" RUN dotnet ef database update --configuration $BUILD_CONFIGURATION
不过这种方式需要在构建时能访问到SQL Server,所以更适合CI/CD流程,本地测试还是方式1更方便。
四、发布到公共容器注册表(比如Docker Hub)
容器注册表就是存放Docker镜像的地方,你可以理解成“Docker的GitHub”。以Docker Hub为例:
步骤1:准备镜像标签
首先构建生产环境镜像,给它打上Docker Hub的标签:
docker build -t your-dockerhub-username/restaurant-manager:v1 .
把your-dockerhub-username换成你自己的Docker Hub用户名,v1是版本号。
步骤2:登录Docker Hub
在终端执行:
docker login
输入你的Docker Hub用户名和密码。
步骤3:推送镜像到注册表
docker push your-dockerhub-username/restaurant-manager:v1
推送完成后,你的镜像就可以在任何能访问Docker Hub的服务器上拉取了。
五、部署到服务器并绑定域名
假设你有一台云服务器(比如AWS、阿里云、腾讯云),步骤如下:
步骤1:在服务器上安装Docker和Docker Compose
以Ubuntu为例:
# 安装Docker sudo apt update sudo apt install docker.io -y # 安装Docker Compose sudo apt install docker-compose -y
步骤2:拉取你的镜像并创建docker-compose.yml
在服务器上创建一个文件夹,比如/opt/restaurant-manager,然后创建docker-compose.yml(把本地的build: .改成镜像地址):
version: '3.9' services: blazor-server: image: your-dockerhub-username/restaurant-manager:v1 ports: - "80:80" - "443:443" environment: - ASPNETCORE_ENVIRONMENT=Production - ConnectionStrings__DefaultConnection=Server=sql-server;Database=RestaurantManagerDb;User=sa;Password=YourStrong!Passw0rd;TrustServerCertificate=True; depends_on: - sql-server networks: - app-network sql-server: image: mcr.microsoft.com/mssql/server:2022-latest environment: - ACCEPT_EULA=Y - SA_PASSWORD=YourStrong!Passw0rd ports: - "1433:1433" volumes: - sql-data:/var/opt/mssql networks: - app-network volumes: sql-data: networks: app-network: driver: bridge
步骤3:启动容器
sudo docker-compose up -d
-d表示后台运行。
步骤4:绑定域名和配置HTTPS
推荐用Nginx做反向代理,把域名指向你的Blazor容器:
- 安装Nginx:
sudo apt install nginx -y - 创建Nginx配置文件
/etc/nginx/sites-available/restaurant-manager:
server { listen 80; server_name your-domain.com; location / { proxy_pass http://localhost:80; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
- 启用配置:
sudo ln -s /etc/nginx/sites-available/restaurant-manager /etc/nginx/sites-enabled/ - 测试配置并重启Nginx:
sudo nginx -t && sudo systemctl restart nginx - 用Certbot申请免费HTTPS证书:
sudo apt install certbot python3-certbot-nginx -y,然后执行sudo certbot --nginx -d your-domain.com,跟着提示完成配置即可。
这样你的应用就可以通过https://your-domain.com访问了。
备注:内容来源于stack exchange,提问作者Muheeb

