Docker部署Node+Koa+TS+Mongo项目

news2024/12/27 13:08:27

在这里插入图片描述

Docker 简介

简而言之,Docker 容器轻量级、启动快、可移植,适合微服务架构。主要组件包括 Docker Engine、Docker 镜像、Docker 容器和 Docker Hub,它通过容器打包应用程序及其依赖项,使得应用在任何环境中都能一致运行。

这里不详细介绍 docker,想了解更多相关知识可以去官网查看docker 官网

安装 docker (mac 系统)

1.通过官网下载小鲸鱼(Docker Desktop),查看 About Dokcer Desktop,可以看到 docker 的信息
在这里插入图片描述

2.打开终端,输入docker -v查看当前的版本,或者查看 docker 服务状态docker info

docker -v 或者 docker info

➜  ~ docker -v
Docker version 27.0.3, build 7d4bcd8

3.如果zsh: command not found: docker,按照以下步骤处理:

  • 在.bash_profile 写入:export PATH=$PATH:/Applications/Docker.app/Contents/Resources/bin/
  • 在.zshrc 中写入:source ~/.bash_profile
  • 运行source .zshrc
  • 运行docker -v

测试 docker

终端运行docker run hello-world, 会得到以下结果:

➜  ~ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Digest: sha256:1408fec50309afee38f3535383f5b09419e6dc0925bc69891e79d84cc4cdcec6
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
....(忽略其他的)

hello-world 是 docker 上面发布的镜像,在 Docker Desktop 中也能看到这个 Image 和 Container,说明 docker 已经可以正常使用了。

docker 镜像和容器

这里来说下 docker 镜像和容器的关系:

  • 想象一下,你要做一个蛋糕。蛋糕的配方就像是 Docker 镜像。
  • 这个配方详细列出了制作蛋糕所需的所有材料和步骤。同样,Docker 镜像包含了一个应用程序运行所需的所有文件、依赖项和设置(可以理解为一个完整的项目)。
  • 当你有了配方(Docker 镜像)之后,你可以根据这个配方反复制作蛋糕(启动容器)。
  • 每次制作出来的蛋糕(容器)都是一样的,因为它们都是根据同一个配方(镜像)做出来的。

镜像的拉取和创建

  1. docker pull 从 Docker Hub 或者其他注册表中拉取镜像
# 拉取 node 镜像最新版本或者指定版本
docker pull node:latest 或 docker pull node:20.10.0

  1. docker image build 从 Dockerfile 构建一个镜像(下面会讲)
docker build -t <镜像名>:<标签> <Dockerfile所在目录>

容器的启动

  1. 使用该镜像运行一个容器 docker run [选项] <镜像名>:[标签]

docker run -d -p 8000:3000 --name my-node-app node:20.10.0

常用选项:

  • -d: 后台运行
  • -p: 端口映射(如 -p 8000:3000, 访问 localhost:8000 代替 localhost:3000)
  • --name: 为容器指定一个名称
  1. 查看所有容器(包括停止的容器)

docker ps -a

  1. 停止和开启容器

docker stop <容器 ID 或名称> / docker start <容器 ID 或名称>

  1. 删除容器

docker rm <容器 ID 或名称>


以上介绍和示例跑通说明我们已经可以开始使用 docker 来部署我们的项目了(其他更多的 docker 语法可以在网上自行查阅,这里不进行详细讲解)

Dockerfile

# 选择基础镜像
FROM node:latest

# 设置维护者信息
LABEL maintainer="edon"

# 防止中文打印信息显示乱码
ENV LANG="C.UTF-8"

# WORKDIR:设置工作目录,所有后续指令(如RUN、COPY、ADD)都会在这个目录下执行。如果目录不存在,会自动创建。
WORKDIR /app

# COPY <源路径> <目标路径> 将文件或目录从构建上下文复制到镜像中。(如有忽略文件配置在.dockerignore中)
COPY ./package.json /app
COPY . /app

# RUN: 在镜像内执行命令。常用于安装软件包或配置环境。
RUN npm install
RUN npm run build
或
RUN npm install && npm run build

# EXPOSE: 声明镜像要监听的端口,这只是一个文档化的指令,实际上并不会开放端口。
EXPOSE 3000

# CMD:指定容器启动时要执行的命令,Dockerfile中只能有一个CMD指令,后面的会覆盖前面的
CMD ["node", "app.js"]

还有其他的配置如,ADDENTRYPOINTVOLUMEUSERARG等等,在这里不详细列出。

以上是 Dockerfile 最基础的结构,将 Dockerfile 放置在根目录下,执行docker image build -t [image:name]:[tag] .即可创建镜像,创建完就可以docker run来运行了。

执行:docker image build -t my-node-app:0.1 .

在这里插入图片描述

在Docker Desktop的Images可以看到:
在这里插入图片描述

Docker Compose

Dockerfile 构建的是一个独立的镜像,但是像我们的后端项目,一般还会连接数据库,比如 mongodb,按照 Dockerfile 模块的介绍,我们还要创建 mongo 的镜像和开启 mongo 容器

# 拉取mongo镜像
docker pull mongo:latest
# 运行mongo容器
docker run -d --name mongo -p 27017:27017 -v mongo-data:/data/db mongo:latest

当我们有一个后端项目,连接着数据库,如 node+mongo,我们可以使用Docker Compose,在一个 docker-compose.yml 文件中定义 Node.js 应用和 MongoDB 的服务,并一次性启动它们。

version: "3.8"

services:
  app:
    image: node:20.16.0
    container_name: node-koa-temp
    working_dir: /app/server
    volumes:
      - ./:/app/server
      - /app/server/node_modules
    environment:
      - HOST_MONGO_URL=mongodb://mongo:27017
      - PORT=8000
    depends_on:
      - mongo
    ports:
      - "8001:8000"
    command: sh -c "npm install -g pnpm@latest --registry=https://registry.npmmirror.com && pnpm install && npm run build && npm run start:build"

  mongo:
    image: mongo:latest
    container_name: node-koa-mongodb
    ports:
      - "27018:27017"
    volumes:
      - mongo-data:/data/db

volumes:
  mongo-data:

以上的配置看着是不是很熟悉,跟 Dockerfile 的配置很相似,配置介绍可参考:Docker Compose


实战 node+koa+ts+mongo

1.先准备好一个 node 后端项目,这里我们会写一个 node+koa+ts+mongo 的项目(这里本地具备 node 和 mongo 环境)

仓库地址

demo仓库地址:github node+koa+ts+mongo

Demo项目介绍

node-koa-temp
│
├── src
│   ├── index.ts
│   ├── controllers
│   │   └── users.ts
│   ├── models
│   │   └── users.ts
│   ├── mongodb
│   │   └── index.ts
│   ├── routes
│   │   └── index.ts
│   ├── types
│   │   ├── common.ts
│   │   └── user.ts
├── .dockerignore
├── .npmrc
├── docker-compose.yml
├── Dcokerfile
├── nodemon.json
├── package.json
├── tsconfig.json
└── README.md

src/mongodb/index.ts

import mongoose from "mongoose"

const uri = "mongodb://localhost:27017"

export const connectToDatabase = async () => {
  try {
    await mongoose.connect(uri, { dbName: "local-mongodb" })
    console.log("Connected to MongoDB with Mongoose")
  } catch (error) {
    console.error("Failed to connect to the database", error)
    throw error
  }
}

src/index.ts

import cors from "@koa/cors"
import http from "http"
import Koa from "koa"
import bodyParser from "koa-bodyparser"
import router from "src/routes"
import { connectToDatabase } from "./mongodb"

const app = new Koa()
app.use(
  cors({
    origin: "*",
    allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    allowHeaders: ["Content-Type", "Authorization", "Accept"],
  })
)
app.use(bodyParser())
app.use(router.routes()).use(router.allowedMethods())

const server = http.createServer(app.callback())
connectToDatabase()
  .then(() => {
    const PORT = 8000
    server.listen(PORT, () => {
      console.log(`Server is running http://localhost:${PORT}`)
    })
  })
  .catch((error) => {
    console.error("Failed to connect to the database", error)
  })

tyconfig.json

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true,
    "baseUrl": "./",
    "paths": {
      "src/*": ["./src/*"],
      "~/*": ["./*"]
    },
    "typeRoots": ["node_modules/@types", "typings"]
  },
  "include": ["src/**/*", "typings"],
  "exclude": ["node_modules"]
}

nodemon.json

{
  "ignore": ["./node_modules/**"],
  "watch": ["src"],
  "exec": "cross-env ts-node -r tsconfig-paths/register src/index.ts",
  "ext": "ts,json"
}

package.json

  "scripts": {
    "dev": "cross-env MODE=stage nodemon --config nodemon.json",
    "build": "rimraf dist && tsc && tsc-alias",
    "start:build": "cross-env MODE=prod node dist/index.js"
  },

本地运行项目

npm run dev

运行成功,可以访问 localhost:8000

在这里插入图片描述

本地编译打包项目和启动

npm run build
npm run start:build

运行成功,可以访问 localhost:8000

docker-compose.yml

version: "3.8"

services:
  app:
    image: node:20.16.0
    container_name: node-koa-temp
    working_dir: /app/server
    volumes:
      - ./:/app/server
      - /app/server/node_modules
    environment:
      - HOST_MONGO_URL=mongodb://mongo:27017
      - PORT=8000
    depends_on:
      - mongo
    ports:
      - "8001:8000"
    command: sh -c "npm install -g pnpm@latest --registry=https://registry.npmmirror.com && pnpm install && npm run build && npm run start:build"

  mongo:
    image: mongo:latest
    container_name: node-koa-mongodb
    ports:
      - "27018:27017"
    volumes:
      - mongo-data:/data/db

volumes:
  mongo-data:

在根目录下执行docker-compse up --build,一次性启动两个容器

在这里插入图片描述

Docker Desktop 的 Container 可以看到:

在这里插入图片描述

这个时候访问 http://localhost:8001, 就可以访问到我们的服务了。

按照以上流程,使用 Dockerfile 可以直接部署 vue 或 React 前端项目,实现 docker 部署前后端项目项目。

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

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

相关文章

Selenium中send_keys上传图片方法以及可能失败的原因

Python Selenium是一个用于自动化浏览器操作的工具&#xff0c;可以用于模拟用户在浏览器中的各种操作。在使用Python Selenium进行自动化测试时&#xff0c;有时需要上传图片。下面是在这种情况下如何上传图片的步骤&#xff1a; 今天是主要说的是input标签&#xff0c;这种可…

基于R语言绘制GGE双标图3

参考资料&#xff1a; https://cran.r-project.org/web/packages/GGEBiplots/GGEBiplots.pdf GGE叠图法一分析品种环境互作模式的理想方法【作物学报】 GGE 双标图如何看&#xff1f;-CSDN博客 1、品种间两两比较 GGE 双标图可用于直接比较两个品种在各个试验点的表现&…

白银市场暴跌的技术分析与投资策略

一、白银市场暴跌与技术分析 周一&#xff08;8月5日&#xff09;&#xff0c;现货白银暴跌逾4.5%&#xff0c;并跌破关键的100日移动均线。FXStreet分析师Christian Borjon Valencia对银价技术走势进行了分析&#xff0c;指出银价前景转为看跌&#xff0c;技术面显示白银将进一…

探索Python并发的秘境:Greenlet库的奇幻之旅

文章目录 探索Python并发的秘境&#xff1a;Greenlet库的奇幻之旅背景&#xff1a;为何选择Greenlet&#xff1f;绿野仙踪&#xff1a;Greenlet是什么&#xff1f;安装&#xff1a;如何将Greenlet纳入囊中&#xff1f;功能探索&#xff1a;Greenlet的五大法宝场景应用&#xff…

【系统分析师】-综合知识-软件工程与项目管理

1、按照成本性态分类&#xff0c;可以分为固定成本、变动成本和混合成本。 &#xff08;1&#xff09;固定成本。管理人员的工资、办公费、固定资产折旧费、员工培训费、广告费、员工培训费、技术开发经费、办公场地及机器设备的折旧费、房屋及设备租金、管理人员的工资等。 …

提示工程:CO-STAR框架

在人工智能领域&#xff0c;尤其是大型语言模型&#xff08;LLM&#xff09;的应用中&#xff0c;提示工程已成为一项至关重要的技能。它不仅需要对技术有深刻的理解&#xff0c;还需要创造力和战略思维的结合。本文将探讨提示工程的重要性&#xff0c;详细介绍CO-STAR框架的使…

0209-开发状态切换(场景切换)功能

一、设置场景状态 1、已有方法 2、实现步骤 引用API&#xff1a;using UnityEngine.SceneManagement 写设置场景状态的方法 场景名字切换&#xff0c;需要获取mSceneName&#xff0c;他是私有的&#xff0c;给一个getset 3、问题 &#xff08;1&#xff09;同步加载 加载场…

【Web开发手礼】探索Web开发的秘密(十六)-Vue2(2)前端工程化、Element组件表格、分页

主要介绍了前端工程化Vue的开发流程、Element组件介绍以及常见的Element组件表格、分页&#xff01;&#xff01;&#xff01; 目录 前言 前端工程化 Vue项目-创建 Vue项目-目录结构 Vue项目-启动 Vue项目-配置端口 Vue项目开发流程 Element组件 快速入门 常见组件 表格…

2024杭电多校(4) 1008. 树形DNA【01Trie、哈希】

题意 给定两颗二叉树 S S S 和 T T T&#xff0c;如果对于 S S S 的某个子树 S ′ S^\prime S′&#xff0c;删除若干个&#xff08;或不删除&#xff09;其子树后&#xff0c;可以和 T T T 相同&#xff08;左子树与左子树匹配&#xff0c;右子树与右子树匹配&#xff0…

C++入门基础知识

在之前我们学习了C语言和初阶数据结构的相关知识&#xff0c;现在已经有了一定的代码能力和对数据结构也有了基础的认识&#xff0c;接下来我们将进入到新的专题当中&#xff0c;这个专题就是C。在C中我们需要花费更大的精力和更长的时间去学习这门建立在C语言基础之上的计算机…

新一代AI软件基础设施 | ZStack AIOS平台“智塔”发布

新一代 IT 基础设施&#xff0c;将从通用算力云平台转型为AI算力AIOS平台。 AI正在重构世界。正如世界是立体的&#xff0c;AI重构也正从多维度开启&#xff1a;基础设施重构&#xff0c;业务应用重构&#xff0c;交互模式重构&#xff0c;数据价值重构&#xff0c;生态系统重…

移动IP:让你的设备随时随地保持连接

随着无线网络技术的迅猛发展&#xff0c;在移动中进行数据通信已成为可能。成千上万的人正在使用移动设备畅享互联网&#xff0c;无论是在火车上、汽车内&#xff0c;还是在其他移动场景中。本文将带你了解移动IP&#xff08;Mobile IP&#xff09;的工作原理及其对网络应用的影…

LLM在线理解;神将网络理解;transform架构

目录 LLM在线理解 神将网络理解 transform架构 模型的子结构: 三个计算 计算1 计算2 计算3 LLM在线理解 LLM Visualization 神将网络理解 transform架构 模型的子结构: 词向量(Embedding) 前馈神经网络(Feed Forward) 残差连接(Add)和层标准化(Norm) 线性层(Linear…

Python版本和cuda版本不匹配解决办法

一、检查版本是否匹配 使用Python进入控制台&#xff0c;然后执行&#xff1a; >>>print(torch.cuda.is_available())如果输出为 False&#xff0c;则说明不匹配 退出Python环境&#xff0c;再检查系统版本&#xff1a; exit()nvcc -V 二、安装 去官网 PyTorch …

转载一篇关于对Linux磁盘部分mount和挂载的解释

转载自: http://t.csdnimg.cn/V3lgahttp://t.csdnimg.cn/V3lga

3_stm32_pwm呼吸灯

到目前已经可以进行基础的Led亮灭控制、使用定时器中断控制Led的亮灭。但是发现Led只有“亮”和 “灭”两种状态&#xff0c;那是否可以有更多状态&#xff1f;如何有更多状态呢&#xff1f;更进一步的想法&#xff0c;Led亮是有了电压差&#xff0c;其中一端是地&#xff0c;那…

C#:具体类=>抽象类=>接口的变化过程详解

文章目录 简单复习继承与多态具体类抽象类及成员使用语法 接口抽象类到接口的进化 简单复习继承与多态 下面,我用一个交通工具的例子来快速复习一下. 1.首先我定义一个基类Vehicle,代表交通工具的总称.里面定义了一个可被重写的成员方法Run. class Vehicle{public virtual voi…

Python Flask+Echarts实现葡萄酒质量的影响因素分析可视化

提示&#xff1a;本文章参考了哔哩哔哩的python课程李巍老师的 视频教程 文章目录 前言一、相关技术1.Flask2.Echarts3.词云 二、代码部分1.5个前端页面&#xff1a;2.代码 效果图 前言 数据分析是指用适当的统计分析方法对收集来的大量数据进行分析&#xff0c;将它们加以汇总…

代码随想录算法训练营第六天(一)|242.有效的字母异位词

LeetCode 242 有效的字母异位词 题目&#xff1a; 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;则称 s 和 t 互为字母异位词。 示例 1: 输入: s "anagram&q…

韦东山嵌入式linux系列-mmap

应用程序和驱动程序之间传递数据时&#xff0c;可以通过read、 write函数进行。这涉及在用户态 buffer 和内核态 buffer 之间传数据&#xff0c;如下图所示 应用程序不能直接读写驱动程序中的buffer&#xff0c;需要在用户态 buffer 和内核态 buffer 之间进行一次数据拷贝。这种…