缘起
哈喽大家好!今天是周一了,这几天趁着午休的时间又读了一本书《偷影子的人》,可以看看?。
今天也是入园的第九个月了,前后端分离系列到了今天正好是 43 篇,也写了 20 万字了,内心也是经历了各种曲折,是时候给《前后端分离》来一个句号了,为啥突然有了这个想法了呢??,周末两天在学习的时候,发现其他有的博主已经把自己的开源项目关闭更新了,刚开始还有点儿不理解,后来想了想,也确实无可厚非,吃完饭做了下思考:
1、我写的这个项目,当时不是为了写框架,只是想给大家提供下学习的参考,对比错误的,我很害怕会出现把注意力过多的放在框架上的,而忽略了基础知识学习的尴尬情况,这个在以后的新公司入职中,会比较被动,比如我前天面试遇到的,1: Vue运行时版本和完整版有啥区别和联系,2:Vue 异步更新DOM的机制有什么好处?如何实现的?;
2、当然,有一些基础比较好的小伙伴,不仅能看懂我的代码,还能在我的项目基础上,进行封装,我还是很欢迎使用的,用在生产环境,如果我还一直进行大的迭代更新的话,可能对大家有一定的影响;
3、前两天群里有小伙伴问了一些部署的相关问题,我才发现,我竟忽略了这一部分,诚然,我也写了一些,但是没有统一起来,那就用这篇详细的部署文章来画个句号吧。
本篇文章会一直更新,内容十分丰富,包含了NetCore+vue 的各种部署方案,以及遇到的主要错误分析,目的就是为了让初学者可以有章可循。
一、部署
各种下载地址:
Runtime(winth hosting) + SDK: https://dotnet.microsoft.com/download
友1、WIN_独立部署
感谢群里(白云)小伙伴,博主 @小淋科技 提出的方案(需要 netcore2.1+ ),我竟然忽略了,该打该打,官档都读不仔细,果然三人行必有我师!
微软官方文档 ——《独立部署 (SCD)》,使用这个方法很简单,只需要部署的时候,选择指定的平台,就可以不用安装其他,比如运行时、托管、SDK等,不过这样的话,可能下文的命令行操作不适用,不过还是很好很简单的方案,欢迎尝试。
1、WIN_IIS 部署,前后端不同站点
为了能有一个全新的环境,我还特地新买一台服务,要做好部署的准备,就必须要先进行初始化操作,也就是先准备好我们用到的原材料:
在服务器开启 IIS 就不多说了,相信每一个 Dotnet 开发者百分比必须要会的,其他的操作流程请看下边的步骤,具体的看动图:
先给自己的两个站点想好端口,比如我想的:core(1001端口)、Vue(1002端口)
// NetCore 部分 0、编译项目,保证代码没问题,并配置 CORS 跨域服务;//下边动图中没有配置CORS,大家自己要注意 ①、发布项目;//请注意我的 publish 路径是 bin/Debug/netcore2.2,因为这样肯定不会漏掉文件!!! ②、拷贝到服务器指定文件夹; ③、IIS 添加站点;// 端口 1001 ④、修改应用程序池为“无托管”;//这也是为啥要安装 windows hosting 的原因 ⑤、安装 windows hosting(服务托管);//这是一个捆包,已经包含 Runtime(下载地址见下文 错误码 500.19 的解决方案中) ⑥、检查是否有指定的 Runtime(运行时); ⑦、重启项目,查看是否正常;http://localhost:1001/
// Vue 部分 ①、Build 项目; ②、拷贝到服务器指定文件夹; ③、IIS 添加站点;// 端口 1002 ④、运行项目,查看是否正常;http://localhost:1002/
动图1():
修改好 hash 模式后,就成功了,注意要在 Core 项目中配置 CORS 跨域:
c.AddPolicy("LimitRequests", policy => { // 支持多个域名端口,注意端口号后不要带/斜杆:比如localhost:8000/,是错的 // 注意,http://127.0.0.1:1818 和 http://localhost:1818 是不一样的,尽量写两个 policy .WithOrigins("http://127.0.0.1:1002", "http://localhost:1002") .AllowAnyHeader() .AllowAnyMethod(); });
最终结果如下:
2、WIN_IIS 部署,前后端一个站点
从上边的过程中,可以看出来还是比较简单的,一气呵成,行云流水,不过可能自己操作的时候会出现这样那样的问题,毕竟我也是给很多小伙伴都部署过,没有上百,也有五十次了,如果你有错误,请看我文章下边第二章的 常见错误 ,找到你遇到的错误。
上边的操作中,我们是把两个项目部署到了 IIS 中的不同站点,当然,我们也可以部署到一个站点,这样的话,就是一个域名了,但是丝毫没有影响我们分开开发,我们前后端攻城狮还是和以前一样的开发,只是将发布的文件上传到指定服务器文件夹中就行了。
操作步骤和上边的其实是几乎一样的,只不过我们不需要配置 CORS 跨域了,因为是同一个站点,且是只需要一个端口号,我们定为 1003端口
// NetCore 部分,和上边的几乎一样,只不过不用进行 CORS 跨域设置 ①、发布项目; ②、拷贝到服务器指定文件夹; ③、IIS 添加站点;// 端口 1003 ④、修改应用程序池为“无托管”;//这也是为啥要安装 windows hosting 的原因 ⑤、安装 windows hosting(服务托管);//这是一个捆包,已经包含 Runtime(下载地址见下文 错误码 500.19 的解决方案中) ⑥、检查是否有指定的 Runtime(运行时); ⑦、重启项目,查看是否正常;http://localhost:1003/ // Vue 部分 ①、修改根路径,并且 Build 项目;// 还要修改接口api的路径,剩下的自己处理吧,不要项目后期用这个方法,路径修改麻烦 ②、拷贝到服务器指定文件夹;//可以和 core 项目放到一起 ③、修改 Core 的 IIS 站点,在它的站点内,嵌套一个vue站点;// 取名为 Vue ④、运行项目,查看是否正常;http://localhost:1003/vue/
动图2:
3、WIN_Git_Nginx_Kestrel 部署
上边的 IIS 部署咱们说完了,大家发现,存在一些问题:
1、过分的依赖 IIS,并没有完完全全的达到跨平台的目的;
2、操作步骤偏多,还需要拷贝文件,并且一个都不能少;
3、因为 IIS 会存在占资源的问题,每次如果我们更新 Blog.Core.dll 文件,都需要关闭站点,然后更新,再启动;
那接下来咱们就说说如何使用 Nginx+Kestrel 来简单的解决这些问题,步骤如下:
这里需要安装 Ngxin (http://nginx.org/en/download.html)、Git(https://git-scm.com/downloads)、SDK(http://go.microsoft.com/fwlink/?LinkID=287120),过程省略,大家自行安装,这里我们把端口定为,NetCore(1004端口)、Vue(1005端口)
// NetCore 部分 ①、执行 Blog.Core.Build.bat 文件;// 主要是 git pull ,dotnet build 和 dotnet run ②、Nginx 代理服务,将 8081 端口,代理到 1004;//具体的代码在下边
③、查看是否正常;// http://localhost:1004/ // Vue 部分 ①、执行 BS 命令;// cnpm run BS,这里是我自己的命令,主要是git pull 和 build ②、Nginx 代理 Vue 服务,并配置跨域,代理到1005;//具体的代码在下边 ③、查看是否正常;// http://localhost:1005/
大家可以看看,或者直接感受一下,这种部署方案,和 IIS 的方案,哪一个更好一些?三步走,也是很简单,而也很直观的。
// 红色是 NetCore 的 Nginx 相关配置;
// 绿色的是 Vue 的 Nginx 的相关配置;
#user nobody; worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; #keepalive_timeout 0; keepalive_timeout 600; proxy_read_timeout 600; proxy_send_timeout 600; # dotnet core upstream dotnetblogserver1 { server 127.0.0.1:8081; } server { listen 1004; server_name localhost; location /{ proxy_pass http://dotnetblogserver1; index index.html index.htm; } location = /50x.html { root html; } } # vue server { listen 1005; server_name localhost; location / { root nuxt\Blog.Admin\dist; index index.html index.htm; } location /api { rewrite ^.+apb/?(.*)$ /$1 break; include uwsgi_params; proxy_pass http://localhost:1004; #// 这是 netcore 端口 } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
}
从上边的部署中,我们可以看到,过程中我们几乎都没有进行什么配置,或者说都是一次性的配置,比如 Git 安装,比如 Nginx 的学习,只要我们配置了一次,以后多个项目就可以很快的操作了,比 IIS 每一个都要 Publish 并且各种配置来的快些。
不仅如此,我们也换掉了 IIS ,使用了 netcore 自带的 Kestrel 应用服务器,并且不会出现任何不同步的问题,只要你本地调试好代码,并 push 到 git 上!
动图3:
4、WIN 部署到 Windows 服务
微软有提供 如何在windows服务托管asp.net core ,不过步骤比较麻烦,还需要改源码,网上找到一种方法 使用NSSM把.Net Core部署至windows服务
简单说一下步骤
1. 下载nssm:http://www.nssm.cc/download
2. 运行cmd,定位到nssm.exe文件路径,运行nssm install
3. 在弹出的窗口配置:
Path:dotnet所在的目录,一般默认是在C:\Program Files\dotnet\dotnet.exe;
Startup directory:程序所在的目录,就是最后程序dll所在的目录;
Arguments:程序dll的名称,一般是项目名加上.dll;
Service name:在此写上服务的名称即可。
最后点击install service 完成windows服务安装。
在windows服务找到对应服务名,启动,然后根据launchSettings.json配置的端口访问,即可调取接口。
4. 如果使用Nginx代理的话,注意端口是5000,不是8081
感谢博友 @小雪转中雪 提醒
5、Linux_Ubuntu_Nginx 部署
1、安装.NET Core
首先需要安装.NET Core Runtime: https://www.microsoft.com/net/download
点击之后,根据您的Linux发行版不同,选择相应的操作步骤:
最后执行dotnet --info验证安装是否成功:
2、安装Nginx
另外还需要安装Nginx,
sudo apt-get install nginx
安装好后,直接访问你的 IP 地址,如果看到如下效果说明安装成功:
修改 nginx.conf 配置代理:
upstream dotnetblogserver1 { server 127.0.0.1:5018; } server { listen 4773; server_name core.idotnet5.com; location /{ proxy_pass http://dotnetblogserver1; index index.html index.htm; } location = /50x.html { root html; } }
修改后,重启:
3、在服务器构建源码并发布
然后就是发布程序了,发布有两种办法:
- 在开发机上执行 dotnet publish 然后把发布的文件远程到服务器上
- 直接在服务器上使用源码构建并发布,我一般是这样做的。
如果直接在服务器上构建发布,所以需要安装.NET Core SDK:https://www.microsoft.com/net/learn/get-started-with-dotnet-tutorial
然后就可以使用发布命令了:dotnet publish --configuration Release。
发布好的文件在 bin/Release/netcoreapp*.*/publish 下面。
再把publish下的所有文件复制到我的目标文件夹即可:
在我的目标目录下,有这些文件:
如果执行 dotnet test.dll,这个程序就会在localhost:5000运行:
4、配置Nginx
然后我们再回来配置Nginx,进入 /etc/nginx/sites-available ,里面有一个Default文件,把它改个名,然后我们再建立一个新的Default文件:
保存后执行 sudo nginx -t 检验这个配置文件。
然后再执行 nginx -s reload 来重启nginx。
随后需要再把发布后的程序运行一下:dotnet test.dll:
在我使用网址访问80端口的时候,会自动跳转到 https//localhost:5001端口,导致连接失败:
可以在开发的时候,就直接去掉项目中使用 https 地址就行,在 launchSettions.json 文件中:
或者禁用 https 中间件:
打开浏览器访问试试:http://yourdomian.com/swagger/index.html
5、守护进程
在/etc/systemd/system 下新建文件(推荐使用winscp),文件名以.service结尾,配置内容为(注意:中文注释需要删掉,否则部分 Linux 服务器会报错):
[Unit] Description=HZKJ #服务描述,随便填就好 [Service] WorkingDirectory=/website/HZKJ #工作目录,填你应用的绝对路径 ExecStart=/usr/bin/dotnet /website/HZKJ/CZKJ.CMS.Web.dll #启动:前半截是你dotnet的位置(一般都在这个位置),后半部分是你程序入口的dll,中间用空格隔开 Restart=always RestartSec=25 #如果服务出现问题会在25秒后重启,数值可自己设置 SyslogIdentifier=HZKJ #设置日志标识,此行可以没有 User=root #配置服务用户,越高越好 Environment=ASPNETCORE_ENVIRONMENT=Production [Install] WantedBy=multi-user.target
写完配置文件后保存,输入指令确认服务:
systemctl enable (你的服务名).service
例如:systemctl enable HZKJ.service;
然后启动服务 systemctl start HZKJ.service
然后查看一下服务状态:systemctl status HZKJ 出现状态说明服务运行正常。
( 借鉴:https://www.cnblogs.com/Tassdar/p/9587829.html )
6、Linux_Docker 部署
1、docker安装
第一种方案:
依次执行下列命令
sudo yum install -y yum-utils device-mapper-persistent-data lvm2 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sudo yum makecache fast sudo yum -y install docker-ce
第二种方案( 绿色的部分):
Install using the repository
Before you install Docker Engine - Community for the first time on a new host machine, you need to set up the Docker repository. Afterward, you can install and update Docker from the repository.
SET UP THE REPOSITORY
-
Update the
apt
package index:$ sudo apt-get update
-
Install packages to allow
apt
to use a repository over HTTPS:$ sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common
-
Add Docker’s official GPG key:
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Verify that you now have the key with the fingerprint
9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
, by searching for the last 8 characters of the fingerprint.$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable"
INSTALL DOCKER ENGINE - COMMUNITY
-
Update the
apt
package index.$ sudo apt-get update
-
Install the latest version of Docker Engine - Community and containerd, or go to the next step to install a specific version:
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
Got multiple Docker repositories?
If you have multiple Docker repositories enabled, installing or updating without specifying a version in the
apt-get install
orapt-get update
command always installs the highest possible version, which may not be appropriate for your stability needs. -
To install a specific version of Docker Engine - Community, list the available versions in the repo, then select and install:
a. List the versions available in your repo:
$ apt-cache madison docker-ce
查看详细的命令,可以去官网来安装:https://docs.docker.com/install/linux/docker-ce/ubuntu/
第三种方案:
如果你Linux系统是 Ubuntu 版本的,发现不能使用 yum 的话,可以使用 wget:
wget -qO- https://get.docker.com/ | sh
安装成功后,可以启动服务
sudo service docker start
检查docker是否安装成功:
docker version
若成功显示如下:
完成之后,我们来使用docker来测试一下HelloWorld,通过输入 docker pull hello-world 来拉取 hello-world 镜像
root@VM-0-3-ubuntu:~# docker pull hello-world Using default tag: latest latest: Pulling from library/hello-world 1b930d010525: Pull complete Digest: sha256:41a65640635299bab090f783209c1e3a3f11934cf7756b09cb2f1e02147c6ed8 Status: Downloaded newer image for hello-world:latest
这样我们就从仓库拉取到了HelloWorld的镜像,接下来我们来运行一下,通过输入docker run hello-world
root@VM-0-3-ubuntu:~# docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
到这里,我们的 Linux 系统下 Docker 环境已经正式配置成功,下边就是要正式部署我们的项目了。
2、Docker 部署
如果你有任何Docker部署的问题,可以联系群友 @赵岩(305353941) ,专业的。
2.1、上传文件到 linux 服务器
在 linux 下创建文件夹 BlogCoreAPI
mkdir BlogCoreAPI //创建文件夹
用 ftp 把发布的文件全部上传到 BlogCoreAPI
2.2、添加 Dockerfile 文件
进入目录 BlogCoreAPI
cd BlogCoreAPI
创建文件 Dockerfile
vim Dockerfile
内容如下,说明:镜像里创建 blogcore 文件夹,复制 linux 上的文件到镜像目录,对外暴露 8101 端口,运行程序
FROM microsoft/aspnetcore:2.2 RUN cd /usr/local/src RUN mkdir blogcore WORKDIR /usr/local/src/blogcore COPY *.* ./ EXPOSE 8101 CMD ["dotnet", "Blog.Core.dll"]
保存
2.3、构建镜像
镜像名字叫 blogcore-image,禁用缓存,否则迭代时会出问题
docker build --no-cache -t blogcore-image . //注意这个点 . 表示当前目录
2.4、运行容器
用镜像 blogcore-image 创建容器,指定容器名称是 blogcore-container,指定时区(默认是美国时间,相差8小时)
docker run --name=blogcore-container -dp 8101:8101--restart=always -e LC_ALL="en_US.UTF-8" -e TZ="Asia/Beijing" blogcore-image //修改默认时区到亚洲/北京,并且将容器里的 8101 端口映射到 linux 主机的 8101 端口,最后每次运行失败后自动重启
如果你想要查看刚刚创建的容器的时区是否成功,可以执行命令:
docker exec blogcore-container date //查询当前容器时区
打开浏览器访问试试:http://yourdomian.com/swagger/index.html
热心博友提供知识:
@ Mr七师弟 的提醒:
2.5、发布更新
上面说的是第一次发布,后期迭代,需要把容器删除,再构建镜像,运行容器。
2.5.1 删除容器
docker container rm -f cchr-container
2.5.2 构建镜像&运行容器
就和上边的一样了:
docker build --no-cache -t cchr-image . docker run --name=blogcore-container -dp 8101:8101--restart=always -e LC_ALL="en_US.UTF-8" -e TZ="Asia/Beijing" blogcore-image
我还不知道有没有更快的方法,欢迎提建议。
7、PM2 做进程管理
我看到了很多教程,但是这里我尝试的时候依然不行,这里先留一个坑,提供有偿帮忙,如果有哪位会的话,可以联系我,或者下边留言 ?。
二、NetCore 错误
下边的都是我平时遇到的常见的错误,如果大家还有其他错误,可以留言下来,我补充到文章中,让更多的小伙伴都看到,避免麻烦。
1、错误码 —— 500.00
解析:发布后启动失败,进程内,网友提供,暂时我还没遇到
方案:
方法1:
应用池高级配置 - 启动32位应用程序 - 设置为True
方法2:
web.config
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" startupTimeLimit="3600" requestTimeout="23:00:00" hostingModel="InProcess">
删除 hostingModel="InProcess"
2、错误码 —— 500.19
解析:未安装 windows 服务器托管,打不开当前项目的 模块 选项
方案:
安装和项目匹配的 服务器托管( windows hosting ),这个是捆绑的可执行文件,除了托管,也把x86 和 x64的运行时都一起安装好了。
3、错误码 —— 500.21
解析:没有安装指定的模块,如果你想问这个模块是在项目哪里写的,可以查看发布后的 web.config 文件
方案:
1、如果你没有安装上边的 windows-hosting ,直接安装就可以解决这个问题;
2、如果已经安装了服务器托管,发现还没有这个 V2 模块,就是你项目的问题了,这个时候你可以从本地再发布 publish 一次,然后拷贝到服务器即可。
但是,如果还没有的话,证明你本地开发的项目异常了,不过这个情况基本可以排除,只要是 SDK 2.2 开发的,本地
最终要确保 AspNetCoreModuleV2 模块被安装。
4、错误码 —— 500.30
解析:进程内失败,这个我没有遇到,有群里小伙伴说的。
方案:
1、检查检查是否安装了 host
5、错误码 —— 502.5
解析:1、没有安装指定的运行时,进程外启动失败。
2、还有可能是在发布的时候,缺少某些依赖dll文件,可以打开日志调试,请看下边第七条。
3、或者使用 dotnet 命令行查看,是否有错误信息在控制台出现。
方案:
安装指定版本的 Runtime 运行时。
一般情况下,只要安装了服务器托管的话,会自动安装对应版本的运行时,但是有时候安装好了,还是会遇到这个错误,是因为我们后期项目迭代升级了:
举个栗子,本来我们的项目是 Netcore 2.1 版本,后来更新到了 2.2 ,但是服务器的运行时还是旧的 Runtime 2.1 运行时,我们把代码部署到服务器,发现没有指定运行时,就会出现这个问题。
下载地址:https://dotnet.microsoft.com/download/visual-studio-sdks?utm_source=getdotnetsdk&utm_medium=referral
6、错误码 —— 503
解析:IIS 项目应用程序池未开启
方案:开启程序池即可,
但是经过测试发现,不使用 “无托管代码” 也可以,这是为什么,很好奇?
7、An error occurred while starting the application
解析:项目已经可以启动,证明环境已经正常,只不过在项目启动的时候,出现了错误,也就是说是项目代码的问题。
方案:查看日志,看项目文件是否齐全。
如果你不知道如何打开日志,请看另一篇文章的这一节:https://www.cnblogs.com/laozhang-is-phi/p/9565227.html#autoid-5-5-0
下边这个错误,就是因为分离的原因,导致 Service.dll 和 Repository.dll ,或者 swagger 的xml 没有拷贝到发布文件夹下,从而导致项目没有启动起来。
8、总结
经过上边多个错误分析,如果我们第一次再服务器中部署,只需要安装 服务器托管 Windows-hosting 即可:
https://dotnet.microsoft.com/download/dotnet-core/2.2
三、Vue 错误
1、跨域失败
这都是很简单的错误,根据上边的动图,咱们也能看出来,关于跨域有以下几个方法:
1、IIS 部署,一定要在后端 NetCore 项目,进行 CORS 跨域;
2、除非你是在 IIS 中的同一个站点配置前后端两个项目;
3、如果是 nginx+kestrel 的话,记得在 nginx 中配置跨域代理;
4、其他方案,略;
2、页面刷新 404
为了这个错误,我上边的第一个动图,还特地的故意做了这个错误,就是 history 和 hash 的情况,当然也是有两个方案:
1、如果你是 IIS 部署,就得使用 hash 模式,不能用 history 模式;如果一定要用 history 模式,可以试试 https://www.jianshu.com/p/7cc266438f09
2、不过如果用 nginx 的话,可以利用 404 页面的机制,将 index.html 页面 copy 一份,重命名成 404.html 即可;
3、IIS 无法导入组件
在 Blog.Admin 项目中,都尝试下这两个导入方式。
如果还不行,就直接修改下导入组件的地方吧(感谢群友@听风者小伙伴提出的方案),不要说不知道这个代码在哪里修改:
四、结语
这篇文章会一直补充,尽量成为前后端分离的一个优质文章吧,希望大家能尽自己的力量,补充下。
前后端分离到这里就差不多了,江湖很大,各位有缘再会!
( MSI加油!)
五、Github & Gitee
https://github.com/anjoy8/Blog.Core
https://gitee.com/laozhangIsPhi/Blog.Core
--- --- ---
安装和项目匹配的 服务器托管( windows hosting ),这个是捆绑的可执行文件,除了托管,也把x86 和 x64的运行时都一起安装好了。
dockerfile中EXPOSE的端口是无效的。官方在定义dotnet基础环境的时候, 设置了环境变量的端口是80 , 如果直接是 docker run -name -p 8101:8101 会出现无法访问,此时执行docker logs containerID 会发现监听的是80 端口, 那么, 讲docker run 命令改成:docker run --name =[] -p8101:80 -d --resratr=always imsges 即可, 在浏览器输入:localhost:8101就可以看到正常访问