本文记录如何在CentOS上通过Docker容器部署asp.net core应用。

整个asp.net core应用的架构如下:

整个项目结构如下:

./
├── docker-compose.yml
├── nginx.conf
├── Dockerfile
├── SearchSchedule.Data
│   ├── bin
│   ├── Infrastructure
│   ├── obj
│   ├── Repositories
│   └── SearchSchedule.Data.csproj
├── SearchSchedule.Model
│   ├── bin
│   ├── Enumeration
│   ├── obj
│   ├── POCO
│   └── SearchSchedule.Model.csproj
├── SearchSchedule.Service
│   ├── bin
│   ├── Extentions
│   ├── IService
│   ├── obj
│   ├── SearchSchedule.Service.csproj
│   └── Service
├── SearchSchedule.sln
└── SearchSchedule.Web
    ├── Api
    ├── appsettings.Development.json
    ├── appsettings.json
    ├── bin
    ├── bower.json
    ├── bundleconfig.json
    ├── Controllers
    ├── Enumeration
    ├── Models
    ├── obj
    ├── Program.cs
    ├── Properties
    ├── SearchSchedule.Web.csproj
    ├── SearchSchedule.Web.csproj.user
    ├── Services
    ├── Startup.cs
    ├── Views
    └── wwwroot

用到的镜像:

microsoft/aspnetcore-build #微软官方的编译asp.net core应用的镜像
microsoft/aspnetcore #微软官方的运行asp.net core应用的镜像
postgres #postgre官方的镜像,数据库版本是10.1
nginx #nginx官方的镜像

用到的容器:

1.一个nginx容器,监听80端口,然后将请求转发到后面的web服务器。这里负载均衡用的是轮换法。
2.两个web服务器,这里部署的是asp.net core 2.0的mvc应用。
3.一个数据库服务器,使用的而是postgresql数据库。

———————————分界线———————————

第一步:创建一个asp.net core应用。该应用包含4个项目:

SearchSchedule.Web//web展示层
SearchSchedule.Service//业务逻辑层
SearchSchedule.Data//数据访问层
SearchSchedule.Model//领域对象层

注意:数据库链接字符串要使用docker容器的名字,因为我们的web容器与数据库库容器是通过link命令简历链接的。docker会在web容器的host文件中,添加数据库容器的名称与IP地址映射。

下面是web项目的appsettings.js文件内容

{
    "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
            "Default": "Warning"
        }
    },
    "db": {
        "Postgresql": { "SearchSchedule": "Host=dbpostgre;Username=postgres;Password=123456;Database=SearchSchedule" }
    }
}

这里的Host=dbpostgre,这个dbpostgre就是后面docker-compose.yml文件里面,web容器link命令链接的容器名。

第二步:创建整个应用的Dockerfile文件,其路径与工程文件sln在同一级目录。

文件名:Dockerfile

FROM microsoft/aspnetcore-build:2.0.0-stretch AS builder
WORKDIR /source

COPY ./SearchSchedule.Data/*.csproj ./SearchSchedule.Data/
COPY ./SearchSchedule.Model/*.csproj ./SearchSchedule.Model/
COPY ./SearchSchedule.Service/*.csproj ./SearchSchedule.Service/
COPY ./SearchSchedule.Web/*.csproj ./SearchSchedule.Web/
COPY *.sln .
RUN dotnet restore ./SearchSchedule.sln

COPY . .
RUN dotnet publish ./SearchSchedule.sln -c Release -o /app/

FROM microsoft/aspnetcore:2.0.0-stretch
WORKDIR /SearchSchedule

COPY --from=builder /app .
ENTRYPOINT ["dotnet", "SearchSchedule.Web.dll"]

这里构建web镜像用到了两个微软的官方镜像。第一个是asp.net core应用的构建环境,第二个是asp.net core应用的运行环境。

注意:这里最开始的5个COPY命令,是为了缓存dotnet restore指令,因为这个指令会下载依赖的package,这个过程比较耗时,如果项目文件没有修改,则不需要每次构建都执行restore。

第三步:创建nginx的配置文件

这里的配置文件会用容器卷的形式,覆盖掉nginx官方镜像里面的配置文件。这样就将我们的配置注入到了nginx官方镜像构建的容器中了。

文件名:nginx.conf

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    upstream searchschedule_com{
        server web1;
        server web2;
    }

    server {
        listen       80;
        #server_name  www.nginxtest.com;
        access_log /var/log/nginx/searchschedule.log main;
    
        location /{
            proxy_pass http://searchschedule_com;
            proxy_http_version 1.1;
        }
    }
}

第四步:创建docker-compose文件,用来编排容器。

文件名:docker-compose.yml

version: '3.1'
services:
    dbpostgre:
        image: postgres:10.1
        restart: always
        volumes:
            - db_coreapp:/var/lib/postgresql/data
        environment:
            POSTGRES_PASSWORD: 123456
            POSTGRES_DB: SearchSchedule
    web1:
        build: .
        restart: always
        links:
            - dbpostgre
        depends_on:
            - dbpostgre
    web2:
        build: .
        restart: always
        links:
            - dbpostgre
        depends_on:
            - dbpostgre
    nginx:
        image: nginx:latest
        restart: always
        volumes:
            - ./nginx.conf:/etc/nginx/nginx.conf
        links:
            - web1
            - web2
        ports:
            - "80:80"
        environment:
            - NGINX_PORT=80
volumes:
    db_coreapp:

第五步:docker-compose构建镜像

运行docker-compose build

[root@14-22 searchschedule]# docker images
REPOSITORY                   TAG                   IMAGE ID            CREATED             SIZE
searchschedule_web1          latest                e7e7b739ebea        39 hours ago        299MB
searchschedule_web2          latest                e7e7b739ebea        39 hours ago        299MB
postgres                     10.1                  599272bf538f        2 weeks ago         287MB
nginx                        latest                40960efd7b8f        4 weeks ago         108MB

运行docker-compose up -d,启动容器,这样就完成了整个部署流程。

[root@14-22 searchschedule]# docker-compose up -d
Starting searchschedule_dbpostgre_1 ...
Starting searchschedule_dbpostgre_1 ... done
Starting searchschedule_web2_1 ...
Starting searchschedule_web1_1 ...
Starting searchschedule_web2_1
Starting searchschedule_web1_1 ... done
Starting searchschedule_nginx_1 ...
Starting searchschedule_nginx_1 ... done

如果docker-compose up 不加-d参数,则是在前台启动,会打印出启动信息。调试的时候可以方便查看容器的启动信息和执行情况。

至此整个发布流程就写完了,根据自己的实际操作写的笔记,可能存在记录不全的情况,大家有问题可以留言,一起讨论。

发表评论

电子邮件地址不会被公开。 必填项已用*标注