带你从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
在我们的根目录下面创建这样一个文件,这个文件名字可以随便取
然后在里面编写逻辑
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脚本我们后面可以用到,这里就记住是让服务器去执行拉取镜像以及执行启动容器的。
当我们做到这一步之后,我们提交代码的时候,应该会出现这样的情况
因为还没有去配置ssh密钥,这个肯定跑不起来,看到我们上面ssh command里面有两个变量,就是我们要配置的,接下来我们去搞服务器。
服务器
最近双十一活动,买个服务器还是挺香的,我买的阿里云2核2g的99/年,买的时候选操作系统,随便一个都可以,我因为对ubuntu熟悉一下,就买了ubuntu操作系统的,买好之后,记得重置密码
后面我们用shell工具连接的时候需要用到密码的
之后我们去下载一个shell工具,连接服务器用的,常见的有xshell finalshell,我用的第二个。
就傻瓜式安装,下一步就可以,然后我们去连接一下服务器,去下载宝塔。
第二步那里选择ssh连接就可以了,然后主机就是你的服务器公网ip,密码就是刚刚的,用户名就是root
连接上了之后,去下载宝塔,这个是ubuntu的命令,其他的操作系统有差别,可以去搜一下就有
wget -O install.sh http://download.bt.cn/install/install-ubuntu_6.0.sh && sudo bash install.sh
下载好之后输入bt default命令就可以打开了
因为宝塔是个可视化操作面板,比较方便,所以先弄好。
接下来我们去搞服务器密钥
我们在这里创建好密钥对,记得它只有一次机会,所以下载好了记得保存在你记得住的地方,然后创建好,记得要绑定,不然没效果,然后我们就要得用ssh密钥来连接服务器了
至此,我们的服务器也弄好了
github绑定密钥
这个是settings界面的,然后大家按照步骤创建就可以,到这里我们的配置就结束了。
创建shell脚本
我们上面不是说了,我们要写一个bash文件吗,现在就要来写,这个bash文件我们要执行拉镜像和跑容器
我们可以选择在宝塔中操作
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肯定找不到
我们来上手操作
这是我现在在跑的容器,我要找到我的后端项目对应的容器id,进去执行命令
docker exec -it <容器id> /bin/sh
跑这个我们就可以在容器内部执行命令
然后就可以把表结构同步过去了,我们也可以在生成Dockerfile的时候写迁移命令也是可以的,这样就不用手动同步了
数据库导出
我们需要将本地的数据迁移上去,需要先导出sql文件,这个就不用在这里展开说了,很简单,不会可以去找个博客教程,不到30s就完了,导出后我们需要将那个sql文件
然后我们在宝塔操作,找到你正在运行的mysql容器目录
将你的sql文件上传上去,放哪里都无所谓,记得路径就行
然后我们进入mysql容器里面,跑上面的那个命令
- 登录账号
mysql -u root -p
- 输入密码 ******* 输入你数据库连接的那个密码
- 进入之后
USE <database_name>
就选中了那张表 - 然后执行
source 刚刚的那个sql文件路径
这样操作数据就同步上去了,注意,数据同步前是一定要有表结构的,所以有先后顺序,这个地方注意。
也可以用这个命令, 将sql文件拷贝到你的容器内,然后跑上面的步骤,看个人喜好了。docker cp /本地路径/your_file.sql 容器名称:/容器路径/your_file.sql
到这里我们的部署就结束了,等项目正式上线的时候,还有其他注意点还会再写一篇博客的
最后
项目是跟着开头提到的小付大佬学习的,主要想学下react,没想到是个全栈项目,就用nestjs写了后端,也学到了很多前端,后端,部署的知识,强烈推荐大家可以去看看。最后 觉得不错的话,可以给个点赞加关注😘
来源:juejin.cn/post/7299859799780655155