Docker 部署方案
部署案例
Docker容器发布必要素 Dockerfile+发布的文件
我们发布Docker有几种解决方案,我习惯代码发布和开发环境分离,所以我选择在服务器pull代码生成后创建容器发布
即下文中“服务器打包创建容器”
其余两种方案本文只列举下所需工具,文章主要以“服务器打包创建容器”展开,自由选择,知识都一样.

服务器打包创建容器
服务器pull代码,服务器build代码,服务build镜像
需要工具列表
●Git
●NetCoreSDK
●NodeJs
环境安装命令
安装Git
# 安装Git 工具$ sudo yum -y install git
安装Net Core SDK
# 设置安装源$ sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm# 安装dotnet-sdk-3.1$ sudo yum install dotnet-sdk-3.1# 安装dotnet-sdk-5.0$ sudo yum install dotnet-sdk-5.0# 安装dotnet-sdk-6.0$ sudo yum install dotnet-sdk-6.0# 检查版本$ dotnet --list-sdks
以下为安装3.1的安装后查询
安装NodeJS
# 进入目录home[root@nine ~]# cd /home# 安装wget$ yum -y install wget# 下载nodejs12.18版本,此版本为编译好的版本,源码编译太多坑,很容易报错[root@nine home]# wget https://nodejs.org/dist/v12.18.3/node-v12.18.3-linux-x64.tar.gz# 解压下载好的node.js包到/usr/local/node-v12.18.3-linux-x64目录下[root@nine home]# tar xf node-v12.18.3-linux-x64.tar.gz -C /usr/local/# 进入usr 目录[root@nine home]# cd /usr/local/# 移动解压好的nodejs到nodejs文件夹[root@nine local]# mv node-v12.18.3-linux-x64/ nodejs# 将目录软链接到全局环境下(命令后面的/usr/local/bin/node是固定的)[root@nine local]# ln -s /usr/local/nodejs/bin/node /usr/local/bin[root@nine local]# ln -s /usr/local/nodejs/bin/npm /usr/local/bin# 这样安装好了以后使用npm安装的包(比如:ionic serve),使用包的命令时可能会提示找不到命令,没关系,在用户目录下终端执行下面命令(固定写法):[root@nine admin]# echo -e "export PATH=$(npm prefix -g)/bin:$PATH" >> ~/.bashrc && source ~/.bashrc# 检查安装情况,检查版本[root@nine local]# node -vv12.18.3# Eg:[root@nine local]# cd /home/code/admin[root@nine admin]# npm install[root@nine admin]# npm run build
构建部署后端NET Core项目镜像容器
添加Dockerfile
Docker容器发布必要素 Dockerfile+发布的文件
当然这里可以在发布文件位置自己写,个人建议直接添加到项目,属性更改始终复制,手工处理这些容易粗心大意出问题
在WebApi层项目创建Dockerfile


然后右键,始终属性、始终复制到输出(bin)目录:
打开Dockerfile,以下为精简的配置文件
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS baseWORKDIR /appCOPY . .EXPOSE 80ENTRYPOINT ["dotnet", "XXXX.dll","-b","0.0.0.0"]#简单注释一下:#FROM:意思是我们的项目源镜像是哪个;#WORKDIR:镜像的工作目录;#COPY:复制文件(将Dockerfile所在目录下文件复制到镜像中的工作目录中)#EXPOSE:容器要开放的端口(我们用.NETCORE的80端口)#ENTRYPOINT:为容器启动后要执行的命令 (这里将执行dotnet XXXX.dll命令) xxx改为自己的项目名称
pull代码服务器Git Pull好代码,这一步没什么好说的
build 项目生成发布文件
# 进入项目目录$ cd /home/core/# 生成项目$ dotnet build# 发布项目$ dotnet publish -o /home/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1-------------------执行效果(预览,部分删减)-------------------Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NETCopyright (C) Microsoft Corporation. All rights reserved.Determining projects to restore...Restored /home/core/FD.GenerationTemplate/FD.GenerationTemplate.csproj (in 365 ms).Restored /home/core/FD.Redis/FD.Redis.csproj (in 364 ms).Restored /home/core/FD.CloudHisCoreApi/FD.CloudHisCoreApi.csproj (in 15.93 sec).FD.GenerationTemplate -> /home/core/FD.GenerationTemplate/bin/Debug/netcoreapp3.1/FD.GenerationTemplate.dllFD.Redis -> /home/core/FD.Redis/bin/Debug/netcoreapp3.1/FD.Redis.dllFD.CloudHisCoreApi -> /home/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1/FD.CloudHisCoreApi.Views.dllBuild succeeded.0 Warning(s)0 Error(s)Time Elapsed 00:00:46.53Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NETCopyright (C) Microsoft Corporation. All rights reserved.Determining projects to restore...All projects are up-to-date for restore.FD.Model -> /home/core/FD.Model/bin/Debug/netcoreapp3.1/FD.Model.dllFD.Services -> /home/code/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1/FD.CloudHisCoreApi -> /home/code/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1/Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NETCopyright (C) Microsoft Corporation. All rights reserved.Determining projects to restore...Restored /home/core/FD.GenerationTemplate/FD.GenerationTemplate.csproj (in 365 ms).Restored /home/core/FD.Services/FD.Services.csproj (in 5.16 sec).FD.CloudHisCoreApi -> /home/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1/FD.CloudHisCoreApi.Views.dllBuild succeeded.0 Warning(s)0 Error(s)-------------------执行效果(预览)-------------------
这两步(pull代码build 项目生成发布文件)也有一个简单的方法,用批处理命令
在项目文件内,新建一个批处理命令 Linux 下批处理.shwindows下.bat新建一个文本文件project.release.sh改后缀,粘贴下面内容保存,上传到代码库
# 拉取代码$ git pull;# 清除发布文件的文件夹,确保文件生成都是全新文件$ rm -rf .release;# 生成项目$ dotnet build;# 发布项目$ dotnet publish -o /home/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1;# 复制文件到我们定义好的目录$ cp -r /home/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1 .release;# 提示信息$ echo "Successfully!!!! ^ please see the file .release";# 注:莫吧中文注释复制到批处理中,请直接复制下面这一段git pull;rm -rf .release;dotnet build;dotnet publish -o /home/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1;cp -r /home/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1 .release;echo "Successfully!!!! ^ please see the file .release";
此时候,我们执行发布的命令变成了两句
# 进入项目目录$ cd /home/core/# 执行批处理命令$ ./project.release.sh-------------------执行效果(预览,部分删减)-------------------[root@nine .release]# cd /home/core/[root@nine core]# ./project.release.shMicrosoft (R) Build Engine version 16.8.0+126527ff1 for .NETCopyright (C) Microsoft Corporation. All rights reserved.Determining projects to restore...Restored /home/core/FD.GenerationTemplate/FD.GenerationTemplate.csproj (in 365 ms).Restored /home/core/FD.Redis/FD.Redis.csproj (in 364 ms).Restored /home/core/FD.CloudHisCoreApi/FD.CloudHisCoreApi.csproj (in 15.93 sec).FD.GenerationTemplate -> /home/core/FD.GenerationTemplate/bin/Debug/netcoreapp3.1/FD.GenerationTemplate.dllFD.Redis -> /home/core/FD.Redis/bin/Debug/netcoreapp3.1/FD.Redis.dllFD.Model -> /home/core/FD.Model/bin/Debug/netcoreapp3.1/FD.Model.dllFD.IRepository -> /home/core/FD.IRepository/bin/Debug/netcoreapp3.1/FD.IRepository.dllFD.Common -> /home/core/FD.Common/bin/Debug/netcoreapp3.1/FD.Common.dllFD.CloudHisCoreApi -> /home/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1/FD.CloudHisCoreApi.dllFD.CloudHisCoreApi -> /home/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1/FD.CloudHisCoreApi.Views.dllBuild succeeded.0 Warning(s)0 Error(s)Time Elapsed 00:00:46.53Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NETCopyright (C) Microsoft Corporation. All rights reserved.Determining projects to restore...All projects are up-to-date for restore.FD.Model -> /home/core/FD.Model/bin/Debug/netcoreapp3.1/FD.Model.dllFD.Redis -> /home/core/FD.Redis/bin/Debug/netcoreapp3.1/FD.Redis.dllFD.Redis -> /home/code/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1/FD.Services -> /home/code/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1/FD.CloudHisCoreApi -> /home/code/core/FD.CloudHisCoreApi/bin/Debug/netcoreapp3.1/Successfully!!!! ^ please see the file .release-------------------执行效果(预览)-------------------
进入发布文件夹内,测试项目dotnetFD.CloudHisCoreApi.dll
# 进入发布文件内$ cd /home/core/.release# 测试项目 dotnet FD.CloudHisCoreApi.dll$ dotnet FD.CloudHisCoreApi.dll-------------------执行效果(预览)-------------------Last login: Fri Mar 25 11:07:34 2022 from oraybox.lan[root@nine ~]# cd /home/core/.release[root@nine .release]# dotnet FD.CloudHisCoreApi.dllwarn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]No XML encryptor configured. Key {fcd46988-fb0f-400a-80d6-c461f77a3a05} may be persisted to storage in unencrypted form.info: Microsoft.Hosting.Lifetime[0]Now listening on: http://localhost:5000info: Microsoft.Hosting.Lifetime[0]Now listening on: https://localhost:5001info: Microsoft.Hosting.Lifetime[0]Application started. Press Ctrl+C to shut down.info: Microsoft.Hosting.Lifetime[0]Hosting environment: Productioninfo: Microsoft.Hosting.Lifetime[0]Content root path: /home/core/.release-------------------执行效果(预览)-------------------可以看到已经正常的监听了5000端口,这里要注意一下,我们在Program.cs文件中,需要配置这样:.UseUrls("http://*:5000")Ctrl+C to shut down
构建镜像
# 根据Dockerfile构建镜像$ docker build -t jamnine/api .-t 镜像名字. 所有文件,记得这个点-------------------执行效果(预览)-------------------[root@nine .release]# docker build -t jamnine/api .Sending build context to Docker daemon 33.92MBStep 1/5 : FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base---> 28de0d96c539Step 2/5 : WORKDIR /app---> Running in 2fd50bc363b8Removing intermediate container 2fd50bc363b8---> 95a8b5d87bdaStep 3/5 : COPY . .---> a4880e87ba57Step 4/5 : EXPOSE 80---> Running in f37fdd29bf1bRemoving intermediate container f37fdd29bf1b---> a6195692236aStep 5/5 : ENTRYPOINT ["dotnet", "FD.CloudHisCoreApi.dll","-b","0.0.0.0"]---> Running in 4211700fb07bRemoving intermediate container 4211700fb07b---> e3022ca40b3bSuccessfully built e3022ca40b3bSuccessfully tagged jamnine/api:latest-------------------执行效果(预览)-------------------
查看镜像
# 查看镜像$ docker images-------------------执行效果(预览)-------------------[root@nine .release]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEjamnine/api latest e3022ca40b3b 3 minutes ago 241MBmcr.microsoft.com/dotnet/aspnet 5.0-buster-slim c535cc5fb113 16 months ago 205MB-------------------执行效果(预览)-------------------这里有了两个镜像,一个是我们的镜像ID为e3022ca40b3b,大小241M的项目文件,一个是我们Dockerfile的源镜像。
生成容器
# 生成容器(临时)$ docker run -it -p 8081:8081 jamnine/api-------------------执行效果(预览)-------------------[root@nine core]# docker run -it -p 8081:8081 jamnine/apiwarn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]No XML encryptor configured. Key {9d54979d-a5f5-47d0-b965-02e902a0820f} may be persisted to storage in unencrypted form.info: Microsoft.Hosting.Lifetime[0]Now listening on: http://[::]:80info: Microsoft.Hosting.Lifetime[0]Application started. Press Ctrl+C to shut down.info: Microsoft.Hosting.Lifetime[0]Hosting environment: Productioninfo: Microsoft.Hosting.Lifetime[0]Content root path: /app-------------------执行效果(预览)-------------------# 恭喜!看到这段没报错信息,容器生成成功,Ctrl+C to shut down退出当前进程,查看下有哪些容器:$ docker ps -a# -a 查看所有容器-------------------执行效果(预览)-------------------[root@nine core]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES583f20c5c996 jamnine/api "dotnet FD.CloudHisC…" About a minute ago Exited (0) 11 seconds ago strange_ardinghelli-------------------执行效果(预览)-------------------# 运行容器$ docker start 583f20c5c996-------------------执行效果(预览)-------------------[root@nine core]# docker start 583f20c5c996583f20c5c996[root@nine core]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES583f20c5c996 jamnine/api "dotnet FD.CloudHisC…" 7 minutes ago Up 57 seconds 80/tcp, 0.0.0.0:8081->8081/tcp strange_ardinghelli-------------------执行效果(预览)-------------------状态已经是运行中了,那怎么测试接口是否正常了呢,继续往下走测试接口# curl命令$ curl http://localhost:8081/api/blog至此,恭喜你,Docker部署NetCore基本已经搞定了,如果你想看看容器内的日志信息。
查看日志
# 查看日志$ docker logs 583f20c5c996-------------------执行效果(预览)-------------------[root@nine core]# docker logs 583f20c5c996warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]No XML encryptor configured. Key {9d54979d-a5f5-47d0-b965-02e902a0820f} may be persisted to storage in unencrypted form.info: Microsoft.Hosting.Lifetime[0]Now listening on: http://[::]:80info: Microsoft.Hosting.Lifetime[0]Application started. Press Ctrl+C to shut down.info: Microsoft.Hosting.Lifetime[0]Hosting environment: Productioninfo: Microsoft.Hosting.Lifetime[0]Content root path: /app-------------------执行效果(预览)-------------------
补充资料--Docker常用命令
# 查看所有镜像$ docker images# 删除一个imageid的镜像$ docker rmi [IMAE_ID]# 删除所有镜像$ sudo docker rmi $(docker images -q)# 查看所有容器运行状态$ docker ps -a$ docker container ls -all# 删除一个containerid的容器(实例)$ docker rm 6f0c67de4b72# 删除所有容器$ docker rm $(sudo docker ps -a -q)# 查看指定时间后的日志,只显示最后100行:$ docker logs -f -t --since="2019-06-08" --tail=100 CONTAINER_ID# 查看某时间之后的日志:$ docker logs -t --since="2019-06-08" CONTAINER_ID# 查看某时间段日志:$ docker logs -t --since="2019-06-08" --until "2019-06-09" CONTAINER_ID# 查看最近30分钟的日志:$ docker logs --since 30m CONTAINER_ID# 停止容器$ docker stop 5ab35ebcb6e2# 删除容器$ docker rm 5ab35ebcb6e2# 删除镜像$ docker rmi 7567a38d491c# 启动容器$ docker start 685cb02f53
构建部署前端Vue项目镜像容器其实这个具体的写法和上篇部署ASP.NETCore是类似的,我这里快速的说一下吧:
添加Dockerfile
部署vue项目,其实就是起一个nginx服务即可,那配置Dockerfile文件就很简单了:
# 设置基础镜像FROM nginx# 定义作者MAINTAINER nine# 将dist文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面COPY dist/ /usr/share/nginx/html/COPY nginx.conf /etc/nginx/nginx.confRUN echo "Asia/shanghai" > /etc/timezoneRUN echo 'echo init ok!!'
其中,第一个就是Build以后的dist目录,第二个就是当前nginx服务的配置文件,毕竟要起服务,要做相应的配置,比如要url重写,或者压缩什么的。
自定义nginx配置文件
直接上代码
worker_processes auto;events {worker_connections 1024;}http {include mime.types;default_type application/octet-stream;gzip on;gzip_min_length 5k;gzip_buffers 4 16k;gzip_comp_level 8;sendfile on;keepalive_timeout 600;client_max_body_size 20m;server {listen 80;server_name localhost;location / {root /usr/share/nginx/html;index index.html index.htm;try_files $uri $uri/ /index.html;}error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}}}
不要告诉我看不懂,主要注意下root根目录的地址要和Dockerfile一致,然后就是路由重写那句话,其他的就很简单。
配置.dockerignore(非必要)
目前就是去掉某些文件和文件夹,不过目前看来,如果按照我下边的方案,可能作用不大,因为还是会把node_modules打包进去,
如果你仅仅想把dist文件夹打包,那就需要换一种写法了,其实说白了,就是把Dockerfile文件放到dist文件夹下就行。
.DS_Storenode_modules# local env files.env.local.env.*.local# Log filesnpm-debug.log*yarn-debug.log*yarn-error.log*
pull代码服务器Git Pull好代码,这一步没什么好说的下载好代码后进入代码目录
# 进入代码目录$ cd /home/vue# 依赖手脚架$ npm install# 发布文件$ npm run build# 拷贝文件到dist目录下,dockerfile和nginx.conf,我这里是在dockerfile目录下放了这两个文件# 具体根据自己项目情况$ cp -r docker/dockerfile/* dist
构建镜像
# 进入打包好的发布文件目录$ cd dist/# 构建容器$ docker build -t admin/dev .
构建容器
# 构建容器$ docker run --name admindev -v /etc/localtime:/etc/localtime -itd -p 6000:80 admin/dev# -v /etc/localtime:/etc/localtime 这里是挂载服务器时间# -itd 生成容器返回ID,比起上面多了个d# -p 宿主机6000映射容器80端口
至此,前后端已经完成
本地打包创建容器,服务器发布
本地编译发布文件添加上dockerfile文件,本地进行Docker build,push(推) docker镜像到镜像仓库,服务器pull(拉)镜像,进行下一步创建容器
这个方案如果是个人的话,需要在开发环境安装Docker,本地都打包好,推送镜像到仓库,个人的话做这个有点多余其实本质就是把自己的电脑当服务器使用,最后服务器只是生成一下容器启动但这个方案在公司内还是比较常见的,公司发布组打包发布测试好的镜像统一推送分发,维护实施人员进行创建容器即可保持了镜像统一没有最好的方案,只有最适合,都是取舍
本地发布,服务器拉取创建发布
本地编译发布文件添加上dockerfile文件,拷贝到服务器进行下一步build镜像
这个方案的话,个人更没必要了公司内部的话,生成文件放到服务器,由实施运维人员去服务器打包等等,还有一点应用场景反正这三种方案,你懂什么原理即可,再怎么变,都万变不离其中1.获取代码 2.生成项目发布文件3.创建镜像 4.创建容器始终都是这四个步骤,只是不同的方式去实现这几个过程