如何在 Windows Server 上用 Docker Compose 编排容器?

来源:AI社区作者:苏沐橙头衔:网络博主
导读:本期聚焦于苏沐橙创作的《如何在 Windows Server 上用 Docker Compose 编排容器?》,敬请观看详情。在一台 Windows Server 上同时运行门户站点和多个接口服务时,逐条手工执行 docker run 既繁琐又容易出错,参数一旦写错就得删掉容器重来。Docker Compose 把端口映射、卷挂载、环境变量等配置收敛到一份 YAML 文件里,一条命令即可完成整套服务的构建、启动与销毁。本文围绕 Windows Server 环境展开,先讲清 Windows 容器与 Linux 容器在内核共享和镜像版本上的差异,再演示启用容器功能、安装 Docker Engine 与 Compose 插件的完整步骤,随后给出一个包含 IIS 站点与接口服务的多容器编排示例,最后整理常用命令和高频故障的排查思路,帮助读者在 Windows 平台稳定落地容器化部署。

容器化早已不是 Linux 平台的专属能力,Windows Server 从 2016 版本开始就原生支持容器运行。配合 Docker Compose 之后,原本散落在多条命令行里的端口映射、卷挂载、环境变量等参数,可以被收敛到一份 YAML 文件中,一条命令即可拉起整套服务,销毁时同样干净利落。对于运行 .NET Framework 老应用、依赖 IIS 的站点,或者短期内无法迁移到 Linux 的业务系统来说,这套组合提供了一条风险可控的渐进式改造路径。

如何在 Windows Server 上用 Docker Compose 编排容器?

一、Windows 容器的运行原理与镜像选择

与不少人的直觉相反,Windows 容器和 Linux 容器在隔离机制上走的是同一条路线:容器与宿主机共享同一个内核。区别在于 Windows 容器共享的是 Windows 内核,这带来一个硬性约束——镜像内打包的操作系统版本必须与宿主机兼容。在一台 Windows Server 2019 上强行运行 ltsc2022 标签的镜像,容器会在启动后立刻退出,日志中会明确写出操作系统不匹配的提示。宿主机的内部版本号可以从注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion 中读取,先拿到 BuildNumber 再去对照镜像标签,能省去大量无意义的试错。

Windows 提供两种隔离模式。进程隔离开销小、启动速度快,但要求容器系统版本与宿主机严格对齐;Hyper-V 隔离则让每个容器运行在独立的轻量虚拟机中,允许版本存在差异,代价是更高的内存占用和更慢的启动速度。在 compose 文件里通过 isolation 字段切换,写成 isolation: process 或 isolation: hyperv 即可。如果宿主机与镜像版本能够对齐,生产环境优先选择进程隔离,资源利用率明显更好。

镜像来源也需要特别注意。Docker Hub 上绝大多数热门镜像只有 Linux 版本,Windows 生态的官方镜像集中在 mcr.microsoft.com 仓库中,例如 IIS 镜像 mcr.microsoft.com/windows/servercore/iis,.NET Framework 运行时镜像 mcr.microsoft.com/dotnet/framework/aspnet。拉取时务必核对标签中的 ltsc 版本号,Windows 基础镜像体积普遍在 GB 级别,磁盘空间也要提前规划。

# 读取宿主机系统内部版本号,用于对照镜像标签
(Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion').CurrentBuildNumber

# 检查容器功能是否已安装
Get-WindowsFeature -Name Containers

二、环境准备:启用容器功能并安装 Docker 与 Compose

环境准备分三步走:启用容器功能、安装 Docker Engine、安装 Compose 插件。Docker Engine 在 Windows Server 上通过 PowerShell 的包提供程序安装,整个过程不需要图形界面,装完重启一次机器即可生效。

# 安装 Docker 提供程序与引擎
Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
Install-Package -Name docker -ProviderName DockerMsftProvider -Force
Restart-Computer -Force

重启后执行 docker version 确认客户端与服务端都已就绪。引擎的全局配置文件位于 C:\ProgramData\Docker\config\daemon.json,该文件默认不存在,需要手工创建目录和文件。常见配置项包括镜像加速地址,以及开启实验特性以支持在同一台机器上切换运行 Linux 容器。每次修改配置后,执行 Restart-Service docker 让其生效。

{
  "registry-mirrors": ["https://mirror.ipipp.com"],
  "experimental": true
}

Compose 这边建议直接上 V2 版本。V1 的 docker-compose.exe 是独立程序,官方已停止维护;V2 以插件形式并入 docker 命令,调用方式从 docker-compose 变成了 docker compose,参数语义基本一致。安装 V2 只需把官方发布的可执行文件放进 C:\Program Files\Docker\Docker\cli-plugins\ 目录并命名为 docker-compose.exe。

# 创建插件目录并下载 Compose V2
New-Item -ItemType Directory -Force -Path "$env:ProgramFiles\Docker\cli-plugins"
Invoke-WebRequest -Uri "https://github.com/docker/compose/releases/latest/download/docker-compose-windows-x86_64.exe" -OutFile "$env:ProgramFiles\Docker\cli-plugins\docker-compose.exe"

# 验证插件是否就位
docker compose version

三、用一份 YAML 文件描述整套服务

假设要在 C:\apps\order-system 目录下编排一个小型系统:一个 IIS 静态门户加一个 .NET Framework 接口服务。目录结构很简单,site 子目录存放门户静态文件,api 子目录存放 Dockerfile 与发布产物,根目录放置 docker-compose.yml。所有服务、网络、卷都在这份文件里声明。

version: "3.8"

services:
  web:
    image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019
    container_name: portal-web
    isolation: process
    ports:
      - "8080:80"
    volumes:
      - C:\apps\order-system\site:C:\inetpub\wwwroot
    restart: unless-stopped
    networks:
      - frontend

  api:
    build:
      context: C:\apps\order-system\api
      dockerfile: Dockerfile
    container_name: order-api
    isolation: process
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
    ports:
      - "9000:80"
    volumes:
      - C:\apps\order-system\logs:C:\app\logs
    depends_on:
      - web
    restart: unless-stopped
    networks:
      - frontend

networks:
  frontend:
    driver: nat

几个字段值得展开说明。volumes 在 Windows 上的写法是盘符路径对盘符路径,冒号两侧都必须是绝对路径,写成相对路径或者指向不存在的目录都会导致容器创建失败;ports 的宿主机端口与容器端口映射格式与 Linux 完全一致;restart: unless-stopped 保证容器异常退出或宿主机重启后自动拉起,前提是 Docker 服务本身被设置为自动启动。depends_on 只控制启动顺序,并不等待上游服务真正就绪,如果接口依赖门户完成初始化,要么给上游服务加 healthcheck 配合 condition 写法,要么在应用层做重试,后者实现成本更低。

api 服务的镜像通过 Dockerfile 构建,基础镜像选 .NET Framework 4.8 的 servercore 版本,把发布产物复制进 IIS 默认站点目录即可。

FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2019
COPY ./publish/ /inetpub/wwwroot
EXPOSE 80

在 docker-compose.yml 所在目录执行 docker compose up -d --build,Compose 会先构建 api 镜像,再按依赖顺序创建并启动两个容器。首次运行需要从远端仓库拉取 servercore 基础镜像,耗时可能达到几分钟,属于正常现象。启动完成后用 docker compose ps 查看状态,浏览器访问宿主机 8080 端口即可看到门户页面。

四、生命周期管理与常用命令

日常运维基本围绕下面这组命令展开,掌握它们就能覆盖绝大多数场景。

命令作用
docker compose up -d后台启动全部服务
docker compose ps查看各服务运行状态
docker compose logs -f api持续跟踪指定服务日志
docker compose exec api cmd进入容器内部排查问题
docker compose restart api重启单个服务
docker compose down停止并移除容器与网络
docker compose down -v连命名卷一并删除

有两点容易被忽视。其一,down 与 down -v 的区别在于后者会把命名卷一起删掉,如果数据库数据放在命名卷里,执行前务必确认。其二,修改 compose 文件后再次执行 up -d,Compose 会做差量更新,只重建配置发生变化的服务,未受影响的服务原样保留。这正是它比逐条执行 docker run 的脚本优雅得多的地方——配置文件天然成了可版本化管理的基础设施声明。

五、高频故障排查思路

排查故障时优先怀疑三类问题。第一类是 YAML 文件本身:缩进必须用空格而不能用 Tab;用记事本编辑容易保存出带 BOM 的 UTF-8 文件,解析时会报出莫名其妙的错误,建议用 VS Code 编辑并确认编码为无 BOM 的 UTF-8。

第二类是容器启动即退出。最常见的原因是镜像版本与宿主机不匹配,docker compose logs 里能看到操作系统不匹配的提示,解决办法是更换镜像标签或者把 isolation 改成 hyperv。另一个高频原因是端口冲突,宿主机上已有进程占用了映射端口时,容器同样无法启动。

# 定位占用 8080 端口的进程
netstat -ano | findstr :8080

# 按进程号强制结束
taskkill /PID 4520 /F

# 查看接口服务最近两百行日志
docker compose logs --tail 200 api

第三类是网络与挂载问题。卷挂载的源路径必须真实存在且以盘符开头;防火墙也常被忽略,宿主机本机能访问不代表外部机器能访问,需要用 New-NetFirewallRule 放行对应端口。把这几类问题按顺序过一遍,绝大多数 Compose 编排故障都能在十分钟内定位到根因。

Docker ComposeWindows Server容器编排修改时间:2026-10-03 18:58:04

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/1003/65222.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。