如何用Docker Compose和SteveLTN/https-portal部署多子域名应用
解决多子域名Docker应用部署的端口冲突与路由问题
你遇到的核心问题确实是多个https-portal容器同时绑定80/443端口导致的冲突——当第二个容器启动时,它无法正常监听这两个端口,Let's Encrypt的ACME验证请求会被第一个容器拦截,最终导致验证失败。
下面是一套适合新手的完整解决方案,用单个反向代理容器统一处理所有子域名的SSL证书和路由转发:
步骤1:调整项目结构
首先把所有应用整合到一个根级别的docker-compose.yml管理,不需要每个应用单独的配置文件。最终结构如下:
-/your-project-root -/apps -/app1Folder Dockerfile -/codeFolder -/app2Folder Dockerfile -/codeFolder docker-compose.yml # 新增根目录的配置文件
步骤2:编写根级别docker-compose.yml
这个文件会同时启动所有应用和一个统一的https-portal反向代理,配置如下:
version: '3.8' # 自定义容器网络,让所有服务能互相访问 networks: app-network: driver: bridge services: # 应用1服务 app1: build: ./apps/app1Folder # 指向app1的Dockerfile目录 restart: always networks: - app-network # 加入自定义网络 # 应用2服务 app2: build: ./apps/app2Folder # 指向app2的Dockerfile目录 restart: always networks: - app-network # 统一的反向代理+SSL证书管理 https-portal: image: steveltn/https-portal:1 ports: - '80:80' # 必须开放,用于ACME验证和HTTP跳转HTTPS - '443:443' # HTTPS服务端口 restart: always environment: # 配置所有子域名的路由规则,用逗号分隔 DOMAINS: 'sub1.example.com -> http://app1:5001, sub2.example.com -> http://app2:5002' STAGE: 'production' # 正式环境用这个,测试阶段可以换成'staging' networks: - app-network
步骤3:确认应用Dockerfile配置
每个应用的Dockerfile保持原有逻辑,只需要确保应用监听的端口唯一(比如app1用5001,app2用5002),不需要暴露端口到主机(反向代理会在容器网络内访问它们)。示例(app2的Dockerfile):
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base WORKDIR /app FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build WORKDIR /src COPY ["App2.csproj", "."] RUN dotnet restore "./App2.csproj" COPY . . WORKDIR "/src/." RUN dotnet build "App2.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "App2.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENV ASPNETCORE_URLS http://+:5002 # 这里改成app2的端口 EXPOSE 5002 ENTRYPOINT ["dotnet", "App2.dll"]
步骤4:部署与验证
- 先停止之前运行的所有容器(进入原应用文件夹执行
docker-compose down) - 进入根项目目录,执行启动命令:
docker-compose up -d - 查看
https-portal的日志,确认证书获取成功:docker-compose logs -f https-portal - 访问
sub1.example.com和sub2.example.com,检查应用是否正常加载且有HTTPS证书。
关键注意事项
- DNS配置:确保所有子域名(
sub1.example.com、sub2.example.com)都指向你的DigitalOcean Droplet公网IP,且DNS已完成传播(可以用nslookup sub2.example.com验证) - 防火墙设置:在DigitalOcean控制台的防火墙规则中,允许80(HTTP)和443(HTTPS)端口的入站流量
- Let's Encrypt速率限制:如果之前用staging环境测试多次,切换到production时注意不要超过证书申请速率限制(每周每个域名最多5个证书)
内容的提问来源于stack exchange,提问作者SimpForJS
相关产品推荐
相关产品推荐

