docker部署node服务类项目

简介: docker部署node服务类项目

docker部署node服务类项目


本文在docker 用 nginx 部署静态项目基础上,继续利用 docker 环境,运行 node,部署服务器项目,从而更多理解docker

在网页里使用接口

上一个静态项目里,添加请求即可。接口会在服务端项目添加。

<body>
  试试
  <script src="https://unpkg.com/axios@0.27.2/dist/axios.min.js"></script>
  <script>
    axios
      .get('/api/json', {
        params: {},
      })
      .then((res) => {
        console.log(res);
      })
      .catch((error) => {
        console.log(error);
      });
  </script>
</body>

创建服务器项目

建一个项目文件夹demo_server,项目路径下运行npm init -y初始化下

然后yarn add express

创建server.js写接口

项目根目录下,创建server.js

const express = require('express');
const PORT = 8080;
const HOST = '0.0.0.0';
const app = express();
app.get('/json', (req, res) => {
  res.json({
    code: 0,
    data: 'This is message from node container',
  });
});
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

拉取node公共镜像

拉取node公共镜像

docker pull node

创建Dockerfile文件

一般自定义构建镜像,是基于Dockerfile文件构建。

项目根目录下,创建Dockerfile文件

FROM node:latest
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "npm", "start" ]
  • FROM - 基于哪个镜像来实现
  • WORKDIR - 工作目录
  • COPY - 添加宿主机文件到容器里
  • RUN - 执行的命令
  • EXPOSE - 容器内应用可使用的端口
  • CMD - 容器启动后,所执行的程序,如果docker run后面跟启动命令会被覆盖掉

创建.dockerignore 文件

构建镜像的时候 node_modules 的依赖直接通过 RUN npm install 来安装。 项目中创建一个 .dockerignore 文件来忽略一些直接跳过的文件:

node_modules
npm-debug.log

自定义构建应用镜像

基于Dockerfile文件,自定义构建服务器镜像:

docker build -t server_image .
  • -t 是给镜像命名
  • . 是基于当前目录的 Dockerfile 来构建镜像

基于镜像启动容器

用下面命令,启动容器,之后访问

docker run -p 5000:8080 -d --name server_container server_image

基于镜像,启动容器,来提供接口服务8080端口,并映射宿主的5000端口。

跨域转发

目前静态项目的端口是3333,而服务的端口是5000,这样请求就会跨域,所以需要将静态项目容器的请求转发到服务的容器上。

查看服务容器对应的 ip

查看服务容器对应的 ip:

docker inspect server_container | grep IPAddress

可以看到是172.17.0.3,不同的可能不一样,记录这个值。

修改 nginx 配置

在静态项目的nginx/default.conf,增加一条规则

location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
}
# 增加这个
location /api/ {
  rewrite  /api/(.*)  /$1  break;
  proxy_pass http://172.17.0.3:8080;
}

/api/{path} 转到目标服务的 /{path} 接口上,这里的172.17.0.3就是服务容器对应的 IP。

配置负载均衡

后端服务一般都是双机或者多机以确保服务的稳定性

我们可以再启动一个后端服务容器,并修改 nginx 的配置,来优化资源利用率,最大化吞吐量,减少延迟,确保容错配置。

先再启动一个服务容器,记录下其 IP

# 容器名和宿主的端口号 需要重命名
docker run -p 5001:8080 -d --name server_container2 server_image
# 得到容器的IP,我这里是172.17.0.4
docker inspect server_container2 | grep IPAddress

修改一下 静态项目的nginx/default.conf(新增 upstream ,修改 location /api/ 中的 proxy_pass

server {
    # ...
    location /api/ {
      rewrite  /api/(.*)  /$1  break;
      # !!!修改这里
      proxy_pass http://backend;
    }
    ; ...
  }
  # !!!upstream要与server同级
  upstream backend {
      server 172.17.0.3:8080;
      server 172.17.0.4:8080;
  }

重启下静态项目的容器docker restart web_container

测试下 — 挂掉其中一个服务容器

docker stop server_container

刷新网页http://localhost:3333/,依旧正常~

网络异常,图片无法展示
|

启动容器失败 - 怎么查看原因

启动容器之后,docker ps却没发现相应的容器,可以通过logs诊断

# 比如 docker logs web_container
docker logs [容器名 或者 容器id]

写负载均衡的时候,就碰到这种问题,原来我把upstream写在server内部了,logs就提示错误信息,然后根据错误提示google了下,因此找到原因~~

docker部署egg项目

成熟的项目,一般都会有框架,docker部署node服务项目,大同小异,这边示例下egg项目的部署

1. 项目新增Dockerfile文件

项目根目录下加Dockerfile文件:

# 设置基础镜像,如果本地没有该镜像,会从Docker.io服务器pull镜像
FROM node:latest
# 配置环境变量
ENV NODE_ENV production
# 这个是容器中的文件目录
RUN mkdir -p /usr/src/app
# 设置工作目录
WORKDIR /usr/src/app
# 拷贝package.json文件到工作目录
# !!重要:package.json需要单独添加。
# Docker在构建镜像的时候,是一层一层构建的,仅当这一层有变化时,重新构建对应的层。
# 如果package.json和源代码一起添加到镜像,则每次修改源码都需要重新安装npm模块,这样木有必要。
# 所以,正确的顺序是: 添加package.json;安装npm模块;添加源代码。
COPY package.json /usr/src/app/package.json
# 安装npm依赖(使用淘宝的镜像源)
# 如果使用的境外服务器,无需使用淘宝的镜像源,即改为`RUN npm i`。
RUN npm i --production --registry=https://registry.npm.taobao.org
# 拷贝所有源代码到工作目
COPY . /usr/src/app
# 暴露容器端口
EXPOSE 9000
CMD npm start

2. 建立镜像,启动容器即可

之后建立镜像,然后启动容器即可

docker build -t egg_image ./
docker run -itd --net=host --name egg_container -p 8000:8000 egg_image

这样就可以访问http://localhost:8000

再次理解docker容器

  • 镜像就像是一个安装包,每个docker容器类似新一个电脑下载了安装包然后启动
  • 每个容器既然都是新电脑,那么就拥有自己独立的空间、网络。

引用

目录
相关文章
|
21天前
|
JavaScript C++ 容器
【Azure Bot Service】部署NodeJS ChatBot代码到App Service中无法自动启动
2024-11-12T12:22:40.366223350Z Error: Cannot find module 'dotenv' 2024-11-12T12:40:12.538120729Z Error: Cannot find module 'restify' 2024-11-12T12:48:13.348529900Z Error: Cannot find module 'lodash'
38 11
|
29天前
|
缓存 JavaScript 持续交付
“解锁Node.js新纪元:如何借助Docker打造快速、高效且一致性的现代应用部署体验”
【10月更文挑战第25天】本文介绍了如何使用Docker容器化Node.js应用,包括容器化的好处、创建Docker镜像的步骤、构建和运行镜像的方法、管理依赖、保持应用更新以及调试技巧。通过容器化,可以提高应用的可移植性和可扩展性,简化开发和部署流程。
30 2
|
2月前
|
负载均衡 应用服务中间件 网络安全
docker swarm添加更多的服务
【10月更文挑战第16天】
23 6
|
2月前
|
Docker 容器
docker swarm启动服务并连接到网络
【10月更文挑战第16天】
34 5
|
2月前
|
负载均衡 网络协议 关系型数据库
docker swarm 使用网络启动服务
【10月更文挑战第15天】
30 4
|
2月前
|
Docker 容器
docker swarm 在服务中使用网络
【10月更文挑战第14天】
27 2
|
2月前
|
SQL JavaScript 关系型数据库
node博客小项目:接口开发、连接mysql数据库
【10月更文挑战第14天】node博客小项目:接口开发、连接mysql数据库
|
2月前
|
安全 网络安全 数据安全/隐私保护
docker服务未启动
【10月更文挑战第2天】
69 3
|
2月前
|
Linux iOS开发 Docker
docker服务未启动
【10月更文挑战第3天】
72 1
|
2月前
|
JavaScript Linux 网络安全
VS Code远程调试Nodejs项目
VS Code远程调试Nodejs项目