【Hono】部署篇 Docker+pm2部署

news2025/1/12 2:42:22

项目开发完后,要部署到服务器上才能正常使用,这里我分享一下dockerpm2两种方式的部署。

以下经验来自于我日常的折腾中,适合入门,非企业级操作,仅用于分享!

Docker部署

docker的话,也算有两种运行方式。

先在本地build,然后打tag,然后push上去。

把包发布到dockerhub或你的对应的云服务商的容器镜像服务上(比如阿里云)后

一种是使用docker run 附带一些参数进行启动

另一种使用docker-compose.yml配置参数,用docker compose命令重新拉取最新的镜像并重启。

Dockerfile

这个dockerfile来自Bun的官方,然后我又加了一些自己的需求,可以做一下参考

# use the official Bun image
# see all versions at https://hub.docker.com/r/oven/bun/tags
FROM oven/bun:1 AS base
WORKDIR /usr/src/app

# install dependencies into temp directory
# this will cache them and speed up future builds
FROM base AS install
RUN mkdir -p /temp/dev
COPY package.json bun.lockb /temp/dev/
RUN cd /temp/dev && bun install --frozen-lockfile

# install with --production (exclude devDependencies)
RUN mkdir -p /temp/prod
COPY package.json bun.lockb /temp/prod/
RUN cd /temp/prod && bun install --frozen-lockfile --production

# copy node_modules from temp directory
# then copy all (non-ignored) project files into the image
FROM base AS prerelease
COPY --from=install /temp/dev/node_modules node_modules
COPY . .

# [optional] tests & build
ENV NODE_ENV=production
# RUN bun test
RUN bun run build

# copy production dependencies and source code into final image
FROM base AS release

# 一个后端node/bun服务运行,必须需要node_modules
# 以及打包后的入口
# 如果存在环境变量配置, 还需要复制环境变量配置文件
COPY --from=install /temp/prod/node_modules node_modules
COPY --from=prerelease /usr/src/app/out/index.js .
COPY --from=prerelease /usr/src/app/package.json .
COPY --from=prerelease /usr/src/app/.env .
COPY --from=prerelease /usr/src/app/.env.production .

# 此处是为了把日志和数据库持久化, 方便备份和查看
# 创建日志目录和数据库目录
RUN mkdir -p /usr/src/app/prod-logs && chmod -R 777 /usr/src/app/prod-logs
RUN mkdir -p /usr/src/app/db && chmod -R 777 /usr/src/app/db

ENV NODE_ENV=production
# run the app
USER bun
EXPOSE 4775/tcp
ENTRYPOINT [ "bun", "run", "index.js" ]

有几个dockerfile内需要注意的点:

  • 如果你有env文件,记得也把env复制进去

  • 如果你的日志等文件持久化了(放在了一个自定义的目录下),记得分配读写权限

  • 记得设置ENV NODE_ENV=xxx

  • 分阶段构建不是必须的

另外,dockerfile中用到了bun run build这个命令

要注意,bun build 需要指定 --targetbun

"scripts": {
    "dev": "bun run --hot src/index.ts",
    "build": "bun build src/index.ts --outdir out --target=bun"
  },

编写完dockerfile以及打包命令后,没必要去服务器验证,可以在本地验证。

docker build ./ -t your_name --load

打包后,直接在docker desktop中点击运行,输入你自定义的端口号、本地挂载路径等就可以了。

如果有错误的话,就直接在desktop看日志,解决完明显的问题后再往服务器上发。

但是如果很多类似:端口号、挂载地址、环境变量需要配置时,光在开始这一步就会感觉非常麻烦。所以还是配一个docker compose比较方便

Docker Compose

小水管服务器最好还是不要在服务器上跑**docker build** ,真是很容易就卡死。

在项目根目录下新建docker-compose配置文件

docker-compose.prod.yml

version: '3.8'
# 正式服务器打包
services:
  hono:
    container_name: 'hono'
    # 填写发布后的镜像
    image: 'xxxxxxx'
    ports:
      - '4775:4775'
    restart: on-failure
    volumes:
      - /home/db/hono:/usr/src/app/db
      - /home/log/hono:/usr/src/app/prod-logs

在配置文件内写好所有的配置,很直观。

如果是在本地的话可以再新建一个

docker-compose.dev.yml

version: '3.8'
# 开发环境测试打包
services:
  hono:
    container_name: 'hono'
    build:
      context: ./
      dockerfile: ./Dockerfile
    ports:
      - '4775:4775'
    restart: on-failure
    volumes:
      - /Users/your_name/your_dir/databases/hono-db:/usr/src/app/db
      - /Users/your_name/your_dir/databases/hono-logs:/usr/src/app/prod-logs

使用本地的dockerfile来打包验证

docker-compose up

这样就不用重复敲很多配置了。

测试没问题,可以正常运行后,就可以去发布了

发布到容器镜像服务

在各家的云服务商的后台,都可以找到各自的容器镜像服务。

因为dockhub被墙了,直接在大陆的服务器上是拉不下来dockhub的镜像的,所以要想分版本的发布,就需要用云服务商自己的容器镜像服务。

以下以阿里云为例。

登录

sudo docker login --username=<your username> registry.cn-beijing.aliyuncs.com

注意:后面的地址registry.cn-beijing.aliyuncs.com,可以在你的阿里云后台找到

打包

打包的时候也有一个坑,就是要注意服务器的platform,在本地打包和push前就要加上参数。 比如我这里是linux/amd64。(你可以先不管,等在服务器上运行时,会提示你报错信息,然后再根据提示加上platform参数重新打包发布也可以。)

docker buildx build ./ -t your_name --load --platform linux/amd64 (对应阿里云ubuntu服务器)

打Tag

打标签前,需要在阿里云控制台里,先创建好自己的命名空间,假设我这里是zzstudio1

docker tag memoz registry.cn-beijing.aliyuncs.com/zzstudi1/your_name:latest

发布

docker push --platform linux/amd64 registry.cn-beijing.aliyuncs.com/zzstudi1/your_name:latest

此时本地操作已经完成,登录到云服务器再去拉取和运行发布好的镜像

不得不说,有墙是真难受,万一有网络问题,还容易卡住。

发布成功后,再去回头看我们docker-compose.prod.yml的配置的image,就是此时发布的镜像了。

只要这个docker-compose.prod.yml文件在服务器上,就可以运行起来了。后续如果需要更新,则需要在本地重复上述的,打包、打Tag、发布流程

然后在服务器重启即可

# 先停止
docker-compose down 
docker-compose up --build -d

注意:docker compose是可以管理多个镜像的,如果你要同时使用redismysqlnginx等,都可以统一管理,详细使用可以看我这篇**《使用Docker Compose部署Nest应用》**,里面有详细的配置说明

小结一下

  1. 配置package.json中的build命令,注意--taget=bun
  1. 参考bun官方示例,编写Dockerfile,构建,然后把项目打上版本号,打包发布到指定平台
  2. 服务器上只装docker,服务都使用docker运行
  3. 编写多个docker-compose.*.yml文件,配置不同环境的策略,拉取指定平台指定版本的镜像
  4. 后续使用docker compose命令进行更新和重新运行

再来看一下pm2部署有什么不同

PM2部署

使用pm2运行项目,需要在服务器安装相应的环境(BunPm2Git),后续有其他服务也使用pm2进行管理就可以了。

就是不像docker似的,环境隔离起来,换服务器方便一些。

但是国内这个环境其实用docker还麻烦一些,如果能一股脑丝滑的发步到dockerhub上就会轻松很多。

所以我一般如果选择了pm2部署,就相当于在服务器上安装了一圈环境(包括Nginx),配置过一遍后,后续使用git提交代码,提交代码后再通过ssh在服务器打包和重启一下对应服务。

以下是一些基本命令,安装node、bun、nginx等,且只在Ubuntu验证过。

安装node20.x版本

curl -sL https://deb.nodesource.com/setup_20.x -o nodesource_setup.sh
sudo bash nodesource_setup.sh

使用apt安装

sudo apt install nodejs

安装完成后验证

node -v
npm -v

安装bun,先安装unzip

sudo apt install unzip

再安装bun

curl -fsSL https://bun.sh/install | bash

设置国内镜像

npm config set registry https://registry.npmmirror.com/

安装PM2

npm install pm2@latest -g

使用ecosystem.config.js (在项目根目录下新建)(内容非常简单,在官网复制就可以)

pm2 start ecosystem.config.js

pm2 stop ecosystem.config.js

pm2 reload ecosystem.config.js

pm2 restart ecosystem.config.js

pm2 delete ecosystem.config.js


安装Nginx

sudo apt install nginx

systemctl status nginx
systemctl start nginx

配置防火墙

sudo ufw allow 'Nginx HTTP'
sudo ufw allow 'Nginx HTTPS'

主配置文件:/etc/nginx/nginx.conf

站点配置文件目录:/etc/nginx/sites-available/etc/nginx/sites-enabled

测试nginx配置

sudo nginx -t

重启nginx

sudo systemctl reload nginx

关于git建裸库,大家可以自行搜索相关文章,我也是按之前搜出来的一篇文章来建的,如果有懒得搜的,也可以直接私信我要教程。

最终,你的服务器上的项目文件夹内要具备:

  • node_modules 是的,后端项目不同于前端,也是需要node_modules才能正常运行的

  • package.json 用于安装和更新node_modules

  • env文件环境变量配置

  • 打包且压缩后的JS文件/文件夹,如:server/index.js

此时在你的服务器环境下运行就可以了

pm2 start ecosystem.config.js

而关于重启、多实例运行等都在一个config.js里配置

启动后,验证项目是否可以被正常请求,数据库读写是否正常,日常是否在正常记录就可以了

总结

对于我来说,选择其中一种方式部署,意味着后续其他服务都用这一种方式进行部署。

如果使用了docker,那我只在服务器上把docker装好,所有服务都通过docker来打包、分版本、发布、拉取、运行、重启。

如果使用了pm2,我会在服务器上直接装一遍NodeBunGitNginxpm2,后续通过git管理代码,通过git tag/branch或是代码内管理版本,ssh工具在服务器打包代码pm2来运行和重启。

当然有很多其他运维工具giteajenkins等等,我看过后感觉都不太适合我这种处于探索而非运营阶段的小水管服务器折腾。

如果真的有业务,着急搭建,我觉得花点钱找个靠谱的人弄都行,不用费这种心。

以上就是全部内容啦👏👏

更多文章,欢迎访问我的博客站

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2275259.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浏览器报错:您的连接不是私密连接,Kubernetes Dashboard无法打开

问题描述 部署完成Kubernetes Dashboard后&#xff0c;打开HTTPS的web页面&#xff0c;Chrome和Edge浏览器都无法正常加载页面&#xff0c;会提示您的连接不是私密连接的报错。 ​​​​​​​​​​​​ 原因&#xff1a; 浏览器不信任这些自签名的ssl证书&#xff0c;为了…

【Unity插件】解决移动端UI安全区问题 - Safe Area Helper

在移动端设计界面时&#xff0c;必须要考虑的就是UI的安全区。 Unity本身也提供了Safearea的API。 但在asset store时已经有人提供了免费的插件&#xff08;Safe Area Helper&#xff09;&#xff0c;我们可以直接使用。 插件链接&#xff1a; https://assetstore.unity.com/p…

ffmpeg7.0 aac转pcm

#pragma once #define __STDC_CONSTANT_MACROS #define _CRT_SECURE_NO_WARNINGSextern "C" { #include "libavcodec/avcodec.h" }//缓冲区大小&#xff08;缓存5帧数据&#xff09; #define AUDIO_INBUF_SIZE 40960 /*name depthu8 8s16 …

USRP X310 Windows 烧录镜像

说明 USRP-X 系列设备包含两个用于两个以太网通道的 SFP 端口。由于 SFP 端口支持 1 千兆 (SFP) 和 10 千兆 (SFP) 收发器&#xff0c;因此 UHD 附带了多个 FPGA 图像&#xff0c;以确定上述接口的行为。 注意&#xff1a;Aurora 图像需要从 FPGA 源代码手动构建。 FPGA 图像…

新型物联网智能断路器功能参数介绍

安科瑞刘鸿鹏 摘要 智能断路器作为现代配电系统的重要组成部分&#xff0c;以其实时监测、多重保护和远程操控的智能化功能&#xff0c;显著提升了电力系统的运行效率和安全性。本文以ASCB1系列智能断路器为例&#xff0c;探讨其技术特点和在工业、商业及民用建筑中的应用价…

119.使用AI Agent解决问题:Jenkins build Pipeline时,提示npm ERR! errno FETCH_ERROR

目录 1.Jenkins Build时的错误 2.百度文心快码AI智能体帮我解决 提问1&#xff1a;jenkins中如何配置npm的源 提问2&#xff1a;jenkins pipeline 类型为pipeline script from SCM时&#xff0c;如何配置npm源 3.最终解决方法-Jenkinsfile的修改 4.感触 1.Jenkins Build时…

pytest+allure 入门

使用allure如何生成自动化测试报​​​​​​告 &#xff1f;一文详解allure的使用 。_allure测试报告-CSDN博客 例子&#xff1a; import allure import pytest import osallure.epic("闹钟") allure.feature("闹钟增删") class TestSchedule():def setu…

【FPGA】时序约束与分析

设计约束 设计约束所处环节&#xff1a; 约束输入 分析实现结果 设计优化 设计约束分类&#xff1a; 物理约束&#xff1a;I/O接口约束&#xff08;例如引脚分配、电平标准设定等物理属性的约束&#xff09;、布局约束、布线约束以及配置约束 时序约束&#xff1a;设计FP…

【Vim Masterclass 笔记09】S06L22:Vim 核心操作训练之 —— 文本的搜索、查找与替换操作(第一部分)

文章目录 S06L22 Search, Find, and Replace - Part One1 从光标位置起&#xff0c;正向定位到当前行的首个字符 b2 从光标位置起&#xff0c;反向查找某个字符3 重复上一次字符查找操作4 定位到目标字符的前一个字符5 单字符查找与 Vim 命令的组合6 跨行查找某字符串7 Vim 的增…

win32汇编环境,窗口程序中对按钮控件常用操作的示例

;运行效果 ;win32汇编环境&#xff0c;窗口程序中对按钮控件常用操作的示例 ;常用的操作&#xff0c;例如创建按钮控件&#xff0c;使其无效&#xff0c;改变文本&#xff0c;得到文本等。 ;将代码复制进radasm软件里&#xff0c;直接就可以编译运行。重点部分加备注。 ;>&g…

继承(7)

大家好&#xff0c;今天我们继续来学习一下继承的知识&#xff0c;这方面需要大家勤动脑才能理解&#xff0c;那么我们来看。 1.9 protected关键字 在类和对象章节中&#xff0c;为了实现封装特性,java中引入访向限定符,主要限定:类或者类中成员能否在类外和其他包中被访问. …

基于RK3568/RK3588大车360度环视影像主动安全行车辅助系统解决方案,支持ADAS/DMS

产品设计初衷 HS-P2-2D是一款针对大车盲区开发的360度全景影像 安全行车辅助系统&#xff0c;通过车身四周安装的超广角像机&#xff0c;经算法合成全景鸟瞰图&#xff0c;通过鸟瞰图&#xff0c;司机非常清楚的看清楚车辆四周情况&#xff0c;大大降低盲区引发的交通事故。 产…

NVIDIA发布GeForce RTX 50 系列,售价549美元起

2025 CES消费电子展&#xff08;1月7日至10日&#xff0c;美国拉斯维加斯&#xff09;正式开幕。北京时间1月7日 (星期二)上午10:30&#xff0c;NVIDIA举办主题演讲&#xff0c;CEO黄仁勋担任主讲。正式发布了全新的RTX 50系列显卡&#xff01;一月下旬上市。同时公布了各版本的…

后端:Spring(IOC、AOP)

文章目录 1. Spring2. IOC 控制反转2-1. 通过配置文件定义Bean2-1-1. 通过set方法来注入Bean2-1-2. 通过构造方法来注入Bean2-1-3. 自动装配2-1-4. 集合注入2-1-5. 数据源对象管理(第三方Bean)2-1-6. 在xml配置文件中加载properties文件的数据(context命名空间)2-1-7. 加载容器…

基于EasyExcel实现通用版一对一、一对多、多层嵌套结构数据导出并支持自动合并单元格

接口功能 通用 支持一对一数据结构导出 支持一对多数据结构导出 支持多层嵌套数据结构导出 支持单元格自动合并 原文来自&#xff1a;https://blog.csdn.net/qq_40980205/article/details/136564176 新增及修复 基于我自己的使用场景&#xff0c;新增并能修复一下功能&#x…

【数据库】一、数据库系统概述

文章目录 一、数据库系统概述1 基本概念2 现实世界的信息化过程3 数据库系统内部体系结构4 数据库系统外部体系结构5 数据管理方式 一、数据库系统概述 1 基本概念 数据&#xff1a;描述事物的符号记录 数据库&#xff08;DB&#xff09;&#xff1a;长期存储在计算机内的、…

网络安全建设方案,信息安全风险评估报告,信息安全检测文档(Word原件完整版)

一、概述 1.1工作方法 1.2评估依据 1.3评估范围 1.4评估方法 1.5基本信息 二、资产分析 2.1 信息资产识别概述 2.2 信息资产识别 三、评估说明 3.1无线网络安全检查项目评估 3.2无线网络与系统安全评估 3.3 ip管理与补丁管理 3.4防火墙 四、威胁细…

数据分析工作流

数据分析工作流 1.流程 数据产生阶段 业务系统生成数据&#xff1a;在各种业务场景下&#xff0c;如用户在电商平台上进行购物&#xff08;产生订单信息、浏览记录等&#xff09;、在金融系统中进行交易&#xff08;产生交易流水、账户余额变动等&#xff09;或者在企业内部的…

【Go】:图片上添加水印的全面指南——从基础到高级特性

前言 在数字内容日益重要的今天&#xff0c;保护版权和标识来源变得关键。为图片添加水印有助于声明所有权、提升品牌认知度&#xff0c;并防止未经授权的使用。本文将介绍如何用Go语言实现图片水印&#xff0c;包括静态图片和带旋转、倾斜效果的文字水印&#xff0c;帮助您有…

PyQt5 UI混合开发,控件的提升

PromoteLabelTest.py 提升的类 import sys from PyQt5.QtWidgets import QApplication, QWidget,QVBoxLayout,QTextEdit,QPushButton,QHBoxLayout,QFileDialog,QLabelclass PromoteLabel(QLabel):def __init__(self,parent None):super().__init__(parent)self.setText("…