北京规划建设 杂志 官方网站wordpress全站cdn教程

张小明 2026/1/14 1:12:21
北京规划建设 杂志 官方网站,wordpress全站cdn教程,wordpress免费插件,四川网络科技有限公司DockerNginxNode.js 全栈容器化部署 通过 Docker Compose 统一编排 Nginx、Node.js 服务#xff0c;实现前后端分离部署。前端使用 Unity WebGL 创建交互式界面#xff0c;后端基于 Node.js 提供 REST API 通信。重点讲解网络配置、反向代理策略、端口映射、跨域处理等实战中…DockerNginxNode.js 全栈容器化部署通过 Docker Compose 统一编排 Nginx、Node.js 服务实现前后端分离部署。前端使用 Unity WebGL 创建交互式界面后端基于 Node.js 提供 REST API 通信。重点讲解网络配置、反向代理策略、端口映射、跨域处理等实战中遇到的问题及解决方案为应用部署提供完整参考。当部署到部署到服务器的时候不知道服务的ip地址可以使用nginx代理服务然后使用请求的时候使用路径请求然后ngixn返回服务器信息。可以在nginx的docker-compose的环境配置中写好ip和端口这样就可以不修改conf文件了。docker配置项目路径docker_net_work_test/ # 项目根目录 ├── nginx/ # Nginx 服务目录 │ ├── html/ # WebGL 前端文件 │ │ ├── Build/ # Unity WebGL 构建输出 │ │ ├── StreamingAssets/ # Unity 流媒体资源 │ │ └── index.html # 入口 HTML 文件 │ ├── Dockerfile # Nginx 镜像构建文件 │ └── nginx.conf # Nginx 配置文件 ├── node/ # Node.js 后端服务目录 │ ├── node_modules/ # Node.js 依赖包 │ ├── .env # 环境变量配置 │ ├── app.js # Node.js 主应用文件 │ ├── Dockerfile # Node.js 镜像构建文件 │ ├── package.json # Node.js 项目配置 │ └── package-lock.json # 依赖锁文件 ├── docker-compose.nginx.yml # Nginx 服务编排配置 └── docker-compose.node.yml # Node.js 服务编排配置项目运行先运行node服务docker-compose -f docker-compose.node.yml up -d运行nginx服务docker-compose -f docker-compose.nginx.yml up -d前端页面http://主机IP:58231nodejs服务http://主机IP:13000/nodejs服务配置docker-compose.node.ymlservices:node:build:./node# 基于node目录下的 Dockerfile 构建镜像container_name:node-app# 容器运行时的名字ports:-13000:13000# 宿主机:容器 端口映射networks:-backend# 定义属于的网络名称 backend 网络networks:backend:name:backend-net# 网络名称app.js/******************************************************************** * - HTTP 13000 (/ /api/health) * 依赖npm i morgan cors dotenv *******************************************************************/require(dotenv).config();consthttprequire(http);constexpressrequire(express);constcorsrequire(cors);constmorganrequire(morgan);/* ------------------ 配置 ------------------ */constHTTP_HOSTprocess.env.HTTP_HOST||0.0.0.0;constHTTP_PORTprocess.env.HTTP_PORT||13000;constNODE_ENVprocess.env.NODE_ENV||development;/* ------------------ Express ------------------ */constappexpress();// CORS 配置if([localhost,development,dev].includes(NODE_ENV)){app.use(cors());console.log((本地调试)/(开发),使用跨域);}elseif([production,pro].includes(NODE_ENV)){console.log(生产环境不使用跨域);}else{app.use(cors());console.log(未知环境使用跨域);}// 日志中间件morgan.token(date,()newDate().toLocaleString(zh-CN));app.use(morgan(:method :url code:status contentLength:res[content-length] - :response-time ms :date));app.use(express.json());/* ------------------ 路由 ------------------ */app.get(/api/config,(req,res){console.log(headers:,req.headers);// 1. 优先用代理头letportreq.get(X-Real-Port)||req.get(X-Forwarded-Port);// 2. 代理头都没有 → 从 Referer 提取if(!port){constrefererreq.get(Referer);constmrefererreferer.match(/:(\d)\//);portm?m[1]:(req.secure?443:80);}constprotoreq.get(X-Forwarded-Proto)||req.protocol;consthostreq.get(X-Forwarded-Host)||req.get(Host);consthostWithPorthost.includes(:)?host:${host}:${port};constbaseUrl${proto}://${hostWithPort};res.json({success:true,baseUrl,host:hostWithPort,proto,environment:NODE_ENV});});// 请求方式测试使用apiapp.get(/api/health,(req,res)res.json({success:true,message:服务健康,environment:NODE_ENV,timestamp:newDate().toISOString()}));app.get(/,(req,res)res.json({success:true,message:HTTP 服务正常,environment:NODE_ENV,paths:{http:/,config:/api/config,health:/api/health,post:/post,put:/put,delete:/delete}}));app.post(/post,(req,res)res.json({success:true,method:POST,message:POST 通道正常,timestamp:newDate().toISOString(),body:req.body}));app.put(/put,(req,res)res.json({success:true,method:PUT,message:PUT 通道正常,timestamp:newDate().toISOString(),body:req.body}));app.delete(/delete,(req,res)res.json({success:true,method:DELETE,message:DELETE 通道正常,timestamp:newDate().toISOString()}));app.use((req,res)res.status(404).json({success:false,message:路由不存在,path:req.path}));/* ------------------ 创建 HTTP 服务器 ------------------ */consthttpServerhttp.createServer(app);/* ------------------ 启动 HTTP ------------------ */httpServer.listen(HTTP_PORT,HTTP_HOST,(){console.log( HTTP 服务 http://${HTTP_HOST}:${HTTP_PORT});console.log(⚡ 环境${NODE_ENV});console.log( 可用路由:);console.log(GET / - 服务状态);console.log(GET /api/config - 配置信息);console.log(GET /api/health - 健康检查);console.log(POST /post - POST 测试);console.log(PUT /put - PUT 测试);console.log(DELETE /delete - DELETE 测试);});DockerfileFROM node:22-alpine WORKDIR /app COPY app.js . RUN npm i express morgan cors dotenv EXPOSE 13000 CMD [node,app.js]使用node:22-alpine镜像拷贝node下的app.js到app文件夹下并安装包暴露端口是13000与docker-compose中的端口暴露的一致。并启动服务。package.json{ name: unity-webgl-server, version: 1.0.0, main: app.js, scripts: { start: node app.js, dev: nodemon app.js }, dependencies: { aedes: ^0.51.3, cors: ^2.8.5, dotenv: ^17.2.3, express: ^4.18.2, morgan: ^1.10.1, websocket-stream: ^5.5.2, ws: ^8.13.0 }, devDependencies: { nodemon: ^3.0.1 } }.envHTTP_HOST0.0.0.0 HTTP_PORT13000 # 应用配置localhost/development/production NODE_ENVlocalhostnginx配置配置ngixn并将html文件拷贝的到容器中使用外部的配置文件端口暴露58231对外8080使用docker内部的端口网络使用和node在同一个网络下。docker-compose.nginx.ymlservices:nginx:build:./nginx# 构建镜像container_name:nginx-webports:-58231:8080# 宿主机 58231 映射到容器 8080networks:-backend# 跟 node 同一网络networks:backend:name:backend-net#复用网络external:true# 不新建网络DockerfileFROM nginxinc/nginx-unprivileged:1.29.0-alpine3.22 COPY nginx.conf /etc/nginx/nginx.conf COPY html/ /usr/share/nginx/html/ USER root使用nginxinc/nginx-unprivileged:1.29.0-alpine3.22镜像可以使用自己的镜像。拷贝nginx.conf拷贝html文件使用root权限。nginx.confworker_processes 1; events { worker_connections 1024; } http { # 引入MIME类型映射表 include mime.types; default_type application/octet-stream; # 开启零拷贝发送文件 sendfile on; keepalive_timeout 65; # 虚拟主机配置 server { # 监听端口 listen 8080; # 服务绑定地址允许所有地址访问 server_name 0.0.0.0; # Docker容器内Node服务反向代理 location /docker_s/ { # 代理转发地址指向Docker内的node-app服务13000端口 proxy_pass http://node-app:13000/; # 传递客户端真实访问端口优先取上层Nginx的X-Real-Port无则用当前服务端口 proxy_set_header X-Forwarded-Port $http_x_real_port$server_port; proxy_set_header X-Real-Port $http_x_real_port$server_port; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # 直接使用nginx提供API配置信息 location /nginx_s/api/config { set $api_proto http; set $api_port 58231; set $api_env production; set $api_host $host:$api_port; # 设置响应头为JSON格式 add_header Content-Type application/json; return 200 { \ \success\:true, \ \baseUrl\:\$api_proto://$api_host\, \ \host\:\$api_host\, \ \proto\:\$api_proto\, \ \environment\:\$api_env\ \ }; } # 前端静态资源入口 location / { # 静态资源根目录 root /usr/share/nginx/html; # 默认索引文件 index index.html index.htm; # SPA路由兼容匹配不到文件时重定向到index.html try_files $uri $uri/ /index.html; } # # 5xx服务器错误页面配置 # error_page 500 502 503 504 /50x.html; # location /50x.html { # root html; # } } }location /docker_s/ {返回将请求反向代理到容器内部的服务器。这里要使用docker的容器名称 虽然在一个网络里面使用localhost会访问nginx的本机而不是访问的实际的服务。location /nginx_s/api/config {在nginx中直接返回因为有时候会获取不到服务的ip地址。unity代码unity 使用tmp使用unitybesthttpv3 进行网络通信。besthttpv3 不支持路由请求所以使用unitywebrequest请求获取服务地址然后在使用unitybesthttpv3进行请求。usingUnityEngine;usingUnityEngine.UI;usingUnityEngine.Networking;usingSystem.Collections;usingBest.HTTP;usingTMPro;namespaceAssets{internalclasshttp_test_unityrequest:MonoBehaviour{[SerializeField]publicTMP_InputFieldurlInputField_unity;[SerializeField]publicTMP_InputFieldurlInputField_besthttp;[SerializeField]publicButtonunityWebRequestButton;[SerializeField]publicButtonbestHttpRequestButton;[SerializeField]publicTMP_TextresponseText;privatevoidStart(){unityWebRequestButton.onClick.AddListener(()StartCoroutine(SendUnityWebRequest()));bestHttpRequestButton.onClick.AddListener(()StartCoroutine(SendBestHTTPRequest()));}privateIEnumeratorSendUnityWebRequest(){responseText.text$UnityWebRequest: 请求中...;using(UnityWebRequestrequestUnityWebRequest.Get(urlInputField_unity.text)){yieldreturnrequest.SendWebRequest();responseText.textrequest.result!UnityWebRequest.Result.Success?$UnityWebRequest错误:\n{request.error}\n{request.downloadHandler?.text}:$UnityWebRequest成功:\n{request.downloadHandler?.text};}}privateIEnumeratorSendBestHTTPRequest(){responseText.text$BestHTTP: 请求中...;boolrequestCompletedfalse;stringresult;newHTTPRequest(newSystem.Uri(urlInputField_besthttp.text),(req,res){resultresnull?请求失败响应为空:!res.IsSuccess?$BestHTTP错误:\n{res.Message}\n{res.DataAsText}:$BestHTTP成功:\n{res.DataAsText};requestCompletedtrue;}).Send();while(!requestCompleted)yieldreturnnull;responseText.textresult;}}}测试html代码!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleGET请求发送器/title /head body h1GET请求发送器/h1 div label forurlInput请输入请求路径:/label br input typetext idurlInput placeholder/api/ size40 value/api/ /div br button onclicksendGetRequest()发送GET请求/button brbr div idresponseArea h3响应结果:/h3 pre idresponseText等待请求.../pre /div script function sendGetRequest() { const urlInput document.getElementById(urlInput); const responseText document.getElementById(responseText); const path urlInput.value.trim(); if (!path) { responseText.textContent 错误: 请输入有效的路径; return; } console.log(请求路径:, path); responseText.textContent 正在请求: ${path}; // 直接获取响应不做任何状态判断 fetch(path) .then(response { console.log(响应状态:, response.status, response.statusText); console.log(响应URL:, response.url); // 无论什么状态码都返回响应文本 return response.text().then(text { return { status: response.status, statusText: response.statusText, headers: Object.fromEntries([...response.headers.entries()]), url: response.url, body: text }; }); }) .then(result { // 显示完整的响应信息 responseText.textContent 响应状态: ${result.status} ${result.statusText} 响应URL: ${result.url} 响应头: ${JSON.stringify(result.headers, null, 2)} 响应体: ${result.body}; }) .catch(error { responseText.textContent 请求异常: ${error.message}; }); } document.addEventListener(DOMContentLoaded, function() { document.getElementById(urlInput).value /api/; }); /script /body /html项目测试运行项目后访问http://localhost:58231/然后发送请求进行测试可以转到不同的location块。转发docker_s/api/health使用besthttpV3进行请求网络命令网络与容器关系命令$netbackend-net; write-host 网络名称: $net; docker network inspect $net -f {{range .Containers}}{{.Name}}{{println}}{{end}} | Where-Object { $_ -ne } | ForEach-Object { $cid docker ps -q --no-trunc --filter name$_; if ($cid) { write-host 容器名称: $_ 容器ID: $($cid.Substring(0,12)) } }可以查看网络下有那些容器。输出PS C:\Users\GoodCooking $netbackend-net; write-host 网络名称: $net; docker network inspect $net -f {{ra nge .Containers}}{{.Name}}{{println}}{{end}} | Where-Object { $_ -ne } | ForEach-Object { $cid docker ps -q --no-trunc --filter name$_; if ($cid) { write-host 容器名称: $_ 容器ID: $($cid.Substring(0,12)) } } 网络名称: backend-net 容器名称: node-app 容器ID: 53a5b8a00a08 容器名称: nginx-web 容器ID: e7ad62d8745b PS C:\Users\GoodCooking
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

温州建站模板搭建轻量应用服务器搭建网站

如何快速掌握猫抓Cat-Catch:网页媒体资源嗅探的完整指南 【免费下载链接】cat-catch 猫抓 chrome资源嗅探扩展 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 还在为无法保存在线视频、音频资源而烦恼吗?猫抓Cat-Catch作为一款功能…

张小明 2026/1/13 11:37:41 网站建设

遵义网站页设计制作文档下载免费网站

FaceFusion与Agility CMS集成:构建智能内容生成与高效分发体系 在流媒体内容爆炸式增长的今天,用户对视频质量、个性化和加载速度的要求达到了前所未有的高度。从短视频平台上的虚拟主播,到跨国企业发布的本地化广告,背后都离不开…

张小明 2026/1/13 11:09:36 网站建设

上海技术公司做网站施工企业安全培训心得体会100字

雷达降雨估计在水文学中的应用 雷达降雨数据的优势与应用 雷达在测量降雨模式时,不仅能获取空间信息,还能记录随时间的变化。每次雷达旋转,都会得到更新后的降雨模式。将这些数据按时间序列排列,就能描绘出风暴的演变过程,包括其增强、衰减,以及接近、经过和离开感兴趣…

张小明 2026/1/13 19:04:07 网站建设

海南住房建设厅定额网站线上推广产品

当 idf.py 不再是文件:一文讲透 ESP-IDF 升级后路径失效的根源与破局之道 你有没有在某次更新完 ESP-IDF 后,突然发现原本好好的项目构建脚本崩了?终端里赫然跳出这行红字: the path for esp-idf is not valid: /tools/idf.py …

张小明 2026/1/13 20:22:27 网站建设

蚌埠网站建设文章域名备案迁移

文章目录一、锁的基本概念:为什么需要锁?二、锁的分类体系三、核心锁机制深度剖析1. 悲观锁 vs 乐观锁2. synchronized的锁升级过程3. 读写锁(ReadWriteLock)4. 自旋锁四、数据库锁机制1. 行锁 vs 表锁2. 间隙锁(Gap L…

张小明 2026/1/4 10:25:45 网站建设

海南网站制做的公司网站顶部下拉广告代码

您的组织是否有能力防御日益增多的网络攻击?渗透测试是评估组织 IT 和安全基础设施的最佳方法之一,因为它可以识别网络和系统中的漏洞。未修补的漏洞是对网络犯罪分子的公开邀请。 美国国家标准与技术研究院 (NIST) 2021 年发现了 4,068 个高风险漏洞。…

张小明 2026/1/14 1:08:02 网站建设