2019/10/24,docker19.03.4, .netcore 3.0
摘要:asp.net core 3.0 网站项目容器化部署,使用docker-compose编排Nginx容器、MySQL容器、web容器
依赖结构介绍
整个网站项目取名samplems,一共需要三个容器(按依赖顺序):
1.MySQL容器,取名为samplems.mysql
,来自mysql
(官方)镜像
2.web容器,取名为samplems.web
,来自samplemsweb
(自己build出来的)镜像
3.nginx容器,取名为samplems.nginx
,来自samplemsnginx
(自己build出来的)镜像
使用docker-compose编排三个容器,建立桥接网络(取名samplems-net
)联系三者
目录结构
在CentOS中新建deploy部署文件夹,用于存放部署所需文件,deploy里文件结构如下:(后文会逐步建立以下内容)
│ docker-compose.yml //compose编排文件
│
├─web //web 目录
│ │ Dockerfile //web docker配置文件
│ │
│ └─publish //web 发布文件(发布生成的内容)
│ ...
│ appsettings.json //发布文件中包含appsettings.json,其中有数据库连接配置
│ ...
│
└─nginx //nginx目录
│ Dockerfile //nginx docker配置文件
│
└─confs //nginx 配置文件目录
nginx.conf //nginx全局配置
samplems.conf //web项目对应的nginx配置文件
把部署分为两步:
1.构建所需镜像
2.使用docker-compose编排容器
构建所需镜像
MySQL镜像
本次项目用到的MySQL镜像直接使用官方镜像,不需要进一步包装修改,直接拉取(下载)官方镜像:
docker pull mysql
web镜像
web项目准备
Visual Studio中,web项目的MySQL数据库连接字符串(appsettings.json中)改为:
server=samplems.mysql;database=samplems;user=root;password=mysql@samplems
注意点:
- server=samplems.mysql,这个地址就是我们的MySQL容器名;
- 此处的密码和后文中docker-compose.yml指定的MySQL密码要一致;
- 连接字符串没有显式指定连接端口,所以是默认的3306端口
web项目发布时,目标运行时选择linux-x64
或可移植
将发布内容拷贝到目标系统上,把它放进deploy/web/publish文件夹内,如下图:
我这里web项目名称为WebMvc,所以其中的WebMvc.dll就是后文Dockerfile中dotnet指令的对象。
Dockerfile编写
deploy/web文件夹下新建Dockerfile文件,内容如下:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.0
WORKDIR /app
COPY ./publish/ /app
EXPOSE 80
ENTRYPOINT ["dotnet","WebMvc.dll"]
上面五句话的意思分别是:
- 基于mcr.microsoft.com/dotnet/core/aspnet:3.0镜像(因为是netcore3.0的web项目),会自动下载该镜像
- 工作目录为容器内的/app
- 将/web/publish文件夹里所有内容拷贝至/app
- 容器暴露80端口
- 使用dotnet运行asp.net core web项目,这里是"WebMvc.dll",因为WebMvc.dll就在工作目录中,所以不需要任何路径
构建web镜像
在deploy/web文件夹下使用以下指令构建镜像:(注意samplemsweb与.之间有空格,samplemsweb就是我们命名的镜像名称)
docker build -t samplemsweb .
如下图所示:
nginx镜像
nginx配置文件
deploy/nginx/confs/下新建nginx.conf文件,此文件是Nginx的配置文件,内容如下:
user nginx;
worker_processes 1;
#error_log
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
client_max_body_size 256m;
client_body_buffer_size 50m;
access_log /var/log/nginx/access.log main;
#以下是 websocket 支持配置
#map $http_upgrade $connection_upgrade {
# default upgrade;
# '' close;
#}
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
deploy/nginx/confs/下新建samplems.conf文件,内容如下:
# 设定负载均衡后台服务器列表
upstream composeserver {
#指定支持的调度算法
ip_hash;
server samplems.web:80;
}
#虚拟主机的配置
server {
listen 80;
location / {
proxy_pass http://composeserver;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#以下是 websocket 支持配置
#proxy_http_version 1.1;
#proxy_set_header Upgrade $http_upgrade;
#proxy_set_header Connection $connection_upgrade;
}
}
其中samplems.web就是我们web容器的名称,后面的80即容器端口
Dockerfile编写
在deploy/nginx文件夹下新建Dockerfile文件,内容如下:
FROM nginx:latest
COPY ./confs/samplems.conf /etc/nginx/conf.d/default.conf
COPY ./confs/nginx.conf /etc/nginx/nginx.conf
上面三句话的意思分别是:
- 基于nginx最新的镜像构建,会自动下载该镜像
- 将confs/samplems.conf文件拷贝至/etc/nginx/conf.d/default.conf
- 将confs/nginx.conf文件拷贝至/etc/nginx/nginx.conf
构建nginx镜像
使用以下指令构建镜像:(注意samplemsnginx与.之间有空格,samplemsnginx就是我们命名的镜像名称)
docker build -t samplemsnginx .
完成后,查看docker镜像列表:
至此所有的镜像已建立
编写docker-compose.yml
在deploy文件夹下新建docker-compose.yml文件,内容如下:
version: '3.4'
services:
samplems.mysql:
image: mysql
container_name: samplems.mysql
ports:
- "3306:3306"
restart: always
environment:
- MYSQL_ROOT_PASSWORD=mysql@samplems
- TZ=Asia/Shanghai
volumes:
- /app/data/mysql:/var/lib/mysql
networks:
- samplems-net
samplems.web:
image: samplemsweb
container_name: samplems.web
restart: always
depends_on:
- samplems.mysql
environment:
- TZ=Asia/Shanghai
networks:
- samplems-net
samplems.nginx:
image: samplemsnginx
container_name: samplems.nginx
restart: always
ports:
- "80:80"
- "443:443"
environment:
- TZ=Asia/Shanghai
volumes:
- /app/logs/nginxlogs:/var/log/nginx
depends_on:
- samplems.web
networks:
- samplems-net
networks:
samplems-net:
driver: bridge
如上代码所示,整个yml文件结构大致分为version、services、networks三块,其中services内又有samplems.mysql、samplems.web、samplems.nginx三块
samplems.mysql:
- image 表示引用的镜像,这里是官方的mysql
- container_name:容器名称(其他两个容器这个字段的定义类似)
- ports 映射的端口号,宿主机的3306映射到容器的3306端口(其他两个容器这个字段的定义类似)
- restart: always 指定容器退出后的重启策略为始终重启(其他两个容器这个字段的定义相同)
- environment 中定义了MySQL root账号的密码为mysql@samplems,这里需要和web项目中密码保持一致
- environment 中定义了容器时区为亚洲上海,防止容器时区和宿主机时区不一致导致获取到的时间有偏差(其他两个容器这个字段的定义相同)
- volumes 挂载数据卷,将容器中所有要写入/var/lib/mysql中的文件,写入到宿主机/app/data/mysql中(这样即使mysql容器被删除,数据依然存在)
- networks 使用自定义的samplems-net桥接网络(其他两个容器这个字段的定义相同)
samplems.web:
- image 这里引用的是我们自己build的web镜像
- depends_on 表明容器要先启动samplems.mysql,再启动samplems.web
samplems.nginx:
- image 这里引用的是我们自己build的nginx镜像
- ports 80端口是默认的http端口,443是默认的https端口
- volumes 挂载数据卷,将容器中所有要写入/var/log/nginx中的文件,写入到宿主机/app/logs/nginxlogs中,这里主要是nginx的日志文件
- depends_on 表明容器要先启动samplems.web,再启动samplems.nginx,如此一来,启动的先后顺序为 mysql->web->nginx
启动容器
至此所有的准备工作都已完成,在deploy文件夹下执行以下命令启动容器:
docker-compose up -d
如下图,三个绿色的done表示三个容器启动成功:
使用docker ps查看容器的运行状态,是正常运行:
开放宿主机防火墙80端口:
sudo firewall-cmd --zone=public --add-port=80/tcp --permanent
sudo systemctl restart firewalld
浏览器访问CentOS的IP地址,即可查看网页: