☰
Orchard Core 实战:使用 Docker 与 Docker Compose 构建、运行与部署
2026/10/7 2:24:12 网站建设 项目流程
  • CMS
  • 后端
  • Web框架

【免费下载链接】OrchardCore

Orchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.

项目地址:https://gitcode.com/gh_mirrors/or/OrchardCore
点击查看免费下载

导读

本文基于 Orchard Core 官方仓库中的 src/docs/topics/docker/README.md 编写,系统讲解如何利用仓库自带的Dockerfile、.dockerignore与docker-compose.yml快速构建 Orchard Core 的 Docker 镜像与容器,覆盖本地测试 PR、验证多数据库环境、清理构建中间镜像、多平台镜像构建与 BuildKit 高级用法。阅读完本文,你将能够从命令行独立完成 Orchard Core 的容器化构建、运行、编排与生产化部署前的环境验证。

为什么用 Docker 跑 Orchard Core

Orchard Core 是一个基于 ASP.NET Core 的开源模块化、多租户应用框架,其源代码仓库根目录内置了Dockerfile,允许开发者从源码直接构建属于自己的 Docker 镜像与容器。这对 Orchard Core 开发者尤其有用:

  • 快速验证 PR:将任意分支的源码打包成镜像,在本地一键拉起测试环境,不必手工安装 .NET SDK 与数据库;
  • 跨环境验证:镜像针对特定操作系统构建,可以观察 Orchard Core 在不同基础镜像(Linux / Windows)下的运行表现;
  • 生产部署铺垫:虽然本文以本地测试为主要场景,但同一套 Dockerfile 与镜像机制同样可迁移到生产服务器;
  • 数据库全家桶测试:配合 Docker Compose 可同时启动 SQL Server、MySQL、PostgreSQL 等 Orchard Core 官方支持的数据库服务。

对于使用 NuGet 包解决方案的开发者,也可以直接把源码中的Dockerfile与.dockerignore复制到解决方案根目录,完成类似操作;不过如果你的目录结构与源码仓库不一致,可能需要自行调整 COPY 路径。

准备工作

在开始之前,需要先在本机安装 Docker 环境:

  • Windows 用户:推荐通过 WSL(Windows Subsystem for Linux)运行容器,参考微软官方 WSL 容器教程(docs.microsoft.com 上的 "WSL Containers" 教程);
  • Ubuntu / Linux 用户:参考 Docker 官方 Engine 安装文档(docs.docker.com/engine/install/ubuntu)完成安装。

安装完成后,用docker --version确认命令行可用,再进入 Orchard Core 源码根目录(即Dockerfile所在目录)执行后续命令。

仓库根目录的 Docker 文件全景

Orchard Core 仓库根目录下提供了 4 个与容器构建相关的文件,它们协同完成“从源码到镜像”的流水线:

文件作用
Dockerfile多阶段构建:先用 .NET SDK 中间镜像发布站点,再生成仅含 ASP.NET Core 运行时的最终镜像
.dockerignore控制构建上下文,排除App_Data、bin、obj等不必要文件
Dockerfile-CI面向 GitHub Actions 持续集成的专用 Dockerfile,直接从预编译产物构建
Dockerfile-CI.dockerignoreCI 专用的 dockerignore,只保留.build/release预编译目录

其中Dockerfile与.dockerignore面向开发者本地使用;Dockerfile-CI与Dockerfile-CI.dockerignore面向仓库的 CI 流水线(见下文“CI 专用 Dockerfile”一节)。

深入理解 Dockerfile:多阶段构建

仓库当前实际使用的 Dockerfile

打开仓库根目录的 Dockerfile,当前实现如下:

# TARGETARCH and TARGETOS are set automatically when --platform is provided. FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:10.0 AS build-env ARG TARGETOS LABEL stage=build-env WORKDIR /source # copy required files for building # .dockerignore excludes App_Data and binaries from these COPY ./src ./src COPY Directory.Build.props . COPY Directory.Packages.props . # build, results are placed in /app RUN dotnet publish src/OrchardCore.Cms.Web/OrchardCore.Cms.Web.csproj -c Release -o /app --framework net10.0 /p:RunAnalyzers=false # build runtime image FROM mcr.microsoft.com/dotnet/aspnet:10.0-nanoserver-ltsc2025 AS build_windows FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS build_linux FROM build_${TARGETOS} AS aspnet EXPOSE 80 ENV ASPNETCORE_URLS=http://+:80 WORKDIR /app COPY --from=build-env /app/ . ENTRYPOINT ["dotnet", "OrchardCore.Cms.Web.dll"]

该 Dockerfile 使用典型的**多阶段构建(multi-stage build)**策略:

  1. 构建阶段(build-env):基于mcr.microsoft.com/dotnet/sdk:10.0中间镜像,其中包含完整的 .NET SDK。--platform=$BUILDPLATFORM让构建阶段在发起构建的宿主机平台上执行(配合 BuildKit 可避免跨平台模拟的开销)。随后将src源码以及Directory.Build.props、Directory.Packages.props两个根级 MSBuild 属性文件复制进镜像,执行dotnet publish生成 Release 发布产物到/app。
  2. 运行时阶段:基于mcr.microsoft.com/dotnet/aspnet:10.0(仅含 ASP.NET Core 运行时,不含 SDK)生成最终镜像。ARG TARGETOS配合build_${TARGETOS}的多阶段目标选择,可同时产出 Linux 与 Windows(nanoserver-ltsc2025)两个平台的运行时镜像。
  3. 运行时配置:EXPOSE 80暴露 HTTP 端口,ENV ASPNETCORE_URLS=http://+:80让 Kestrel 监听 80 端口,ENTRYPOINT直接以dotnet OrchardCore.Cms.Web.dll启动站点。

版本说明:仓库当前global.json指定的 .NET SDK 版本为10.0.401(见 global.json),因此 Dockerfile 使用net10.0目标框架。官方文档编写时示例为sdk:6.0与aspnet:3.1,仅为当时快照;以当前仓库实际内容为准,若需回退到旧版本请自行同步修改基础镜像标签与--framework参数。

文档示例中的经典写法

官方文档展示了这一思想的简化版本,方便理解结构:

# Create an intermediate image using .NET Core SDK FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env LABEL stage=build-env WORKDIR /app # Copy and build in the intermediate image COPY ./src /app RUN dotnet publish /app/OrchardCore.Cms.Web -c Release -o ./build/release # Build runtime image FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 EXPOSE 80 ENV ASPNETCORE_URLS http://+:80 WORKDIR /app COPY --from=build-env /app/build/release . ENTRYPOINT ["dotnet", "OrchardCore.Cms.Web.dll"]

注意其中的LABEL stage=build-env:这个标签是后续“清理中间镜像”的关键钩子(见下文)。

.dockerignore:控制构建上下文

仓库根目录的 .dockerignore 用于过滤发送给 Docker 守护进程的构建上下文,防止把本地数据与编译产物带入镜像:

# Ignore any App_Data folder **/App_Data/ # Ignore all built assets **/[b|B]in/ **/[O|o]bj/

逐行解读:

  • **/App_Data/:排除所有租户数据目录。Orchard Core 默认把站点数据(如 SQLite 数据库、日志)存放在App_Data,这些内容绝不能打进镜像;
  • **/[b|B]in/与**/[O|o]bj/:同时匹配大写/小写形式的bin与obj目录,剔除所有已编译的 .NET 构建产物,保证镜像内是从干净源码重新发布的结果。

官方文档还给出了一个更激进的“白名单”变体(先忽略一切、再放行src),适合只想打包源码的场景:

# ignore all ** # Except src for building !./src/* # Ignore any App_Data folder **/App_Data/ # Ignore all prebuild **/[b|B]in/ **/[O|o]bj/

使用 docker 命令构建并运行镜像

基础流程

在源码根目录(Dockerfile 所在目录)执行:

REM Folder where the Dockerfile stands cd /orchardcore REM Build image from Dockerfile docker build -t oc . REM Creates a container, runs it and expose its service on port 80 docker run -p 80:80 oc
  • docker build -t oc .:根据当前目录下的Dockerfile构建镜像,并打上oc标签;
  • docker run -p 80:80 oc:基于oc镜像创建并启动容器,把容器内 80 端口映射到宿主机 80 端口。

启动成功后,浏览器访问 http://localhost 即可进入 Orchard Core 的安装向导。此时默认使用 SQLite 数据库——所有数据都写在容器内,容器销毁后数据随之丢失,适合快速验证;若需要持久化与多数据库,请使用下文的 Docker Compose。

清理构建中间镜像

由于Dockerfile使用中间镜像执行dotnet publish,长时间不清理会占用可观磁盘空间。仓库为中间镜像打上了stage=build-env标签,便于精确清理。

使用docker命令时的推荐流程:

REM Prunes intermediate containers created while building by using --rm docker build -t oc --rm . REM Prunes all intermediate images docker image prune -f --filter label=stage=build-env REM Creates a container, runs it and expose its service on port 80 docker run -p 80:80 oc
  • --rm:构建完成后自动删除中间容器;
  • docker image prune -f --filter label=stage=build-env:仅删除带stage=build-env标签的中间镜像,保留最终运行镜像。

使用 Docker Compose 编排多数据库环境

Docker Compose 可以让你在源码根目录执行一条docker-compose up命令,同时启动 Web 容器与 Orchard Core 官方支持的各数据库服务,避免在宿主机上逐个安装数据库。前提是根目录存在docker-compose.yml文件。Compose 的完整用法参考 Docker 官方 Compose 文档(docs.docker.com/compose)。

官方文档给出的docker-compose.yml示例:

version: '3.3' services: web: build: context: . dockerfile: Dockerfile ports: - "5009:80" depends_on: - sqlserver - mysql - postgresql sqlserver: image: "mcr.microsoft.com/mssql/server" environment: SA_PASSWORD: "P@ssw0rd!123456" ACCEPT_EULA: "Y" mysql: image: mysql:latest restart: always environment: MYSQL_DATABASE: 'orchardcore_database' MYSQL_USER: 'orchardcore_user' MYSQL_PASSWORD: 'orchardcore_password' MYSQL_ROOT_PASSWORD: 'root_password' ports: - '3306:3306' expose: - '3306' volumes: - mysql-data:/var/lib/mysql postgresql: image: postgres:latest volumes: - postgresql-data:/var/lib/postgresql/data ports: - 5432:5432 environment: POSTGRES_USER: orchardcore_user POSTGRES_PASSWORD: orchardcore_password POSTGRES_DB: orchardcore_database volumes: mysql-data: postgresql-data:

关键点说明:

  • web 服务:以当前目录为构建上下文(context: .)、使用根目录Dockerfile构建,宿主机 5009 端口映射到容器 80 端口,访问 http://localhost:5009 即可;depends_on声明对三个数据库服务的启动依赖;
  • sqlserver 服务:使用微软官方 SQL Server 镜像,通过SA_PASSWORD与ACCEPT_EULA: "Y"完成初始化(生产环境务必更换强密码并妥善管理SA_PASSWORD);
  • mysql 服务:mysql:latest镜像,通过环境变量预建orchardcore_database数据库与orchardcore_user用户,数据持久化在命名卷mysql-data;
  • postgresql 服务:postgres:latest镜像,同样通过环境变量初始化用户与数据库,数据持久化在命名卷postgresql-data;
  • 命名卷:volumes段声明的mysql-data与postgresql-data用于跨容器生命周期持久化数据,避免重启丢失。

Compose 场景下的中间镜像清理

REM Builds images if they are not already built docker-compose build REM Prune intermediate remaining images docker image prune -f --filter label=stage=build-env REM Start all containers docker-compose up
  • docker-compose build:构建尚未构建的镜像;
  • docker image prune -f --filter label=stage=build-env:清理dotnet publish阶段留下的中间镜像;
  • docker-compose up:启动全部容器。

如果不定期清理中间镜像,日积月累会占用大量磁盘空间;stage=build-env标签让清理变得精确而安全。

自动创建租户:Autosetup 与数据库 Shell 配置

在容器场景下,每次启动后都需要通过浏览器手动执行站点安装向导,这对自动化测试与 CI 很不友好。官方文档将该主题标记为 TODO,但给出了两条线索:

  1. 数据库 Shell 配置:Orchard Core 的 Shell 配置可以存储在数据库中,而不是默认的App_Data文件系统。在appsettings.json中配置:

    { "OrchardCore": { "Shells": { "Database": { "DatabaseProvider": "SqlConnection", "ConnectionString": "", "TablePrefix": "", "MigrateFromFiles": true } } } }

    然后在Startup.cs中通过services.AddOrchardCms().AddDatabaseShellsConfiguration();启用。MigrateFromFiles可在启用时把现有App_Data中的租户配置自动迁移到数据库。注意:使用该提供程序前必须先创建好数据库,并限制其访问权限。

  2. Autosetup 功能:仓库在历史 PR(OrchardCMS/OrchardCore #4567)中引入了自动安装能力,可结合环境变量或配方(Recipe)在容器启动时自动完成站点初始化,从而省去人工安装步骤。具体配置项以当前版本源码与发布说明为准。

让容器通过 HTTPS 对外服务

生产环境通常需要 HTTPS。ASP.NET Core 官方镜像仓库提供了现成的示例方案(dotnet-docker 仓库中的 “Hosting ASP.NET Core Images with Docker over HTTPS” 样例),核心思路是把开发证书(dev certificate)与密码导入容器并配置 Kestrel 绑定 HTTPS 端口。结合 Orchard Core 的 Dockerfile,可在运行时通过挂载证书、设置ASPNETCORE_Kestrel__Certificates__Default__Path与Password环境变量实现,具体以官方样例与 .NET 版本对应文档为准。

针对特定环境构建镜像

若要针对不同运行环境(如不同操作系统发行版、不同 .NET 版本)定制镜像,关键在于基础镜像的选择:

  • .NET SDK 镜像(mcr.microsoft.com/dotnet/sdk):用于构建阶段,包含编译所需的完整 SDK,可按需指定版本号(如10.0);
  • ASP.NET Core Runtime 镜像(mcr.microsoft.com/dotnet/aspnet):用于运行时阶段,仅包含运行 ASP.NET Core 应用所需的运行时与依赖,体积远小于 SDK 镜像,并区分 Linux 与 Windows(nanoserver-ltsc2025)变体。

构建时通过--platform参数指定目标平台(如--platform=linux/amd64、--platform=windows/amd64),仓库 Dockerfile 中的ARG TARGETOS会自动接收该值并选择对应的运行时阶段。

CI 专用 Dockerfile:为什么仓库要维护两份

仓库同时维护了 Dockerfile-CI 与 Dockerfile-CI.dockerignore,其设计动机是:

  • GitHub Actions 是仓库的持续集成工具,用于构建与测试各分支。若在 CI 上像本地一样执行完整的多阶段dotnet publish,构建会显著慢于直接使用已发布产物;
  • 因此Dockerfile-CI不再包含 SDK 构建阶段,而是假定.build/release目录已存在预编译的发布产物,直接用 ASP.NET Core 运行时镜像封装:
# This Docker file is intended for the CI # A prerequisite is a published application in the .build/release FROM --platform=$BUILDPLATFORM golang:alpine AS build ARG TARGETOS FROM mcr.microsoft.com/dotnet/aspnet:10.0-nanoserver-ltsc2025 AS build_windows FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS build_linux FROM build_${TARGETOS} AS aspnet EXPOSE 80 ENV ASPNETCORE_URLS http://+:80 WORKDIR /app COPY .build/release /app ENTRYPOINT ["dotnet", "OrchardCore.Cms.Web.dll"]

而 Dockerfile-CI.dockerignore 采用白名单策略,只放行预编译产物:

# Buildkit Only working in linux # Ignore all ** # Except precompiled files !/.build/release/*

CI 中的实际用法

在仓库的 GitHub Actions 工作流中(如 .github/workflows/preview_ci.yml 与 .github/workflows/release_ci.yml),先发布应用到.build/release,再使用docker buildx build -f Dockerfile-CI --platform=linux/amd64 -t orchardproject/orchardcore-cms-linux:dev --push .同时构建并推送 Linux 与 Windows 两个平台的镜像。也就是说:

  • 本地开发:用Dockerfile(含完整构建阶段),直观、独立;
  • CI 发布:用Dockerfile-CI(纯运行时封装),快速、稳定,且通过 buildx 支持多平台(--platform)构建与推送。

自定义 Dockerfile 与 BuildKit 注意事项

如果希望在自己的项目中使用多个不同名称的 Dockerfile(如针对不同环境维护多份),需要满足:

  • Docker 版本至少 19.03,才能启用 Docker BuildKit(BuildKit 可解析多个不同的.dockerignore文件,-f指定 Dockerfile 时使用-f Dockerfile.X同时自动匹配Dockerfile.X.dockerignore);
  • 文档明确指出GitHub Actions 目前仅在 Linux 上支持 BuildKit(相关讨论见仓库 issue #7651 与 docker/setup-buildx-action 的说明),Windows/macOS runner 上的多平台构建能力受限,跨平台构建(尤其 Windows 镜像)建议在 Linux runner 上通过 buildx 模拟完成。

BuildKit 还带来额外的构建加速与缓存能力(如并发执行构建步骤、按层缓存复用),对频繁迭代 Dockerfile 的开发者有明显收益。

常见问题速查

问题解决方案
容器启动后无法访问站点确认-p 80:80或-p 5009:80端口映射正确,并检查ASPNETCORE_URLS是否绑定 80 端口
磁盘被中间镜像占满docker image prune -f --filter label=stage=build-env定期清理
需要同时测多个数据库使用文档提供的docker-compose.yml,一条docker-compose up拉起 SQL Server / MySQL / PostgreSQL
容器数据随容器销毁丢失使用 Compose 命名卷(mysql-data、postgresql-data)持久化数据库数据
想自动完成站点安装参考数据库 Shell 配置(AddDatabaseShellsConfiguration)与 Autosetup 功能,避免手工向导
需要 HTTPS参照 ASP.NET Core 官方 Docker HTTPS 样例,注入开发证书并配置 Kestrel 证书路径
需要 Windows 平台镜像使用带--platform=windows/amd64的 buildx 构建,仓库 Dockerfile 已内置nanoserver-ltsc2025运行时阶段

总结

从源码到可运行的容器,Orchard Core 仓库通过 Dockerfile 与 .dockerignore 提供了完整的多阶段构建方案:SDK 中间镜像完成dotnet publish,运行时镜像保持最小体积;stage=build-env标签让中间镜像可被精确清理。配合 docker-compose.yml 示例,可以在本地一键验证 SQL Server、MySQL、PostgreSQL 三种官方支持的数据库环境;Dockerfile-CI 则展示了面向 CI 的“预编译 + 运行时封装”模式,支持通过 buildx 多平台发布。无论是日常测试 PR、验证多数据库兼容性,还是为生产部署做铺垫,这套容器化工作流都能直接复用。

  • CMS
  • 后端
  • Web框架

【免费下载链接】OrchardCore

Orchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.

项目地址:https://gitcode.com/gh_mirrors/or/OrchardCore
点击查看免费下载
上一篇:3分钟搞定Windows和Office激活:零基础也能用的智能激活脚本
下一篇:Windows系统终极激活方案:KMS_VL_ALL_AIO一键激活完整指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询