使用 docker-compose 构建你的项目

使用 docker-compose 构建你的项目

  • 1. Docker
    • 1.1 安装
    • 1.2 docker-compose
  • 2 准备项目
    • 2.1 初始化一个node项目
    • 4. 准备一个 Dockerfile 文件
    • 5. 构建镜像
  • 3.docker-compose构建
    • 3.1 配置docker-compose.yml 文件
    • 3.2 编排多个服务
  • 重新构建镜像 --force-rm 删除构建过程中的临时容器。
  • 运行容器
  • 4. 水平扩展 node 服务
    • 4.1 scale
    • 4.2 修改nginx配置文件

最近再次手撕docker。所以就想者分享一下这方面的知识。欢迎各位踩我

1. Docker

docker的是什么, 就当大家有一定的Docker基础了

所以这篇文章主要是实战方面的内容,具体理论的话,可以去搜搜其它文章了解学习一下。或者去官网

1.1 安装

window 系统或者 macos 系统可以直接去官网下载 Docker Desktop,链接:hub.docker.com/?overlay=on…
然后就是傻瓜式安装了,这边就不介绍了
注意: window下需要企业版才能安装,家庭版不能安装(或者安装比较麻烦)

1.2 docker-compose

在安装完 Docker Desktop 后,会默认自动安装好 docker-compose
可以自己在命令行上试试,查看当前版本

docker-compose -v
docker -v

2 准备项目

2.1 初始化一个node项目

mkdir  /www
mkdir  /www/node-server
cd /www/node-server

在这里插入图片描述

  1. 初始化package.json
npm init -y

执行后创建以下文件及文件夹
在这里插入图片描述

  1. 搭建一个http服务器
    这边使用的是express,用koa也行,看自己喜欢
npm install express

简单代码 dev-server.js
在这里插入图片描述

 let express = require('express')
let os = require('os')
let app = express()
// 获取本机ip地址
function getLocalIpAddress () {let ip = ''let netInfo = os.networkInterfaces()let osType = os.type()if (osType === 'Windows_NT') { for (const dev in netInfo) {// win7的网络信息中显示为本地连接,win10显示为以太网if (dev === '本地连接' || dev === '以太网') {for (let j = 0; j < netInfo[dev].length; j++) {if (netInfo[dev][j].family === 'IPv4') {ip = netInfo[dev][j].address;break;}}}}} else if (osType === 'Linux') {ip = netInfo.eth0[0].address;}return ip
}
app.get('/getJson', (request, response) => {response.send({title: 'Hello Express、Hello Docker',ip: getLocalIpAddress(),env: process.env.NODE_ENV})
})
// 监听3000端口
app.listen(3000, () => {console.log('server is started')
})

4. 准备一个 Dockerfile 文件

在这里插入图片描述

Docker中镜像和容器的关系就像类与实例的关系
镜像可以通过Dockerfile文件来生成,容器通过镜像来创建

Dockerfile用于生成镜像
复制代码

# 指定的一个基础镜像
FROM node:latest
# 工作目录
WORKDIR /www/node-server/  
# copy package.json 到工作目录中
COPY package.json /www/node-server/package.json
# 安装依赖
RUN npm install
# 拷贝当前目录的文件到工作目录中
# 如果有不需要忽略的文件,可以写在 .dockerignore 文件中,比如忽略 node_modules 文件夹
COPY . /www/node-server/
# 向外暴露3000端口
EXPOSE 3000
# 容器运行后执行的命令
CMD npm run start

5. 构建镜像

修改package.json 增加代码

  "scripts": {"test": "echo \"Error: no test specified\" && exit 1","start": "node dev-server.js 3000"},

在这里插入图片描述
执行构建镜像命令

 docker build -t node-server .

检查构建结果
在这里插入图片描述

构建成功后,创建容器

docker run --name node-server-1 -p 3000:3000 node-server

使用浏览器访问 3000 端口看看是否启动成功了
在这里插入图片描述

3.docker-compose构建

前面我们要使用容器时,需要先定义 Dockerfile 文件,然后使用 docker build、docker run 等命令操作容器。
然而我们的系统一般都包含上百的服务,每个服务又有多个实例,如果全手动来启动关闭的话,那工作量之大可想而知

那通过 docker-compose 可以轻松、高效的管理容器,它是一个用于定义和运行多容器 Docker 的应用程序工具

3.1 配置docker-compose.yml 文件

在项目目录下创建一个 docker-compose.yml 文件
在这里插入图片描述

version: "3"
services: # 服务列表node: # node 服务build: context: /www/node-server # Dockerfile 的目录,用于构建镜像dockerfile: Dockerfilecontainer_name: node-server-1 # 容器名称ports: # 暴露的端口- "3000:3000"restart: always # 自动重启environment: # 设置环境变量- NODE_ENV=productioncommand: npm run start # 覆盖容器启动后默认执行的命令

构建镜像

docker-compose build

执行结果如下
在这里插入图片描述

运行容器

docker-compose up -d

报错

[root@dev07 music]# docker-compose up -d
Creating node-server-1 ... errorCreating node-server-1 ... ERROR: for node-server-1  Cannot create container for service node: Conflict. The container name "/node-server-1" is already in use by container "39e4c77c6c5215731eef4aERROR: for node  Cannot create container for service node: Conflict. The container name "/node-server-1" is already in use by container "39e4c77c6c5215731eef4ab66d1e25d0428619c82e33ba49d059d2b0fc2fc87c". You have to remove (or rename) that container to be able to reuse that name.
ERROR: Encountered errors while bringing up the project.

问题分析:
使用docker build时 ,构建过镜像
解决方案:

[root@dev07 music]# docker rm 39e4c77c6c5215731eef4ab66d1e25d0428619c82e33ba49d059d2b0fc2fc87c

不出意外的话,通过浏览器访问3000端口也是能正常访问

3.2 编排多个服务

比如我们现在需要构建一个 nginx服务来将请求代理到我们的 node-server,那我们需要构建两个服务
那么问题来了

  • nginx容器如何使用我的自己的nginx.conf配置文件

可以通过 volumes 文件映射

  • nginx容器和 node-server 容器如何进行通信

可以使用 docker-inspect 命令来查看 node-server 容器的IP地址,然后修改nginx.conf的配置、
使用networks和links

docker容器每次重新构建运行时,IP 地址不一定是一样的,所以每次都要修改nginx.conf的配置,所以方案1的效率显然是低下的。

  • 新增一个 nginx.conf 配置文件
worker_processes 1;events {worker_connections 1024;
}
http {upstream node-server {  server node:3000;} server {listen 80;server_name localhost;location / {proxy_pass http://node-server/;}}
}

重新修改一下 docker-compose.yml 文件

复制代码# docker-compose.yml

version: "3"
services: # 服务node: # node 服务build: . # Dockerfile 的目录,用于构建镜像container_name: node-server-1 # 容器名称ports: # 暴露的端口- "3000:3000"restart: always # 自动重启environment: - NODE_ENV=productionnetworks: # 加入网络- "my-network"command: npm run start # 覆盖容器启动后默认执行的命令nginx:image: nginx:latest 指定 nginx 镜像ports: # 将本机的 8080 端口映射到容器的80端口- "8080:80"            container_name: nginx-noderestart: alwaysvolumes: # 映射本机 F:/nginx.conf 文件到 容器的 /etc/nginx/nginx.conf:ro 文件- "F:/nginx.conf:/etc/nginx/nginx.conf:ro"networks: - "my-network"links: # 设置 node 服务别名,其实是设置/etc/hosts的域名解析- "node"depends_on: # 指定依赖于哪个服务- node
networks: # 网络my-network: # 网络名称driver: bridge

重新构建

复制代码# 删除上次构建的容器
docker-compose down

重新构建镜像 --force-rm 删除构建过程中的临时容器。

docker-compose build --force-rm

运行容器

docker-compose up -d
不出意外的话,通过浏览器访问本地的8080端口,是可以访问到 node-server 的

按着上面的套路,可以继续扩展 redis、mysql服务等,也是通过加入 network 和 links 来进行相互通信
这部分就不进行介绍了

4. 水平扩展 node 服务

当用户量比较小的情况下,我们一个 node 服务就够用了,当用户量大的时候,就一个 node 服务的话,就显得力不从心了。
一般情况下都是升级机器,加服务,通过 nginx进行负载均衡
在这里插入图片描述

那我们如何通过 docker-compose 快速的水平扩展服务呢?

4.1 scale

docker-compose 给我们提供了一个 scale 命令,用于在本机下快速构建多个服务

# 删除上次构建的容器
docker-compose down
# 重新构建镜像 --force-rm 删除构建过程中的临时容器。
docker-compose build --force-rm
# 运行容器 增加 --scale node=5
docker-compose up -d --scale node=5 

通过–scale node=5我们构建5个node服务
不过不出意外的话,是会构建失败的,报端口占用错误

因为我们的每个node服务都占用了 3000 本机的端口。
所以我们需要修改一下 docker-compose.yml 文件,只暴露容器的3000端口,不暴露本机的端口

# docker-compose.yml
version: "3"
services: # 服务node: # node 服务build: . # Dockerfile 的目录,用于构建镜像# container_name: node-server-1 # 容器名称# ports: # 暴露的端口#    - "3000:3000"expose:- "3000"restart: always # 自动重启environment: - NODE_ENV=productionnetworks: # 加入网络- "my-network"command: npm run start # 覆盖容器启动后默认执行的命令nginx:image: nginx:latest 指定 nginx 镜像ports: # 将本机的 8080 端口映射到容器的80端口- "8080:80"            container_name: nginx-noderestart: alwaysvolumes: # 映射本机 F:/nginx.conf 文件到 容器的 /etc/nginx/nginx.conf:ro 文件- "F:/nginx.conf:/etc/nginx/nginx.conf:ro"networks: - "my-network"links: # 设置 node 服务别名,其实是设置/etc/hosts的域名解析- "node"depends_on: # 指定依赖于哪个服务- node
networks: # 网络my-network: # 网络名称driver: bridge

重新运行

复制代码# 运行容器 增加 --scale node=5
docker-compose up -d --scale node=5
不出意外的话,这次可以构建成功
通过 docker ps -a 可以查看当前运行的容器
复制代码docker ps -a
不出意外的话,通过nginx访问,负载均衡没有生效,每次访问得到的ip地址一直是同一个

4.2 修改nginx配置文件

我们通过 docker inspect nginx-node 命令,在查看一下 nginx 容器的信息

docker inspect nginx-node

在这里插入图片描述

可以看到 “node-server_node_3:node”,我们nginx配置了server node:3000;,所以每次请求,nginx都将请求代理到node-server_node_3这个node服务上了,

upstream node-server {  server node:3000;
} 

所以我们修改一下 nginx.conf 配置,这样就能将请求代理到不同的机器上了

upstream node-server {  upstream node-server {  server node_1:3000 weight=3; # 加权重server node_2:3000;server node_3:3000;server node_4:3000;server node_5:3000;}
} 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI-Chat,一款集全网ai功能的应用(附下载链接)

AI-Chat是一款综合性的聊天机器人&#xff0c;集成了多种先进的模型和功能。它采用了GPT4.0、联网版GPT和清华模型等多种模型&#xff0c;使得其具备更强大的语言处理能力。同时&#xff0c;AI-Chat还融合了AI绘画模型&#xff0c;例如Stable Diffusion绘画、文生图、图生图、艺…

硬件知识积累 网口接口 百兆,千兆,万兆 接口介绍与定义 (RJ45 --简单介绍)

1. 百兆网口 1.1百兆网的定义 百兆网的意思是是100Mb/S&#xff0c;中文叫做100兆位/秒。 1.2百兆网口的常用连接器 1.1.1 一般百兆网口的连接器一般是RJ45 下面是 实物图&#xff0c; 原理图&#xff0c;封装图。 1.3 百兆网口连接线的介绍 1.3.1 百兆需要使用的线的定义 百…

Flowable主要子流程介绍

1. 内嵌子流程 &#xff08;1&#xff09;说明 内嵌子流程又叫嵌入式子流程&#xff0c;它是一个可以包含其它活动、分支、事件&#xff0c;等的活动。我们通常意义上说的子流程通常就是指的内嵌子流程&#xff0c;它表现为将一个流程&#xff08;子流程&#xff09;定…

十四、流式编程(2)

本章概要 中间操作 跟踪和调试流元素排序移除元素应用函数到元素在 map() 中组合流 中间操作 中间操作用于从一个流中获取对象&#xff0c;并将对象作为另一个流从后端输出&#xff0c;以连接到其他操作。 跟踪和调试 peek() 操作的目的是帮助调试。它允许你无修改地查看…

Learn Prompt- Midjourney 图片生成:基本设置和预设

/settings指令为模型版本、样式值、质量值和升级器版本等常用选项提供切换按钮。 备注 添加到提示末尾的参数将覆盖/settings中的设置。 模型版本​ 1️⃣ MJ Version 12️⃣ MJ Version 23️⃣ MJ Version 34️⃣ MJ Version 45️⃣ MJ Version 5&#x1f308; Niji Mode&a…

数据结构与算法-时间复杂度与空间复杂度

数据结构与算法 &#x1f388;1.概论&#x1f52d;1.1什么是数据结构&#xff1f;&#x1f52d;1.2什么是算法&#xff1f; &#x1f388;2.算法效率&#x1f52d;2.1如何衡量一个算法的好坏&#xff1f;&#x1f52d;2.2算法的复杂度&#x1f52d;2.3时间复杂度&#x1f4d6;2…

Swift SwiftUI 隐藏键盘

如果仅支持 iOS 15 及更高版本&#xff0c;则可以通过聚焦和取消聚焦来激活和关闭文本字段的键盘。 在最简单的形式中&#xff0c;这是使用 FocusState 属性包装器和 focusable() 修饰符完成的-第一个存储一个布尔值&#xff0c;用于跟踪第二个当前是否被聚焦。 Code struct C…

分类预测 | MATLAB实现WOA-CNN-GRU-Attention数据分类预测

分类预测 | MATLAB实现WOA-CNN-GRU-Attention数据分类预测 目录 分类预测 | MATLAB实现WOA-CNN-GRU-Attention数据分类预测分类效果基本描述模型描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现WOA-CNN-GRU-Attention数据分类预测&#xff0c;运行环境Matlab2021b及以上&…

使用python处理MNIST数据集

文章目录 一. MNIST数据集1.1 什么是MNIST数据集1.2MNIST数据集文件格式1.3使用python访问MNIST数据集文件内容 附录程序源码 一. MNIST数据集 1.1 什么是MNIST数据集 MNIST数据集是入门机器学习/识别模式的最经典数据集之一。最早于1998年Yan Lecun在论文:[Gradient-based l…

yolo增加slide loss,改善样本不平衡问题

slide loss的主要作用是让模型更加关注难例&#xff0c;可以轻微的改善模型在难例检测上的效果 论文地址&#xff1a;https://arxiv.org/pdf/2208.02019.pdf 代码&#xff1a;GitHub - Krasjet-Yu/YOLO-FaceV2: YOLO-FaceV2: A Scale and Occlusion Aware Face Detector 样本不…

2023年“羊城杯”网络安全大赛 决赛 AWDP [Break+Fix] Web方向题解wp 全

终于迎来了我的第一百篇文章。 这次决赛赛制是AWDP。BreakFix&#xff0c;其实就是CTFFix&#xff0c;Fix规则有点难崩。Break和Fix题目是一样的。 总结一下&#xff1a;败北&#xff0c;还是太菜了得继续修炼一下。 一、Break ezSSTI 看到是SSTI&#xff0c;焚靖直接一把梭…

软件设计模式系列之十三——享元模式

1 模式的定义 享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;它旨在减少内存占用或计算开销&#xff0c;通过共享大量细粒度对象来提高系统的性能。这种模式适用于存在大量相似对象实例&#xff0c;但它们的状态可以外部化&#xff08;e…