- FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
- RUN apt-get update
- RUN apt-get install -y nginx
- WORKDIR /App
- COPY bin/Debug/netcoreapp2.2/publish .
- COPY ./startup.sh .
- RUN chmod 755 /App/startup.sh
- RUN rm /etc/nginx/nginx.conf
- COPY nginx.conf /etc/nginx
- ENV ASPNETCORE_URLS http://+:5000
- EXPOSE 5000 80
- CMD ["sh", "/app/startup.sh"]
Line 1 指定基础镜像
Line 3-4 从 Debian package management store 安装 Nginx
Line 6-7 设置工作目录, 放置 ASP.NET Core webApp 部署包
Line 9-10 设置启动脚本
Line 12-13 设置 nginx 配置文件
Line 15-16 设置 ASP.NETCore Kestrel 在 5000 端口上监听, 暴露 5000,80 端口给容器外部
Line 18 稍后给出启动脚本
tip: 需要理解容器内是一个独立的 Linux 环境, Dockfile 中 EXPOSE 用于指示容器打算暴露的端口.
这里可只暴露 80 端口给外部, 但是必须给 ASPNETCORE_URLS 定义一个非 80 端口, 作为容器内 kestrel 监听端口.
最终 (tree -L 1) 输出的 App 目录结构如下
.
├── App.csproj
├── appsettings.Development.JSON
├── appsettings.JSON
├── bin
├── Dockerfile
├── nginx.conf
├── obj
├── Program.cs
├── Properties
├── Startup.cs
└── startup.sh
Nginx 配置
创建以上 Dockerfile 中需要的 nginx 配置文件, 在同一目录, VIM nginx.conf 创建文件:
- worker_processes 4;
- events { worker_connections 1024; }
- http {
- sendfile on;
- upstream app_servers {
- server 127.0.0.1:5000;
- }
- server {
- listen 80;
- location / {
- proxy_pass http://app_servers;
- proxy_redirect off;
- 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-Host $server_name;
- }
- }
- }
Line 8-10 定义一组服务器 (这里只有 webapp), 资源名称(app_servers) 可用在本文件任意位置.
Line 13 通知 Nginx 在 80 端口监听
Line 15-22 指示所有的请求都需要被代理到 app_servers
总之, 这个文件定义了 Nginx 在 80 端口监听外部请求, 并将请求转发给同一容器的 5000 端口.
启动脚本
对于 Docker 容器, 只能使用一个 CMD(或 ENTRYPOINT 定义), 但是这种反向代理配置需要启动 Nginx 和 Kestrel, 所以我们定义一个脚本去完成这两个任务
- #!/bin/bash
- service nginx start
- dotnet /App/App.dll
构建镜像
docker build -t example/hello-nginx .
该镜像名称为 example/hello-nginx 观察输出, 会看到 Dockerfile 中定义的每一步输出.
该镜像构建 Dockerfile 与 vs docker tool 生成的 dockerfile 进行对比, 该文件生成的镜像更小, 充分利用了镜像分层的理念.
运行镜像
docker run --name test -it -d -p 8080:80 example/test
该容器名称为 test, 现在可从 http://localhost:8080 端口访问 webapp, 通过 curl -s -D - localhost:8080 -o /dev/null 验证
通过 shell 终端进入容器内部, 可进一步分别探究 Nginx 和 Kestrel 服务:
- docker exec -it test bash
- # curl -s -D - localhost:80 -o /dev/null
- HTTP/1.1 200 OK
- Server: nginx/1.6.2
- Date: Fri, 24 Feb 2017 14:45:03 GMT
- Content-Type: text/html; charset=utf-8
- Transfer-Encoding: chunked
- # curl -s -D - localhost:5000 -o /dev/null
- HTTP/1.1 200 OK
- Date: Fri, 24 Feb 2017 14:45:53 GMT
- Transfer-Encoding: chunked
- Content-Type: text/HTML; charset=utf-8
- Server: Kestrel
tip: 对于正在运行的容器, 可使用 docker exec -it [container_id] [command] 进入容器内部探究容器
对于启动失败的容器, 可使用 docker logs [container_id] 查看容器输出日志
来源: https://www.cnblogs.com/mi12205599/p/10789202.html