注册
web

带你从0到1部署nestjs项目

前言


最近跟着一个掘金大佬做了一个全栈项目,前端react,后端我是用的nest,大佬用的midway


大佬博客地址(前端小付 的个人主页 - 动态 - 掘金 (juejin.cn)


最近项目也是部署上线了,因为域名还没备案,地址就先不发出来了,这篇文章就讲讲如何部署。一直有兄弟问prisma如何部署,这篇文章就帮你扫清障碍,文章可能比较长,希望耐心看完


后端技术栈



  • nestjs
  • mysql
  • redis
  • minio
  • prisma

部署需要掌握的知识



  • docker
  • github actions
  • 服务器

实战


nestjs打包镜像


我们部署的时候用的docker,docker需要拉镜像,然后生成容器,docker的知识可以去学习下,这里就默认大家会了,我们在打包的时候要写Dockerfile文件,后端项目是需要保留node_modules的,所以打包的时候一起打进去,我的项目用的pnpm包管理工具,我的文件挂载时有点点问题,我就没有用pm2去执行多阶段打包,多阶段打包速度会比较快,还有就是比如开发环境的依赖可以不打,当然这都是优化的地方,暂时没有去做,大家可以自行尝试


# 因为我们项目使用的是pnpm安装依赖,所以找了个支持pnpm的基础镜像,如果你们使用npm,这里可以替换成node镜像
# FROM nginx:alpine
FROM gplane/pnpm:8 as builder

# 设置时区
ENV TZ=Asia/Shanghai \
DEBIAN_FRONTEND=noninteractive
RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} > /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata && rm -rf /var/lib/apt/lists/*

# 创建工作目录
RUN mkdir -p /app

# 指定工作目录
WORKDIR /app

# 复制当前代码到/app工作目录
COPY . ./

RUN npm config set registry https://registry.npm.taobao.org/
# pnpm 安装依赖
COPY package.json /app/package.json

RUN rm -rf /app/pnpm-lock.yml
RUN cd /app && rm -rf /app/node_modules && pnpm install

RUN cd /app && rm -rf /app/dist && pnpm build

EXPOSE 3000
# 启动服务
CMD pnpm run start:prod


这样后端镜像就构建好了,接下来去编写github action的文件,github actions是做ci/cd的,让我们每次的部署走自动化流程,不要每次手动去做这些工作


github actions


在我们的根目录下面创建这样一个文件,这个文件名字可以随便取


12.png


然后在里面编写逻辑


name: Docker

on:
push:
branches: ['main']

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Setup Docker buildx
uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf

- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-

- name: Log int0 registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new

- name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache

- name: SSH Command
uses: D3rHase/ssh-command-action@v0.2.1
with:
HOST: ${{ secrets.SERVER_IP }}
PORT: 22
USER: root
PRIVATE_SSH_KEY: ${{ secrets.SERVER_KEY }}
COMMAND: cd /root && ./run.sh

这里的['main']就是我们要执行哪个分支,你不是main分支,那就改成你的分支就可以,其他都是固定的模板,直接用


SSH Command 这个是我们取做ci/cd的时候,每次我们提交代码,然后配置了ssh密钥,就可以让服务器执行run.sh命令,这个shell脚本我们后面可以用到,这里就记住是让服务器去执行拉取镜像以及执行启动容器的。


当我们做到这一步之后,我们提交代码的时候,应该会出现这样的情况


13.png


因为还没有去配置ssh密钥,这个肯定跑不起来,看到我们上面ssh command里面有两个变量,就是我们要配置的,接下来我们去搞服务器。


服务器


最近双十一活动,买个服务器还是挺香的,我买的阿里云2核2g的99/年,买的时候选操作系统,随便一个都可以,我因为对ubuntu熟悉一下,就买了ubuntu操作系统的,买好之后,记得重置密码


14.png


后面我们用shell工具连接的时候需要用到密码的


之后我们去下载一个shell工具,连接服务器用的,常见的有xshell finalshell,我用的第二个。


15.png


就傻瓜式安装,下一步就可以,然后我们去连接一下服务器,去下载宝塔。


16.png


第二步那里选择ssh连接就可以了,然后主机就是你的服务器公网ip,密码就是刚刚的,用户名就是root


连接上了之后,去下载宝塔,这个是ubuntu的命令,其他的操作系统有差别,可以去搜一下就有


wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh


下载好之后输入bt default命令就可以打开了


17.png


因为宝塔是个可视化操作面板,比较方便,所以先弄好。


接下来我们去搞服务器密钥


18.png


我们在这里创建好密钥对,记得它只有一次机会,所以下载好了记得保存在你记得住的地方,然后创建好,记得要绑定,不然没效果,然后我们就要得用ssh密钥来连接服务器了


20.png


至此,我们的服务器也弄好了


github绑定密钥


21.png


这个是settings界面的,然后大家按照步骤创建就可以,到这里我们的配置就结束了。


创建shell脚本


我们上面不是说了,我们要写一个bash文件吗,现在就要来写,这个bash文件我们要执行拉镜像和跑容器


23.png


我们可以选择在宝塔中操作


docker-compose pull && docker-compose up --remove-orphans

然后我们在同目录下也就是root目录下面新建一个docker-compose.yml文件,来启动容器的,这个文件就不要展示了,也就是创建了哪些服务,挂载哪些卷,如果有需要评论区说一下就行,很简单,因为我们用了很多服务,mysql redis minio nginx 这些多镜像,就得多个容器来跑,docker-compose无疑就好


到这里后端项目就部署完了,我们还得迁移数据库对吧


数据库部署


pirsma迁移

因为我用的mysql和prisma,typeorm思路差不多,可以一样用。我们的prisma以及typeorm迁移的时候只可以同步表结构,数据不会同步过去,所以我们跑迁移命令的时候,跑完会发现没有数据,我们需要手动导入数据


另外注意点,我们docker-compose.yml里面的mysql容器名字对应我们连接的主机名,这里记得更改prisma连接,不然你的prisma还连接在localhost肯定找不到


我们来上手操作


24.png


这是我现在在跑的容器,我要找到我的后端项目对应的容器id,进去执行命令


docker exec -it <容器id> /bin/sh 跑这个我们就可以在容器内部执行命令


25.png


然后就可以把表结构同步过去了,我们也可以在生成Dockerfile的时候写迁移命令也是可以的,这样就不用手动同步了


数据库导出

我们需要将本地的数据迁移上去,需要先导出sql文件,这个就不用在这里展开说了,很简单,不会可以去找个博客教程,不到30s就完了,导出后我们需要将那个sql文件


然后我们在宝塔操作,找到你正在运行的mysql容器目录


26.png


将你的sql文件上传上去,放哪里都无所谓,记得路径就行


然后我们进入mysql容器里面,跑上面的那个命令



  1. 登录账号 mysql -u root -p
  2. 输入密码 ******* 输入你数据库连接的那个密码
  3. 进入之后 USE <database_name> 就选中了那张表
  4. 然后执行 source 刚刚的那个sql文件路径

这样操作数据就同步上去了,注意,数据同步前是一定要有表结构的,所以有先后顺序,这个地方注意。


也可以用这个命令, 将sql文件拷贝到你的容器内,然后跑上面的步骤,看个人喜好了。
docker cp /本地路径/your_file.sql 容器名称:/容器路径/your_file.sql


到这里我们的部署就结束了,等项目正式上线的时候,还有其他注意点还会再写一篇博客的


最后


项目是跟着开头提到的小付大佬学习的,主要想学下react,没想到是个全栈项目,就用nestjs写了后端,也学到了很多前端,后端,部署的知识,强烈推荐大家可以去看看。最后 觉得不错的话,可以给个点赞加关注😘


作者:西檬
来源:juejin.cn/post/7299859799780655155

0 个评论

要回复文章请先登录注册