我终于会用Docker了(nest+prisma+psotgresql+nginx+https)

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 这次自己有一个NestJS后端服务需要自己部署了,之前部署node服务可能更多是pm2那一套,自己的项目可以尝试各种各样的技术,所以这次就尝试一下早就想用的docker来实际部署一下本文会讲什么:对于docker的理解,docker必知必会的命令,以及最后是笔者的实战部署,和一些踩坑记录; 本文不会讲什么:docker更深层次的原理,即本文更多是一篇应用性文章,欢迎继续阅读后续章节;

我终于会用Docker了(nest+prisma+psotgresql+nginx+https)

前言


这次自己有一个NestJS后端服务需要自己部署了,之前部署node服务可能更多是pm2那一套,自己的项目可以尝试各种各样的技术,所以这次就尝试一下早就想用的docker来实际部署一下

本文会讲什么:对于docker的理解,docker必知必会的命令,以及最后是笔者的实战部署,和一些踩坑记录; 本文不会讲什么:docker更深层次的原理,即本文更多是一篇应用性文章,欢迎继续阅读后续章节;

基本概念介绍


简介

如果是计算机专业的学生,那么是肯定学过操作系统的,而学这门课程有一门操作系统实验,需要自己在linux上通过模拟器再运行一个非常低版本的linux,笔者隐约记得好像是0.11那个版本,因为这个版本代码相对来说都是比较核心主要的功能,用来学习是非常不错的。

在操作系统运行一个可以运行其他环境的"系统环境",这不就是Docker的概念吗。或者如果你没有上述的经历,那总在本机运行过VM吧,甚至说win11中的wsl总知道吧。

基本概念就是这个:在linux系统上运行一个"系统环境",官方叫做容器。

那这个所谓的"系统环境"可以做什么呢,当然是运行一些我们常用的东西,如node、mysql、redis以及我们自己的应用程序等。

图片来源

优点

好,问题又来了,为什么不直接在该linux系统上运行这些环境:这个问题用Docker的主要优势就能回答:

1)简化应用程序部署和依赖管理

Docker是将应用程序和其依赖项打包在一个容器中,避免了复杂的依赖管理和手动安装,因此可以快速部署和更新应用程序。

怎么理解:

  • python打包exe用过吧:它会将其依赖的所有环境一起打包最后成为一个可执行文件,形成了这样一个可执行文件,是不是用户只需要双击就能打开,不需要像程序员一样安装各种复杂的依赖
  • 前端的electron用过吧:它也将应用程序与浏览器环境打包在一起了,用户也可以直接使用你的应用程序了
  • 这么理解:有了它,我们就可以直接把这个"软件包"进行部署,而没有它,我们就需要到用户的主机,去干什么pip install之类的,真累~

2)跨平台和环境可移植性

Docker容器可以在任何操作系统、云平台和虚拟化环境中运行,保证了应用程序在不同环境下的稳定性和可靠性。

也是第一点所讲到的,既然都打包成了一个软件包,那么就可以非常方便地运行在各个环境之中了:

  • 想想Java虚拟机JVM,Java刚出的时候主打的就是一个可移植性,其就是通过先编译成字节码,也就是那个.class文件,然后该文件就可以在任何安装了JVM的系统上运行了。
  • Docker也是,只要该环境安装了Docker,那么由其打包的"软件包"也就能直接运行了

一些关键词及概念


想入门某个领域,第一步就是得先了解该领域特有的关键热词,下面是Docker中常用的一些关键词及概念简介:

  1. Docker镜像(Image): Docker镜像是一个轻量级的、可移植的、自包含的软件包,其中包含了运行某个应用程序所需的所有文件、配置和依赖项。
  2. Docker容器(Container): Docker容器是由Docker镜像创建的运行实例,容器中包含了所有运行应用程序所需的文件、配置和依赖项,以及运行时环境。

镜像与容器的概念就和程序与进程的概念是一致的,一个是乐谱,另外一个就是正在演奏的音乐了

  1. Docker仓库(Registry): Docker仓库是一个用于存储和共享Docker镜像的中央存储库,Docker Hub是一个公共的Docker仓库。
  2. Dockerfile: Dockerfile是一个文本文件,其中包含了一组指令,用于自动化构建Docker镜像。就和C语言中的Makefile差不多。
  3. Docker Compose: Docker Compose是一个工具,用于定义和运行多个Docker容器组成的应用程序,并管理它们之间的交互。
  4. Docker网络(Network): Docker网络是一种机制,用于在多个Docker容器之间建立网络连接,以实现容器之间的通信。
  5. Docker数据卷(Volume): Docker数据卷是一种机制,用于在Docker容器和主机之间共享数据。
  6. Docker daemon:是Docker的核心组件之一,也称为Docker引擎。它是一个长期运行的后台进程,负责管理Docker镜像、容器、网络和存储卷等资源。

图片来源

相关概念如果不理解也没关系,后续实战时看看这些东西到底长啥样,就自然而然就明白了

常用命令



这里简单索引并介绍一下笔者自己常用的一些关于docker及docker-compose相关的命令,希望对你所有帮助:image.png

Docker与Docker-compose:构建镜像image.png

一般一个Dockerfile对应一个容器,如果我们要部署多个容器,就需要每次运行各个不同的Dockerfile,为了简化docker的复杂操作,就有了dcoekr-compose,它就可以在其yml文件上写多个镜像进行部署容器

还有就是这里有一个shell脚本,后续会使用该setup.sh,作用就是每次更新部署时在对应目录运行就可以了:

#!/usr/bin/env bash
#image_version=`date +%Y%m%d%H%M`;
# 关闭容器
docker-compose stop || true;
# 删除容器
docker-compose down || true;
# 构建镜像
docker-compose build;
# 启动并后台运行
docker-compose up -d;
# 查看日志
docker logs nodejs;
# 对空间进行自动清理
docker system prune -a -f


实战


现在,你已经了解了Docker的相关概念以及Docker的一些常用操作了,下面就进入实战让你练练手并加深理解。

我的项目文件目录如下:

nest-api
├─ .dockerignore
├─ .eslintrc.js
├─ .github
│  └─ workflows
│     └─ ci.yml
├─ .gitignore
├─ .graphqlconfig
├─ .node-version
├─ .prettierrc.json
├─ .vscode
│  └─ extensions.json
├─ docker-compose.db.yml
├─ docker-compose.migrate.yml
├─ docker-compose.yml
├─ Dockerfile
├─ Dockerfile.alpine
├─ LICENSE
├─ nest-cli.json
├─ package-lock.json
├─ package.json
├─ pull-env.sh
├─ .env
├─ README.md
├─ run.sh
├─ setup.sh
├─ src[略]
略...


prisma+nest应用的Dockerfile

编写自己的NestJS应用需要的Dockerfile:

FROM node:16-alpine AS builder
# Create app directory
WORKDIR /app
# A wildcard is used to ensure both package.json AND package-lock.json are copied
COPY package*.json ./
COPY prisma ./prisma/
# Install app dependencies
RUN npm install
COPY . .
RUN npm run build
FROM node:16-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD [ "npm", "run", "start:prod" ]


这些英文单词都是一看就差不多懂得命令这里就不过多赘述了,其中FROM node:16-alpine代表该镜像继承自node镜像,毕竟是个node应用嘛;apline版本更加轻量,打包体积更小,一般来说不去编写哪些C++扩展都是够用的。

图片来源

nest应用+postgresql+niginx的yml配置

此时相当于我们就有我们自己应用的镜像文件了,但其依赖的环境还没有,比如postgresql;还有就是我需要的nginx,这些都是有现成的,所以就不用自己构建了,直接使用;但想要将它们弄在一起,就需要编写docker-compose.yml文件,如下:


version: '3.8'
services:
  nest-api:
    container_name: nest-api
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - '3000:3000'
    depends_on:
      - postgres
    env_file:
      - .env
  postgres:
    image: postgres:13
    container_name: postgres
    restart: always
    ports:
      - '5432:5432'
    env_file:
      - .env
    volumes:
      - postgres:/var/lib/postgresql/data
  nginx:
    image: nginx:stable-alpine      # 指定服务镜像
    container_name: nginx    # 容器名称
    restart: always                 # 重启方式
    ports:                          # 映射端口
      - "80:80"
      - "443:443"
    volumes:                        # 挂载数据卷
      - /etc/localtime:/etc/localtime
      - /home/ubuntu/work/nginx/conf.d:/etc/nginx/conf.d
      - /home/ubuntu/work/nginx/logs:/var/log/nginx
      - /home/ubuntu/work/nginx/cert:/etc/nginx/cert
    depends_on:                     # 启动顺序
      - nest-api
volumes:
  postgres:
    name: nest-db


其中volumes的意思就是让容器中的某个文件与操作系统中的某个文件进行对应,从而做到持久化存储。

配置niginx

上述中的:

      - /home/ubuntu/work/nginx/conf.d:/etc/nginx/conf.d
      - /home/ubuntu/work/nginx/logs:/var/log/nginx
      - /home/ubuntu/work/nginx/cert:/etc/nginx/cert


冒号前面的路径是我自己在操作系统环境中创建的路径,你也可以根据自己的习惯进行创建,然后对应到容器的路径就可以了

1)conf.d配置

vim /home/ubuntu/work/nginx/conf.d/default.conf


该文件内容如下:

server {
  listen 443 ssl http2;
  server_tokens off;
  root /var/www/html;
  index index.html index.htm;
  # 修改为自己的域名
  server_name api.example.com;
  client_max_body_size 4M;
  # ssl证书存放位置
  ssl_certificate /etc/nginx/cert/api.example.com.pem;
  ssl_certificate_key /etc/nginx/cert/api.example.com.key;
  ssl_session_timeout 5m;
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  # 访问 / 路径时执行反向代理
  location / {
    # 这里 nodejs 是 node 容器名
    proxy_pass http://nest-api:3000;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    # 后端的Web服务器可以通过 X-Forwarded-For 获取用户真实 IP
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    # 允许客户端请求的最大单文件字节数
    client_max_body_size 15M;
    # 缓冲区代理缓冲用户端请求的最大字节数
    client_body_buffer_size 128k;
  }
}
server {
   listen 80;
   #请填写绑定证书的域名
   server_name api.example.com; 
   #把http的域名请求转成https
   return 301 https://$host$request_uri; 
}


2)cert文件夹

记得放入你下载的ssl证书就可以了。

3)logs

对应的日志,有问题就就cat一下,看里面有error不

prisma的一个踩坑

这是prisma需要的databaseURL:

DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DB_HOST}:${DB_PORT}/${POSTGRES_DB}?schema=${DB_SCHEMA}&sslmode=prefer


其中DB_HOST在nest运行在本地的时候,比如你启动了postgresql,然后npm run start:dev,这时候DB_HOST=localhost

而当你nest运行在容器中,比如部署的时候docker-compose up -d,就需要改为对应容器的名字postgres

我确实忘改了😭😭😭

最后


笔者在本文主要叙述了如下部分,也可以当作自检清单:

  1. docker是什么
  2. docker的优势,为什么要使用它
  3. docker相关的关键词及概念
  4. 常用命令
  5. 最后用了现在比较新的一些技术栈部署实践

本文实战部分没有每步都截图演示,假的理由是因为自己试试比啥都好,真实原因是懒得再去运行截图了...

最后希望本文对你有所帮助,如果本文中理解有误或者操作配置不当,也希望互帮互助,在评论区中友善指出...



相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
18天前
|
Web App开发 算法 应用服务中间件
nginx开启局域网https访问
【10月更文挑战第22天】为了调试WebRTC功能,需要在局域网内搭建HTTPS协议。具体步骤包括:在已部署Nginx和安装OpenSSL的环境中生成私钥、证书签名请求和自签名证书;将生成的文件放置到Nginx的证书目录并修改Nginx配置文件,最后重启Nginx服务。注意,自签名证书不受第三方机构认可,如需正式使用,需向CA申请签名。
|
2月前
|
应用服务中间件 Linux nginx
Docker镜像-手动制作yum版nginx镜像
这篇文章介绍了如何手动制作一个基于CentOS 7.6的Docker镜像,其中包括下载指定版本的CentOS镜像,创建容器,配置阿里云软件源,安装并配置nginx,自定义nginx日志格式和web页面,最后提交镜像并基于该镜像启动新容器的详细步骤。
163 21
Docker镜像-手动制作yum版nginx镜像
|
1月前
|
安全 应用服务中间件 Shell
nginx配置https的ssl证书和域名
nginx配置https的ssl证书和域名
|
1月前
|
Docker 容器
docker nginx-proxy 添加自定义https网站
docker nginx-proxy 添加自定义https网站
39 4
|
1月前
|
前端开发 应用服务中间件 nginx
docker运行nginx镜像
这篇文章详细说明了如何在Docker中部署并运行Nginx服务,包括拉取镜像、配置文件的挂载以及容器的启动配置。
284 0
docker运行nginx镜像
|
2月前
|
应用服务中间件 nginx Docker
Docker镜像-基于DockerFile制作编译版nginx镜像
这篇文章介绍了如何基于Dockerfile制作一个编译版的nginx镜像,并提供了详细的步骤和命令。
460 17
Docker镜像-基于DockerFile制作编译版nginx镜像
|
2月前
|
NoSQL 关系型数据库 Redis
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
mall在linux环境下的部署(基于Docker容器),docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongodb、minio详细教程,拉取镜像、运行容器
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
|
2月前
|
应用服务中间件 nginx Docker
docker应用部署---nginx部署的配置
这篇文章介绍了如何使用Docker部署Nginx服务器,包括搜索和拉取Nginx镜像、创建容器并设置端口映射和目录映射,以及如何创建一个测试页面并使用外部机器访问Nginx服务器。
|
2月前
|
Linux Docker Windows
Docker配置https证书案例
本文介绍了如何为Docker的Harbor服务配置HTTPS证书,包括安装Docker和Harbor、修改配置文件以使用证书、生成自签名证书、配置证书以及验证配置的步骤。
181 2
Docker配置https证书案例
|
2月前
|
应用服务中间件 Linux nginx
Docker镜像-基于DockerFile制作yum版nginx镜像
本文介绍了如何使用Dockerfile制作一个基于CentOS 7.6.1810的yum版nginx镜像,并提供了详细的步骤和命令。
139 20
下一篇
无影云桌面