[Ручная серия] Создайте свой проект с помощью docker-compose

Node.js Docker
[Ручная серия] Создайте свой проект с помощью docker-compose

предисловие

Прошло больше полугода с тех пор, как я в последний раз писал статью в Наггетс (в основном из-за своего низкого уровня, не знаю, что написать).

Однако в новом году всегда пишите что-нибудь подытоживающее и подытоживающее.

я ей недавно пользоваласьdocker. Поэтому я хочу поделиться этими знаниями. Я не знаю, лучшая ли это практика, добро пожаловать, наступи на меня.

1. Docker

dockerЧто это?На платформе Nuggets было много статей, и оценки, которые я привел, не так хороши, как они. Итак, когда у каждого есть определенная основа Docker

Поэтому эта статья в основном посвящена реальному боевому содержанию.Если у вас есть конкретная теория, вы можете поискать другие статьи, чтобы узнать о ней. или перейти на официальный сайт

1.1 Установка

windowсистема илиmacosСистему можно скачать прямо с официального сайтаDocker Desktop,Связь:Hubei.docker.com/?overlay=on…

Тогда это дурацкая установка, которая здесь не будет представлена.

Уведомление: windowДля установки требуется корпоративная версия, но домашняя версия не может быть установлена ​​(или установка более хлопотная)

1.2 docker-compose

после установкиDocker DesktopПосле этого он будет автоматически установлен по умолчаниюdocker-compose

Вы можете попробовать сами в командной строке, чтобы увидеть текущую версию

docker-compose -v
docker -v

2 Подготовьте проект

2.1 Инициализироватьnodeпроект

  1. инициализацияpackage.json
npm init -y
  1. Создайте http-сервер Здесь используетсяexpress,использоватьkoaхорошо, смотри, что тебе нравится
npm install express
  1. написать код
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')
})
  1. подготовить один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
  1. построить образ
docker build .

  1. После успешной сборки создайте контейнер
docker run --name node-server-1 -p 3000:3000 node-server
  1. Используйте браузер для доступа к порту 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: . # 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

Если ничего другого, доступ через браузер3000Доступ к порту также возможен в обычном режиме.

3.2 Организация нескольких сервисов

Например, теперь нам нужно построитьnginxсервис для прокси-запросов к нашемуnode-server, то нам нужно построить два сервиса

Тогда вот проблема

  • nginxКак контейнер использует мой собственныйnginx.confконфигурационный файл

    • в состоянии пройтиvolumesсопоставление файлов
  • nginxконтейнер иnode-serverКак общаются контейнеры

    1. можно использоватьdocker-inspectкоманда для просмотраnode-serverконтейнерIPадрес, а затем изменитьnginx.confКонфигурация,
    2. использовать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. Горизонтальное масштабирование узловых сервисов

При относительно небольшом количестве пользователей нам достаточно одного сервиса узла, при большом количестве пользователей одного сервиса узла недостаточно.

В нормальных условиях это обновление машины, добавление сервисов и передачаnginxБалансировка нагрузки

Как мы передаем docker-compose быстрое расширение уровня обслуживания?

4.1 scale

docker-compose предоставляет нам команду масштабирования для быстрого локального создания нескольких сервисов.

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

пройти через--scale node=5Мы строим 5 узловых сервисов

Однако, если ничего другого, сборка завершится ошибкой, и будет сообщено об ошибке занятости порта.

Потому что каждый из наших узловых сервисов занимает порт 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Эта служба узла включена,

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;
    }
} 

5. Резюме

Наше текущее расширение — это масштабирование в автономной среде.Независимо от того, насколько расширена услуга, она может быть ограничена только автономной средой. Но ресурсы одного сервера ограничены, так как же расширить несколько серверов? Тогда вам нужно использовать технологию роя. У меня будет возможность поделиться этим в следующий раз.

Из-за ограниченного технического уровня вы можете указать на плохой текст и слегка распылить!

Добро пожаловать, чтобы следовать

Добро пожаловать в общедоступный номер»разработка кода», делясь последней технической информацией каждый день

image