前端全栈之路 - docker部署node后端

394 阅读5分钟

主要思路

本文主要讲最近实践的node后端代码部署。

工程:express后端工程、数据库为mongodb 思路:配置docker,安装项目和db,用docker-compose组合容器,最后阿里云部署

操作记录

使用docker容器化应用,使得部署过程更加简单和可重复。

下方triim代表项目名称。

容器化应用

  1. 创建Dockerfile: 在你的项目根目录下创建一个名为 Dockerfile 的文件。这个文件描述了如何构建你的 Docker 镜像。例如:
# 使用官方 Node.js 作为基础镜像
FROM node:20.11.1

# 设置工作目录
WORKDIR /usr/src/triim

# nodemon
RUN npm install -g nodemon

# 安装依赖
COPY package*.json ./
RUN npm install

# 拷贝源代码
COPY . .

# 暴露端口
EXPOSE 4000

# 启动应用
CMD [ "npm", "run", "dev" ]

☆WORKDIR小知识☆

WORKDIR 指令用于设置后续指令(如 RUNCMDENTRYPOINTCOPY 和 ADD)的工作目录。 此处,WORKDIR /usr/src/nako-make 指令将工作目录设置为 /usr/src/nako-make。这意味着后续的 COPY 和 RUN 指令都会在这个目录下执行。

  • 例如,COPY package*.json ./ 指令将会把 package*.json 文件复制到容器的 /usr/src/nako-make 目录下,而不是容器的根目录。

  • 同样,RUN npm install 指令将会在 /usr/src/nako-make 目录下执行,安装的 Node.js 依赖会被安装到这个目录下的 node_modules 文件夹。

总的来说,WORKDIR 指令可以帮助我们组织和管理 Docker 容器中的文件和目录,使得 Dockerfile 更清晰,更易于理解。

  1. 构建 Docker 镜像:在你的项目根目录下运行以下命令来构建 Docker 镜像: docker build -t triim .

  2. 运行 Docker 容器:你可以在本地运行你的 Docker 容器来测试它: docker run -p 4000:4000 -d triim

  3. 推送 Docker 镜像:你可以将你的 Docker 镜像推送到 Docker Hub 或者阿里云的镜像仓库:

docker tag my-app:latest myusername/my-app:latest
docker push myusername/my-app:latest
  1. 在服务器上运行 Docker 容器:在你的服务器上,你可以拉取你的 Docker 镜像并运行它:
docker run -p 4000:4000 -d triim
docker run -p 4000:4000 -v ${pwd}:/app -d triim // 热更新

容器化MongoDB

在 Docker 中安装 MongoDB,你可以使用 MongoDB 的官方 Docker 镜像。以下是一个基本的步骤:

  1. 拉取 MongoDB 的 Docker 镜像。在终端中运行以下命令: docker pull mongo

  2. 运行 MongoDB 容器。在终端中运行以下命令: docker run --name triim-mongo -d mongo

这个命令会启动一个名为 triim-mongo 的 MongoDB 容器,并在后台运行。MongoDB 服务器默认监听 27017 端口。如果你想要将 MongoDB 的端口映射到宿主机的端口,你可以使用 -p 参数。例如,以下命令会将容器的 27017 端口映射到宿主机的 27017 端口: docker run --name triim-mongo -p 27017:27017 -d mongo

至此,一个不带db的后端服务就跑起来了。

关联node应用容器和mongodb容器

要让你的 Node.js 应用连接到 Docker 中的 MongoDB 容器并存储数据,你需要做以下几步:

首先,环境变量设置数据库的访问uri, 可以docker容器名:端口号的形式访问数据库。如下方的MONGO_URI=mongodb://triim_mongo:27017,triim_mongo

"scripts": {
    "dev": "MONGO_URI=mongodb://192.168.xx.xx:27017 nodemon app.js",
    "prod": "MONGO_URI=mongodb://triim_mongo:27017 nodemon app.js",
  },

docker run --name triim-mongo -p 27018:27017 -v mongodb_data:/data/db mongo

  • 其中,-p端口,27017是mongo的image跑起来后的默认端口,此处被映射到了宿主机的27018端口。所以如果要可视化查看数据,mongo compass可以直接连27018端口查看。 截屏2024-05-20 15.23.33.png
  • 其中,-v(volume命令),这里将容器下的/data/db数据,持久化到了mongodb_data目录下(/var/lib/docker/volumes/mongodb_data/_data),如此操作,即使容器删除,数据依然存在。

在代码中,即可用宿主机的端口号来访问了。 const client = new MongoClient('mongodb://192.168.31.29:27018', {});

docker-compose 维护多个容器

至此,虽然项目只有两个容器,但是需要记多个命令包括参数,更改后多次构建镜像运行容器显得有些繁琐,时间一久也不容易记住。

那么docker-compose就该上场了,其可以管理运行多个容器,使流程简化。

以当前项目为例:

  • 首先,在项目根目录下创建docker-compose.yml
  • 内容如下:d
version: '3'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    command: npm run dev
    depends_on:
      - db
  web-prod:
    build: .
    ports:
      - "3001:3000"
    command: npm run prod
    depends_on:
      - db
  db:
    image: mongo
    container_name: game_avatar_mongo
    ports:
      - "27017:27017"
    volumes:
      - /var/lib/mongodb:/data/db
  • 运行:
    • docker-compose up 会跑所有容器
    • docker-compose up web-prod 会跑web-prod以及所有它依赖的
    • docker-compose run [指定容器]
    • docker-compose build 如果有更改,则要重新构建后再运行

看,是否比之前的命令简化很多,一条命令就能跑起来所有所需容器。

部署到云服务器

  • 环境:package.json脚本命令指定生产环境变量
  • 代码:ecs根目录/source下,git拉取管理源代码
  • 运行:运行生产环境容器,docker-compose up web-prod -d (detach后台运行,退出服务器不会关闭)

截屏2024-05-29 14.37.21.png

服务运行成功!

补充

docker-compose run有时会失败,可以设置延长超时时间。具体如下:

COMPOSE_HTTP_TIMEOUT 是一个环境变量,用于设置 Docker Compose 与 Docker daemon 通信的超时时间(以秒为单位)。默认值是 60 秒。

在 Unix 或 Linux 系统(包括 Mac)上,你可以使用 export 命令在当前 shell 会话中设置这个环境变量。例如:

export COMPOSE_HTTP_TIMEOUT=200

这会将 COMPOSE_HTTP_TIMEOUT 设置为 200 秒。

如果你想要在所有 shell 会话中都使用这个设置,你可以将这个命令添加到你的 shell 初始化文件中(例如 ~/.bashrc 或 ~/.bash_profile)。