开发环境:桌面云系统(无法使用docker desktop),win10系统

后端开发工具:vs2022   数据库:mysql     缓存:redis    队列和事件处理:rabbitmq

前端开发工具:visual studio code    框架:vue

发布步骤

一、发布接口端.NET6 项目

  1.  由于不能运行docker desktop,所以发布的时候只能发布到文件夹,然后手动发布到docker,发布界面如下,注意下图红框选中处,这就是我踩的第一个坑,发布时我想着是发布到liunx系统,所以选择的是liunx-64,发布后才发现运行不了,报错内容为:

System.InvalidOperationException: Unable to resolve service for type '***.***.***' while attempting to activate '***.***.***'
错误意思就是加载dll文件失败,后面将目标运行时改为 可移植 然后重新发布,更新后,重新运行dcoker(docker restart 容器Id),问题解决

  2. dockerfile文件编写,dockerfile文件可以由系统自动生成,但是手动发布需要修改系统生成的dockerfile文件,因为手动发布已经生成了dll文件,不需要调用build命令再次生成

   下面是系统生成的dockerfile,包括了复制项目文件到对应文件夹和build生成dll文件

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["WebApi/Web/Web.csproj", "WebApi/Web/"]
COPY ["WebApi/AdminApi/AdminApi.csproj", "WebApi/AdminApi/"] RUN dotnet restore "WebApi/Web/Web.csproj"
COPY . .
WORKDIR "/src/WebApi/Web"
RUN dotnet build "Web.csproj" -c Release -o /app/build FROM build AS publish
RUN dotnet publish "Web.csproj" -c Release -o /app/publish FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Web.dll"]

  下面是我修改后的dockerfile文件,内容简洁很多,只保留了程序入口以及运行端口指定

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

#拷贝发布目录下的所有文件到容器的工作根目录,如果你的站点文件和dockerfile在同一个文件夹下面可以和下面一样否则要加上站点文件的目录 
  COPY ./ ./

#COPY fonts/ /usr/share/fonts/

ENV ASPNETCORE_ENVIRONMENT Development # 设置运行环境为开发环境,可选值为 Production、Development、Staging 默认值为Production
ENTRYPOINT ["dotnet", "Web.dll"]

  3. 将文件上传至centos系统,可用的工具有很多,我这边使用的工具是FinalShell,该工具支持界面操作,比其它工具操作要简单一些,比如修改配置文件可以在本地打开,然后直接修改保存,不需要在命令行里面云操作,同时也可以直接拖动文件到指定目录

  4. 创建镜像文件,文件上传后,进行文件所在目录,cd  文件目录 。然后使用以下命令 创建镜像文件  注意后面的 . 不能少

docker build -t 镜像名称:版本号 .

  5. 启动运行容器 ,使用下面的命令启动容器   其中8001是系统的端口号,80是容器  --restart=always 表示容器停止后自动重启(比如服务器重启了),如果运行容器时没有加这个参数,可以使用docker container update --restart=always 容器名字  来修改,  -e TZ=Asia/Shanghai  表示指定容器的时区,以免.net core获取的时间不正确  -v 是指定挂载目录/home/OnlineBusiness/dotnet_docker_test宿主机目录,--log-opt 是docker的日志生成参数 max-size=100m,是限制日志文件大小为100M max-file=10是指最多保留10个日志文件,超过的将删除 :后面的是docker应用内目录

docker run -d -p 8030:80 --name 容器名称 --restart=always -e TZ=Asia/Shanghai -d -v /home/OnlineBusiness/dotnet_docker_test:/app --log-opt max-size=100m --log-opt max-file=10 镜像名称:版本号

  6. 如果容器启动成功,可以使用docker ps查看运行中的容器,这时使用 服务器IP:端口号 及可访问系统,系统部署完成

  7. docker日志目录 /var/lib/docker/containers/容器ID/容器ID-json.log

  8. 踩到的坑

    坑一:上面已经说了,发布时选择目标运行时的问题,我这里改成可移植即可运行

    坑二:swagger运行不了,linux系统目录的问题导致swagger运行不了,根据错误信息查了一下是因为路径的问题,加载xml文件失败,导致swagger运行失败,liunx系统里面的路径要注意两点,1) 目录的分隔符与windows不一致,建议拼接路径是使用Path.DirectorySeparatorChar来获取分隔符,这样就不需要判断运行环境了,我这里swagger运行不了就是因为使用windows里面的目录分隔符。 2)获取当前目录,建议使用Directory.GetCurrentDirectory(),不要使用AppContext.BaseDirectory,这个方法在开发环境中获取到的是.dll文件所有目录

    坑三:ZKWeb.System.Drawing组件的使用,在liunx里面使用该 组件需要另外安装该组件,关键是我安装了也解决不了问题,解决方案见另外一篇博文https://www.cnblogs.com/ithome8/p/16423027.html,这里不再说明。

    坑四:rabbitmq的使用,当然这个和发布没有多大关系,是因为发布的站点和本地站点 使用同一个rabbitmq服务器时会报错,冲突了,访问同一队列,不使用同一个服务器就OK了。

二、发布前端VUE项目

  1. 进入CMD模式,并且进入项目的根目录 ,使用npm run build进行项目打包,也可以使用VSCode,在终端下面输入npm run build来进行打包,命令执行后文件会打包到vue.config.js文件中配置的outputdir指定的目录下面。

  2. 编写nginx config配置文件,内容如下,在项目发布的目录下面创建nginx/conf.d目录,将该文件保存到该 目录并且命名为default.conf,注意最好不要在中使用中文,否则可能会乱码

server {
listen 80;
listen [::]:80;
server_name localhost; # 测试vue history 模式下发布问题
# 方式一 一般选用方式二就可以
location / {
root /usr/share/nginx/html;
index index.html index.htm;
client_max_body_size 200m;
if (!-e $request_filename) {
rewrite ^/(.*) /index.html last;
break;
}
error_page 404 /404.html;
# To allow POST on static pages
error_page 405 =200 $uri;
}
# 此外,如果VUE应用没有发布在域名的目录根下,比如[http://xxx.com/wx/]
# 那么除了上述配置:
#location /wx{
# root /data/nginx/html; # 在linux下部署一般都是将路径配置完全
#root html;
#index index.html index.htm;
#error_page 404 /wx/index.html;
#if (!-e $request_filename) {
#rewrite ^/(.*) /wx/index.html last;
#break;
#}
#} # 方式二
#location / {
#try_files $uri $uri/ /index.html;
#}
# 配置反响代理接口的反响代理,这里是反向代理的接口配置,不然会访问不了接口
location ~ /admin/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #//利用正则进行匹配#去掉api前缀,$1是正则中的第一串,这样后端的接口也不需要带api了
rewrite ^/(.*)$ /$1 break;
#**//api前面的部分将被替换成localserver的地址**
proxy_pass http://172.16.19.155:8030;
}
# 配置反响代理接口的反响代理
location ~ /WebApi/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #//利用正则进行匹配#去掉api前缀,$1是正则中的第一串,这样后端的接口也不需要带api了
rewrite ^/(.*)$ /$1 break;
#**//api前面的部分将被替换成localserver的地址**
proxy_pass http://172.16.19.155:8030;
}
#access_log /var/log/nginx/host.access.log main; }

  3. 编写dockerfile文件,内容如下 ,也可以直接将文件上传到指定目录,后面的COPY命令就可以不用了

# 设置基础镜像
FROM nginx
# 将dist文件中的内容复制到 ./html/ 这个目录下面,./html/是nginx容器的默认文件目录
COPY dist/ ./html/
# 用本地的 default.conf 配置来替换nginx镜像里的默认配置,确认文件的路径是正确的
ADD conf.d/default.conf /etc/nginx/conf.d/

  4. 创建镜像文件,文件上传后,进行文件所在目录,cd  文件目录 。然后使用以下命令创建镜像文件  ,注意后面的 . 不能少

docker build -t 镜像名称:版本号 .

  5. 启动运行容器 ,使用以下代码 其中8001是系统的端口号,80是容器的端口号,如果要打开就是系统的 IP:8002

docker run --name=容器名称 -p 8002:80 -d 镜像名称:版本号  

  6. 至此VUE项目发布就完成了,下面说一下踩的坑

    坑一:发布后打开网站是一片空白,只有两个JS报错,通过查询知道了是什么原因,是配置文件vue.config.js里面没有指定publicPath,导致vue找不到目录,加上即可,代码如下

const urlConfig = require('./src/config/url') // 引入服务器路径配置

const path = require('path')
const resolve = (dir) => path.join(__dirname, dir)
module.exports = {
// 部署应用包时的基本 URL
publicPath: process.env.NODE_ENV === 'production' ? '/admin' : '/',
// 当运行 vue-cli-service build 时生成的生产环境构建文件的目录
outputDir: '../../publish/dist',
// 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录
assetsDir: 'static',
publicPath: './',

    坑二:接口调用报跨域错误,获取不到数据,在本地开发正常,是因为开发环境是使用的proxy做了代理转发,所以可以正常访问,下面这段代码会进行转发,所以在开发环境可以正常访问不会跨域    

  devServer: {
open: false,
host: '0.0.0.0',
port: 8031,
https: false,
hotOnly: false,
proxy: {
'/admin': {
target: urlConfig.proxyURL,
ws: false,
secure: false,
changeOrigin: true
}
},
before: () => { }
}

    解决方案,代码里面接口的访问地址仍然使用项目的访问地址,在nginx里面做配置,进行反向代理,跳转到接口的地址,配置代码如下

   # 配置反响代理接口的反响代理,这里是反向代理的接口配置,不然会访问不了接口
location ~ /admin/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #//利用正则进行匹配#去掉api前缀,$1是正则中的第一串,这样后端的接口也不需要带api了
rewrite ^/(.*)$ /$1 break;
#**//api前面的部分将被替换成localserver的地址**
proxy_pass http://***.***.***.***:8001;
}

在此记录一下,以免后面还遇到这些问题。。。

关于.net6项目发布到docker(nginx)踩到的一些坑的更多相关文章

  1. 使用jib-maven-plugin将Spring Boot项目发布为Docker镜像

    目录 介绍 使用 总结 介绍 将spring boot(cloud)项目发布到docker环境作为镜像,一般常用的一个是com.spotify的docker-maven-plugin这个maven插件 ...

  2. Linux环境下将.net6项目部署到docker

    1.创建一个ASP.NET Core Web应用(MVC) 注意点:建议不用勾选单选框"启用Docker(E)",因为勾选后,涉及到Docker-Desktop的安装,可能会引起本 ...

  3. Centos8 Docker部署 .Net6 项目

    .Net6项目发布 1.在VS中发布项目,并编写好Dockerfile文件 Dockerfile文件内容如下: FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS ...

  4. asp.netcore 3.0 Docker Nginx(震惊,原来docker是这样的!)

    引言 Docker发布于2013年,Docker是dotCloud公司创始人在法国期间发起的一个公司内部项目,他是dotCloud多年云技术的一个革新.Docker在容器基础上进行了一步的封装,从网络 ...

  5. jenkins+docker+k8s项目发布

    目录 一.简介 二.新建docker-build工程 三.项目部署 四.访问测试 一.简介 1.该章节基于jenkins.Harbor.pipeline.k8s来做发布,如对这些不熟悉,请按以下进入学 ...

  6. Taurus.MVC 微服务框架 入门开发教程:项目部署:4、微服务应用程序发布到Docker部署(上)。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 开源地址:https://github.com/cyq1162/Taurus.MVC 本系列第一篇:Tauru ...

  7. Taurus.MVC 微服务框架 入门开发教程:项目部署:5、微服务应用程序发布到Docker部署(下)。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 开源地址:https://github.com/cyq1162/Taurus.MVC 本系列第一篇:Tauru ...

  8. .NET Core部署到linux(CentOS)最全解决方案,高阶篇(Docker+Nginx 或 Jexus)

    在前两篇: .NET Core部署到linux(CentOS)最全解决方案,常规篇 .NET Core部署到linux(CentOS)最全解决方案,进阶篇(Supervisor+Nginx) 我们对. ...

  9. k8s:py项目发布完整流程

    k8s:py项目发布流程 1. 编写Dockerfile # cat Dockerfile FROM python:3.6-slim USER root RUN apt-get update & ...

  10. jenkins项目发布

    目录 一.简介 二.docker打包 一.后端打包 二.前端打包 三.启动容器 四.完整代码 五.发布测试 六.优化方案 七.源码地址: 八.参考 一.简介 1.该章节基于jenkins.Harbor ...

随机推荐

  1. jdbcTemplate之“rowMapper内部类写法”

    jdbcTemplate的rowMapper内部类写法 String sql ="select sku,feature from product"List<Product&g ...

  2. 智表ZCELL专业版授权说明

    专业版: 1.智表专业版按照部署地址授权,价格1680元.(IP或域名均可,授权时localhost会同步授权) 2.授权版本为智表专业版最新版本,不提供历史版本授权.授权为插件使用权,不提供源码. ...

  3. Seata源码—2.seata-samples项目介绍

    大纲 1.seata-samples的配置文件和启动类 2.seata-samples业务服务启动时的核心工作 3.seata-samples库存服务的连接池配置 4.Seata对数据库连接池代理配置 ...

  4. TVM Pass优化 -- 算子融合(FuseOps)

    定义 算子融合 就是将多个计算单元合并到一个计算单元里完成计算,减少中间数据读写内存的操作,从而节省计算时间. TVM中将算子融合分为四种: kElemWise:两个tensor之间按照元素逐个操作的 ...

  5. 定制Django的Tag和Filter(二)

    配置 (1)最常见的放置自定义Tag和Filter的地方是在Django的app下.当一个app被添加到settings.py的INSTALLED_APPS 后,任何在它下面的合法位置将自动的可在te ...

  6. 高德地图 MCP,可用 Java SolonMCP 接入(支持 java8, java11, java17, java21)

    1.MCP技术概述 1.1 什么是 MCP MCP (Model Control Protocol) 是一种允许大模型与外部工具交互的协议,高德地图基于此协议提供了地图服务能力,使 AI 大模型能够直 ...

  7. codeup之输出梯形

    Description 输入一个高度h,输出一个高为h,上底边为h的梯形. Input 一个整数h(1<=h<=1000). Output h所对应的梯形. Sample Input Co ...

  8. codeup之字符串比较

    Description 比较两个字符串s1和s2的大小,如果s1>s2,则输出一个正数:若s1=s2,则输出0:若s1<s2,则输出一个负数. 要求:不用strcpy函数:两个字符串用ge ...

  9. BAPI_RESERVATION_CHANGE 删除预留

    CLEAR: reservationitems[],reservationitems. CLEAR: reservationitemsx[],reservationitemsx,reservation ...

  10. AI Chat 智能聊天工具,支持DeepSeek 、Gemini、Grok、OpenAI和自定义AI

    AI Chat [中文]|[English] AI Chat 是一个智能聊天工具,支持DeepSeek .Gemini.Grok.OpenAI和自定义AI,使用SwiftUI.SwiftData开发, ...