使用 docker-compose 构建你的项目

最近再次手撕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: Dockerfile
    container_name: node-server-1 # 容器名称
    ports: # 暴露的端口
        - "3000:3000"
    restart: always # 自动重启
    environment: # 设置环境变量
        - NODE_ENV=production
    command: npm run start # 覆盖容器启动后默认执行的命令

构建镜像

docker-compose build

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

运行容器

docker-compose up -d

报错

[root@dev07 music]# docker-compose up -d
Creating node-server-1 ... error

Creating 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 "39e4c77c6c5215731eef4a


ERROR: 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=production
        networks: # 加入网络
            - "my-network"
        command: npm run start # 覆盖容器启动后默认执行的命令
    nginx:
        image: nginx:latest 指定 nginx 镜像
        ports: # 将本机的 8080 端口映射到容器的80端口
            - "8080:80"            
        container_name: nginx-node
        restart: always
        volumes: # 映射本机 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=production
        networks: # 加入网络
            - "my-network"
        command: npm run start # 覆盖容器启动后默认执行的命令
    nginx:
        image: nginx:latest 指定 nginx 镜像
        ports: # 将本机的 8080 端口映射到容器的80端口
            - "8080:80"            
        container_name: nginx-node
        restart: always
        volumes: # 映射本机 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;
    }
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮华落定

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值