使用DockerCompose部署服务

news/2025/1/7 16:25:06/文章来源:https://www.cnblogs.com/98kk/p/18654293

由于格式或图片解析问题,为了更好的阅读体验,可前往 阅读原文

以前我们总是用命令管理每个容器的启动、停止等等,若有多个容器时可能还存在启动优先级的问题,那就要等到指定的容器启动后再去启动另一个容器,对于整体的应用服务管理极其不方便,简单的docker run命令更适合初学者或者调试使用, docker提供docker compose来解决多容器部署。

Docker Compose是Docker官方提供的一个工具,它允许用户通过配置文件定义和运行多个 Docker 容器,以便更轻松地管理 Docker 应用程序的部署和运行。Docker Compose 可以让用户在单个主机上运行多个容器,也可以在多个主机上运行同一组容器,并且可以实现容器之间的相互通信和协作

扫码关注攻粽号,查看更多优质文章

image

优势

相比启动单个容器,使用docker compose有以下优势:

  • 简化多容器应用部署: Docker Compose 可以将多个容器的部署、启动、停止、删除等操作集成到一起,以便简化多容器应用的部署和管理。
  • 统一配置管理: Docker Compose 允许用户使用 YAML 文件定义容器的配置,从而实现容器的统一管理。这使得在多容器应用中对于环境变量、网络设置、端口映射等配置的管理更加方便和统一。
  • 容器之间的通信: Docker Compose 允许用户自定义容器之间通信的网络,容器之间可以直接通信,方便了应用程序的开发和部署。
  • 可重复性和可移植性: 使用 Docker Compose 可以将应用程序的部署过程进行标准化,降低了部署过程中的错误率。同时,Docker Compose 配置文件可以在不同的环境中使用,从而实现应用程序的可移植性。
  • 管理多个环境: Docker Compose 可以对不同的环境进行管理,比如开发环境、测试环境和生产环境,从而方便了应用程序的开发和测试。

初识DockerCompose

Docker Compose 配置文件是一个 YAML 格式的文件,用于定义多个 Docker 容器的配置和关系。下面是一个简单的 Docker Compose 配置文件示例:

version: '3'
services:web:build:context: .dockerfile: Dockerfile.webports:- "8080:80"depends_on:- redisredis:image: "redis:alpine"

在这个示例配置文件中,version 字段指定了 Docker Compose 的版本号,services 字段用于定义多个 Docker 容器。在 services 字段中,每个容器都是一个子字段,其键名是容器的名称,其值是一个包含容器配置的键值对。

在示例配置文件中,定义了两个容器 web 和 redis,其中:

  1. web 容器使用本地 Dockerfile.web 配置文件构建镜像,将容器的 80 端口映射到主机的 8080 端口,其依赖redis的启动后才会启动自己
  2. redis 容器使用 Redis 官方镜像,并使用 Alpine 版本,没有指定其他特殊的配置。

从以上可以看出docker compose是将整个应用的所有容器全部写在了同一个配置文件中,其也会自动管理容器的启动先后顺序,而对于配置文件的管理也更加方便,接下来看下其常用语法。

语法

docker compose的配置是个yaml文件,在配置文件中容器将作为服务部署,docker compose帮我们统一管理这些服务,包括镜像、启动顺序、网络、数据卷、端口、重启策略等等。配置中services、networks、volumes等这些都可以在最顶端定义表示需要创建的全局network、volume等等。

services

在Docker Compose中,services是定义容器的基本单位

语法:

services:<service_name>:<service_config>

其中,<service_name>是服务名称,可以任意命名,但建议使用有意义的名称。<service_config>是服务的配置信息,包含了运行服务所需的所有信息,如镜像、容器名称、端口映射、环境变量等。

例子:

version: '3'
services:web:image: nginxports:- "8080:80"

image

services中的每个容器都是一个服务,其都会包含镜像文件。镜像可以指定第三方的,也可以使用本地Dockerfile进行构建

语法:

# 省略其他...
<service_config># 使用第三方image: nginx:alpine# 本地构建build:context: .dockerfile: Dockerfile

你可以在容器中通过image指定第三方的镜像文件,也可以使用build来进行本地镜像的构建,build可以简写成build: your dir不需要指定上下文等等,其默认会使用当前目录下的Dockerfile文件进行构建

ports、networks、volumes

除了容器中的镜像外,其他如:端口、数据卷、网络其实都是类似,并且和直接用docker run启动容器时使用差不多

语法:

# 省略其他...
<service_config>image: nginx:alpine# 端口ports:- "<host_port>:<container_port>/<protocol>"- "1000"- "8080:80"- "443:443/tcp"# 数据卷volumes:- myvolume:/etc/data- /root/html:/etc/nginx/html# 网络networks:- mynetwork# 定义数据卷
volumes:myvolume:# 定义网络
networks:mynetwork:

上面展示了端口、数据卷、网络的基本配置:

  • 端口:在容器中使用ports来定义端口的的映射,语法如上,当仅指定一个端口是<container_port>,这种就是告诉外面容器内使用了1000端口,你可以进行映射,实际上并没有和宿主机进行映射而是一种定义,可dockerfile中的expose类似;使用<host_port>:<container_port>时前面表示宿主机端口,后者表示容器端口,二者进行映射;除此还支持协议,直接在最后加上/<protocol>即可
  • 数据卷:容器中使用volumes列表进行卷的映射,你可以直接使用宿主机的目录进行映射,也可以使用docker创建的卷,并且你还可以使用没有创建的数据卷,但同时你必须在顶级定义指定的数据卷,这样docker会帮你自动创建数据卷
  • 网络:使用网络和数据卷类似,当使用不存在的自定义的网络时,也需要在顶级进行定义

depends_on

使用depends_on字段来定义容器之间的依赖关系,以确保在启动容器时,必须先启动其所依赖的容器

语法:

depends_on:- <service_name>- <service_name2>...

其中,<service_name>是所依赖的服务名称,可以是单个服务或多个服务

例子:

version: '3'
services:db:image: mysqlweb:image: my-web-appdepends_on:- db

在这个示例中,我们定义了两个服务:一个名为db的服务,使用了mysql镜像;一个名为web的服务,使用了自定义的web应用镜像,并在depends_on字段中指定了db服务,表示web服务依赖于db服务。

在启动这个Docker Compose文件时,Docker会先启动db服务,然后再启动web服务,以确保web服务可以连接到db服务并正常运行。

environment

可以使用environment字段来设置容器中的环境变量,其与docker run -e、Dockerfile中定义的ENV类似

语法:

environment:- <key>=<value>- <key2>=<value2>...

其中,<key>是环境变量的名称,<value>是环境变量的值。可以设置多个环境变量,每个环境变量之间用-分隔

例子:

version: '3'
services:web:image: my-web-appenvironment:MYSQL_HOST: dbMYSQL_USER: userMYSQL_PASSWORD: password

在这个示例中,我们定义了一个名为web的服务,使用了自定义的web应用镜像,并设置了三个环境变量:MYSQL_HOST、MYSQL_USER和MYSQL_PASSWORD。这些环境变量可以在容器内部使用,例如在web应用的配置文件中。

需要注意的是,如果在Docker Compose文件中定义了环境变量,而在Dockerfile中也定义了同名的环境变量,那么Docker Compose文件中的环境变量会覆盖Dockerfile中的环境变量。

除此之外还可以使用.env文件或命令行参数来设置环境变量。这样可以避免将敏感信息硬编码到Docker Compose文件中
:::warning 注意
Docker Compose文件中定义的环境变量会覆盖.env文件中的同名环境变量
:::

.env配置文件示例:

MYSQL_HOST=db
MYSQL_USER=user
MYSQL_PASSWORD=password

compose文件配置:

version: '3'
services:web:image: my-web-appenvironment:MYSQL_HOST: ${MYSQL_HOST}MYSQL_USER: ${MYSQL_USER}MYSQL_PASSWORD: ${MYSQL_PASSWORD}

使用docker-compose命令的--env-file参数来指定环境变量文件。

restart

使用restart字段来定义容器的重启策略,在容器异常退出或停止时,自动重新启动容器

语法:

restart: <restart_policy>

其中,<restart_policy>是重启策略,可以是以下几种之一:

  • no:不重启容器,默认值
  • always:总是重启容器,除非手动停止容器
  • on-failure:在容器异常退出时重启容器,可以使用-t选项指定重启次数
  • unless-stopped:除非手动停止容器,否则总是重启容器

例子:

version: '3'
services:web:image: my-web-apprestart: always

在这个示例中,我们定义了一个名为web的服务,使用了自定义的web应用镜像,并设置了重启策略为always,表示总是重启容器。需要注意的是,restart字段只会在容器异常退出或停止时才会生效,而不会影响容器的启动顺序或依赖关系。

更多

关于docker compose配置的讲解就到这里,其配置和docker run很相似,关于更多配置可以查看👉官方文档

命令

有了配置文件后可以通过命令行对整个服务进行发布、构建、删除等等

docker compose [-f <arg>...] [--profile <name>...] [options] [COMMAND] [ARGS...]

build

docker compose build [OPTIONS]

用于构建Docker镜像,可以通过一些参数来自定义构建过程:

  • --no-cache:禁止使用缓存进行构建。如果使用了缓存,Docker会在构建镜像时尽可能地复用之前构建过的镜像层,以提高构建速度。使用--no-cache选项可以强制Docker从头开始构建镜像
  • --pull:在构建镜像之前,拉取最新的基础镜像。如果基础镜像版本已经过时,使用--pull选项可以确保构建的镜像使用最新的基础镜像
  • --parallel:并行构建多个Docker镜像。如果同时构建多个镜像,可以使用--parallel选项加快构建速度

up

docker compose up [OPTIONS]

用于启动Docker Compose定义的所有服务,可以通过一些参数来自定义启动过程:

  • -d:在后台模式下启动服务。如果不使用-d选项,则docker-compose up命令会在前台模式下启动服务,并输出日志信息
  • --build:在启动服务之前,自动构建镜像。如果服务的镜像已经存在,使用--build选项可以强制重新构建镜像
  • --scale:扩展指定服务的容器数量。使用--scale选项可以根据实际需要动态地扩展服务的容器数量。

stop

docker compose stop [OPTIONS] [SERVICE...]

用于停止由Docker Compose定义的服务的容器,不会删除容器、网络和卷:

  • -t:停止服务的超时时间。使用-t选项可以指定停止服务的超时时间,单位为秒
  • SERVICE:指定要停止的服务,如果只需要停止一个或几个服务的容器,可以在stop命令后面指定要停止的服务名

rm

docker compose rm [OPTIONS]

用于停止并删除由Docker Compose定义的服务的容器、网络和卷:

  • -f:强制停止并删除服务的容器、网络和卷。如果服务的容器正在运行或者网络和卷正在被使用,使用-f选项可以强制停止并删除它们
  • --stop:停止服务的容器,但不删除它们。如果只想停止服务的容器而不删除它们,可以使用--stop选项

kill

docker compose kill [OPTIONS] [SERVICE...]

用于强制停止由Docker Compose定义的服务的容器:

  • -s:指定信号量。使用-s选项可以指定要发送的信号量

更多

更多关于docker compose命令使用方法参考👉官方文档

实战

本次将部署两个容器服务:前端和后端,其中前端使用nginx进行部署,后端使用nodejs作为api服务,将nginx端口映射到宿主机,然后通过宿主机IP:Port形式访问前端页面,页面中请求后端服务,点击这里👉下载示例源码。

  1. 创建前端页面静态文件index.html:页面包括一个输入框和一个按钮,点击发送请求到/api,这里会请求nginx,nginx做反向代理到nodejs
    <input type="text">
    <button>发送</button>
    <script>const btn = document.querySelector("button")const input = document.querySelector("input")btn.addEventListener("click", () => {fetch(`/api?q=${input.value}`, {mode: "cors",method: "get"}).then(res => res.json()).then(res => console.log(res))})
    </script>
    
  2. 创建default.conf进行nginx的配置与转发:当访问/是返回前端页面,页面中的请求/api会被代理到compose-nodejs:10010,这里的compose-nodejs是nodejs的服务名,只有当compose中的容器使用同一个网络时才可以使用服务名的形式访问
    upstream backend {server compose-nodejs:10010;
    }
    server {listen 80;server_name localhost;# 首页静态页面location / {root /usr/share/nginx/html;index index.html index.htm;}# 反向代理到 nodejslocation /api {# 允许跨域add_header Access-Control-Allow-Origin $http_origin always;add_header Access-Control-Allow-Credentials true always;add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';add_header Access-Control-Allow-Headers 'content-type';if ($request_method = "OPTIONS") {return 204;}proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;proxy_set_header Host $http_host;proxy_set_header X-Nginx-Proxy true;proxy_pass http://backend;}
    }
    
  3. 创建nodejs作为后端服务:nodejs使用express作为http服务,并监听10010端口,当访问时返回code和时间戳
    const express = require("express");
    const app = express();
    app.use((req, res) => {console.log(req.url);res.json({code: 200,date: +new Date(),});
    });
    app.listen(10010, () => console.log("server is runnning on port 10010"));
    
  4. 创建docker-compose.yml配置文件:里面包含了nginx和nodejs容器,两者都是用本地的Dockerfile进行构建镜像,nginx映射宿主机10010端口到容器的80端口,并且两者的启动顺序为compose-nodejscompose-nginx,使用相同的网络compose
version: "3"
services:compose-nginx:build:context: .dockerfile: Dockerfile.nginxcontainer_name: compose-nginxports:- "10010:80"depends_on:- compose-nodejsnetworks:- composecompose-nodejs:build:context: .dockerfile: Dockerfile.nodejscontainer_name: compose-nodejsnetworks:- composenetworks:compose:
  1. 创建镜像构建文件:分别使用Dockerfile.nginxDockerfile.nodejs来构建nginx和nodejs镜像,具体配置文件如下

    Dockerfile.nginx

    FROM nginx:alpine
    COPY index.html /usr/share/nginx/html
    COPY default.conf /etc/nginx/conf.d
    EXPOSE 80
    ENTRYPOINT [ "nginx", "-g", "daemon off;" ]
    

    Dockerfile.nodejs

    FROM node:alpine
    WORKDIR /app
    COPY package.json .
    RUN npm install
    COPY server.js .
    EXPOSE 10010
    ENTRYPOINT [ "npm", "run", "server.js" ]
    
  2. 启动整体服务:

    docker compose up -d
    

参考文档

  • Compose file build reference
  • The Compose file
  • Version and name top-level element
  • Services top-level element
  • Networks top-level element
  • Volumes top-level element
  • Configs top-level element
  • Secrets top-level element
  • Command line Guides
  • NodeJS Guides

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

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

相关文章

读数据保护:工作负载的可恢复性27传统的数据保护方案

传统的数据保护方案1. 传统的数据保护方案 1.1. 备份行业有一个比较特殊的地方在于,10年或20年前设计的一些产品至今仍然有许多人在用 1.2. 在20年前,市面上的所有备份方案都是我们现在称之为传统备份产品的那种方案1.2.1. 必须自己动手把上百个UNIX系统里的数据各自备份到单…

DateTimeExtensions:一个轻量C#的开源DateTime扩展方法库

推荐一个专门为System.DateTime编写的扩展方法库。 01 项目简介 该项目主要是为System.DateTime和System.DateTimeOffset的编写的扩展方法,包括自然日期差值的文本表示(精确和人性化四舍五入)、多个时区的节假日和工作日计算。 核心扩展方法有: 1、DateTimeOffset和DateTim…

OpenVX的基本操作与支持树莓派联合开发

OpenVX支持树莓派联合开发 Khronos集团和树莓派共同致力于OpenVX的开源实现™11.3,通过了树莓派的一致性。通过一致性配置文件,开源实现了树莓派上OpenVX 1.3中指定的视觉、增强视觉和神经网络。 当Khronos标准在目标系统上可用时,应用程序开发人员可以始终自由使用这些标准…

推荐4本书《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》

4本书推荐《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》由清华大学出版社资深编辑赵佳霓老师策划编辑的新书《AI芯片开发核心技术详解》已经出版,京东、淘宝天猫、当当等网上,相应陆陆续续可以购买。该…

技术架构典型技术选型

技术架构由多种技术组成,过程中可能涉及非常多的具体技术【图】技术架构核心技术 下面我们就技术架构中核心的流量调度、服务治理、监控体系、消息列队、微服务技术框架等进一步展开介绍。 一、流量调度 流量调度是技术架构中的核心技术,包括负载均衡、API网关、配置中心,以…

什么是单向认证与双向认证

什么是SSL双向认证,与单向认证证书有什么区别 SSL/TLS 证书是用于用户浏览器和网站服务器之间的数据传输加密,实现互联网传输安全保护,大多数情况下指的是服务器证书。服务器证书是用于向浏览器客户端验证服务器,这种是属于单向认证的SSL证书。但是,如果服务器需要对客户端…

「杂文」日常 11

基于手机相册的 2024 年度总结好像一年的开头是考试周来着非常卓越的年轻就是好啊,骑车跨越半个城区去吃包子当时还是狂热粥批 给春节活动攒了大量抽嫖同学的桌游寒假打了不少生稀盐酸看起来还挺有精神的()被 jbbai 带着入坑铲了 当时那个段位乱 D 凑大羁绊就爽吃了因为看到…

块存储、文件存储、对象存储的比较分析

【摘要】本文从从应用角度比较块存储、文件存储、对象存储,对三者的层次关系进行了清晰的解读,并比较了分布式存储在块存储、文件存储、对象存储的应用成效。 一、块存储、文件存储、对象存储三者的本质差别 1.1 块存储 典型设备:磁盘阵列,硬盘 块存储主要是将裸磁盘空间整…

分析基于ASP.NET Core Kernel的gRPC服务在不同.NET版本的不同部署方式的不同线程池下的性能表现

分析基于ASP.NET Core Kernel的gRPC服务在不同.NET版本的不同部署方式的不同线程池下的性能表现 使用默认的 gRPC 项目模板创建,垃圾回收器类型为 ServerGC(Server garbage collection)。 使用 ghz 工具在不同的请求总数、连接数、并发数的参数下,进行压力测试,接口为 /gree…

Python学习(七)——配套《PyTorch深度学习实战》

1. 介绍一下下面这张图推荐系统自己还差点就去研究了这张图片概述了几种数据分析和机器学习的应用场景,包括推荐系统、网页搜索、舆情分析、关联规则、社交网络分析以及天气预测。下面是对每个部分的详细解释: 推荐系统用户u, 商品i:推荐系统旨在为特定用户(u)推荐商品(i…

golang1.23版本之前 Timer Reset方法无法正确使用

在 Go 1.23 之前,正确使用 Timer.Reset 是一个挑战,因为 Stop 和抽取操作之间的状态可能不一致,导致定时器异常触发。最好的做法是避免复用定时器,每次都创建一个新的定时器,这样代码更简洁、健壮,也更容易维护。golang1.23版本之前 Timer Reset方法无法正确使用 golang1…

【kafka】携程基于Kafka的数据校验代理在FinOps领域的应用

一、现状与问题1.1 现状1.2 问题描述1.3 解决方案二、设计与核心实现2.1 Kafka的相关背景知识2.2 Kafka Gatekeeper的设计和实现三、总结以下文章来源于携程技术 ,作者懿涵作者简介 懿涵,携程HybridCloud团队云原生研发工程师,关注云原生、IaC领域。为了有效管理云成本,基于…