当前位置: 首页 > news >正文

【Docker】Docker Compose的使用

我们知道使用一个Dockerfile模板文件,可以让用户很方便的定义⼀个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。

例如要实现一个Web项目,除了Web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等,我们只能一个一个写dockerfile文件,然后bulid构建和run,手动操作单个容器。

Docker Compose恰好满足了这样的需求。它允许⽤户通过⼀个单独的docker-compose.yml模板⽂件(YAML格式)来定义⼀组相关联的应⽤容器为⼀个项⽬(project)。

在这里插入图片描述

docker-compose基础概念

docker-compose项目是docker官方的开源项目,负责实现对docker容器集群的快速编排。

docker-compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器(containner)

  • docker-compose运行目录下的所有文件(docker-compose.yml文件、extends文件或环境变量等)组成一个工程,如无特殊指定,工程名即为当前目录名。
  • 一个工程当中,可以包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖。
  • 一个服务中可以包括多个容器实例,docker-compose并没有解决负载均衡的问题。因此需要借助其他工具实现服务发现及负载均衡,比如nginx。

docker-compose的安装

Docker安装完成后,docker-compose也随之自动安装:

$ docker-compose --version
docker-compose version 1.25.0, build unknown

最新版本号可以在这里查询:https://github.com/docker/compose/releases

没有安装的可以使用下面的命令进行安装:

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose$ sudo chmod +x /usr/local/bin/docker-compose$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c

熟悉python的朋友,可以使用pip去安装docker-Compose:

$ pip install docker-compose

docker-compose文件的语法结构

docker compose文件的语法说明 https://docs.docker.com/compose/compose-file/

version: "3.8" # 可选,docker compose语法的版本services: # 容器servicename: # 服务名字,这个名字也是内部 bridge网络可以使用的 DNS nameimage: # 镜像的名字command: # 可选,如果设置,则会覆盖默认镜像里的 CMD命令environment: # 可选,相当于 docker run里的 --envvolumes: # 可选,相当于docker run里的 -vnetworks: # 可选,相当于 docker run里的 --networkports: # 可选,相当于 docker run里的 -pservicename2:volumes: # 可选,相当于 docker volume createnetworks: # 可选,相当于 docker network create

程序准备

准备一个Python文件,名字为app.py内容如下:

from flask import Flask
from redis import Redis
import os
import socketapp = Flask(__name__)
redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)@app.route('/')
def hello():redis.incr('hits')return f"Hello Container World! I have been seen {redis.get('hits').decode('utf-8')} times and my hostname is {socket.gethostname()}.\n"

准备Dockerfile

准备一个Dockerfile

FROM python:3.9.5-slimRUN pip install flask redis && \groupadd -r flask && useradd -r -g flask flask && \mkdir /src && \chown -R flask:flask /srcUSER flaskCOPY app.py /src/app.pyWORKDIR /srcENV FLASK_APP=app.py REDIS_HOST=redisEXPOSE 5000CMD ["flask", "run", "-h", "0.0.0.0"]

镜像准备

构建flask镜像,准备一个redis镜像。

$ docker image pull redis$ docker image build -t flask-demo .$ docker image ls
REPOSITORY   TAG          IMAGE ID       CREATED          SIZE
flask-demo   latest       e878470f65a4   13 minutes ago   128MB
redis        latest       7614ae9453d1   21 months ago    113MB
python       3.9.5-slim   c71955050276   2 years ago      115MB

创建一个docker bridge

$ docker network create -d bridge demo-network
adc45a365e7294f56b65464eb88a212624855b52dc568c9f70c4e39c31d43e4a$ docker network ls
NETWORK ID     NAME           DRIVER    SCOPE
28e45b9b8f4b   bridge         bridge    local
adc45a365e72   demo-network   bridge    local
29c08e905dab   host           host      local
d466db2f54a1   none           null      local

创建redis container

创建一个名为redis-server的container,连到demo-network上:

$ docker container run --rm -d --name redis-server --network demo-network redis
ff46dca96a56f8ce739732a87e2407fffcbc4a16651638aed15224ea9e355a6a$ docker container ls
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS      NAMES
ff46dca96a56   redis     "docker-entrypoint.s…"   24 seconds ago   Up 23 seconds   6379/tcp   redis-server

创建flask container

创建一个名为flask-demo的container,连到demo-network上:

$ docker container run --rm -d --network demo-network --name flask-demo --env REDIS_HOST=redis-server -p 5000:5000 flask-demo
a843952b19fc98f8dfd8a46eac18abb8885834a1f718de5ca265f09795db0f2a$ docker container ls
CONTAINER ID   IMAGE        COMMAND                  CREATED              STATUS          PORTS                                       NAMES
a843952b19fc   flask-demo   "flask run -h 0.0.0.0"   About a minute ago   Up 59 seconds   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   flask-demo
ff46dca96a56   redis        "docker-entrypoint.s…"   9 minutes ago        Up 9 minutes    6379/tcp                                    redis-server

访问http://127.0.0.1:5000应该能看到类似下面的内容,每访问一次,计数加1:

$ curl http://127.0.0.1:5000
Hello Container World! I have been seen 1 times and my hostname is a843952b19fc.

可以把上面的步骤合并到一起,成为一个部署脚本:

# prepare image
docker image pull redis
docker image build -t flask-demo .# create network
docker network create -d bridge demo-network# create container
docker container run -d --name redis-server --network demo-network redis
docker container run -d --network demo-network --name flask-demo --env REDIS_HOST=redis-server -p 5000:5000 flask-demo

改造为Docker Compose

以上面的Python Flask + Redis练习为例子,改造成一个docker-compose文件。

docker-compose.yml文件如下:

version: "3.8"services:flask-demo:image: flask-demo:latestenvironment:- REDIS_HOST=redis-servernetworks:- demo-networkports:- 8080:5000redis-server:image: redis:latestnetworks:- demo-networknetworks:demo-network:

docker-compose常用命令

运行这些命令需要结合docker-compose一起使用,且必须要在含有docker-compose.yml文件的目录中或者使用-f参数指定docker-compose.yml文件才可以使用,不然报错。

docker-compse up

docker-compse up创建和启动容器。

$ docker-compose up -d
Starting app_redis-server_1 ... done
Starting app_flask-demo_1   ... done

如果想要服务后台运行,需要带上-d参数。

docker-compose ps

docker-compose ps列出容器。

$ docker-compose psName                     Command               State                    Ports
------------------------------------------------------------------------------------------------------
app_flask-demo_1     flask run -h 0.0.0.0             Up      0.0.0.0:8080->5000/tcp,:::8080->5000/tcp
app_redis-server_1   docker-entrypoint.sh redis ...   Up      6379/tcp

down 删除容器、网络、数据卷和镜像
stop/start/restart 停止/启动/重启服务

docker-compose stop

docker-compose stop停止服务。

$ docker-compose stop
Stopping app_redis-server_1 ... done
Stopping app_flask-demo_1   ... done

docker-compose start

docker-compose start启动服务。

$ docker-compose start
Starting flask-demo   ... done
Starting redis-server ... done

docker-compsoe restart

docker-compose restart重启服务。

$ docker-compose restart
Restarting app_redis-server_1 ... done
Restarting app_flask-demo_1   ... done

docker-compse down

docker-compse down删除容器、网络、数据卷和镜像。

$ docker-compose down
Stopping app_redis-server_1 ... done
Stopping app_flask-demo_1   ... done
Removing app_redis-server_1 ... done
Removing app_flask-demo_1   ... done

docker-compse logs

docker-compse logs查看服务容器的输出。

$ docker-compose logs -f
Attaching to app_flask-demo_1, app_redis-server_1
flask-demo_1    |  * Serving Flask app 'app.py'
flask-demo_1    |  * Debug mode: off
flask-demo_1    | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
flask-demo_1    |  * Running on all addresses (0.0.0.0)
flask-demo_1    |  * Running on http://127.0.0.1:5000
flask-demo_1    |  * Running on http://172.21.0.3:5000
flask-demo_1    | Press CTRL+C to quit
。。。 。。。

docker-compose top

docker-compose top显示正在运行的容器进程。

$ docker-compose top
app_flask-demo_1UID       PID    PPID    C   STIME   TTY     TIME                                CMD
-----------------------------------------------------------------------------------------------------------------
systemd+   11265   11244   2   16:31   ?     00:00:00   /usr/local/bin/python /usr/local/bin/flask run -h 0.0.0.0app_redis-server_1UID       PID    PPID    C   STIME   TTY     TIME             CMD
---------------------------------------------------------------------------
systemd+   11078   11059   0   16:30   ?     00:00:00   redis-server *:6379

docker-compose scale

docker-compose scale指定一个服务容器启动数量。

现在推荐使用docker-compose up -d --scale

$ docker-compose scale redis-server=2
WARNING: The scale command is deprecated. Use the up command with the --scale flag instead.
Starting app_redis-server_1 ... done
Creating app_redis-server_2 ... done$ docker-compose psName                     Command                State                      Ports
---------------------------------------------------------------------------------------------------------
app_flask-demo_1     flask run -h 0.0.0.0             Up         0.0.0.0:8080->5000/tcp,:::8080->5000/tcp
app_redis-server_1   docker-entrypoint.sh redis ...   Up         6379/tcp
app_redis-server_2   docker-entrypoint.sh redis ...   Up         6379/tcp$ docker-compose up -d --scale redis-server=1
app_flask-demo_1 is up-to-date
Stopping and removing app_redis-server_2 ... done
Starting app_redis-server_1              ... done

docker-compose exec

docker-compose exec在容器里面执行命令。

$ docker-compose exec --index=2 redis-server bash
root@7b36aecb80d1:/data#

docker-compse build

docker-compse build重新构建服务。

将上面的docker-compose.yml修改如下:

version: "3.3"services:flask-demo:build:context: .dockerfile: Dockerfileimage: flask-demo:latestenvironment:- REDIS_HOST=redis-servernetworks:- demo-networkports:- 8080:5000redis-server:image: redis:latestnetworks:- demo-networknetworks:demo-network:

主要是将flask-demo的镜像改为从Dockerfile构建而不是使用已有镜像。

$ docker-compose build
redis-server uses an image, skipping
Building flask-demo
Step 1/8 : FROM python:3.9.5-slim---> c71955050276
Step 2/8 : RUN pip install flask redis &&     groupadd -r flask && useradd -r -g flask flask &&     mkdir /src &&     chown -R flask:flask /src---> Using cache---> 41091d3d13c5

相关文章:

【Docker】Docker Compose的使用

我们知道使用一个Dockerfile模板文件,可以让用户很方便的定义⼀个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。 例如要实现一个Web项目,除了Web服务容器本身,往往还需要…...

2023年中国调速器产量、销量及市场规模分析[图]

调速器行业是指生产、销售和维修各种调速器设备的行业。调速器是一种能够改变机械传动系统输出转速的装置,通过调整输入和输出的转速比来实现转速调节的功能。 调速器行业分类 资料来源:共研产业咨询(共研网) 随着工业自动化程度…...

深入了解JVM调优:解锁Java应用程序性能的秘诀

文章目录 &#x1f34a; JVM调优&#x1f389; 增大Eden 空间大小&#x1f389; 如果MinorGC 频繁&#xff0c;且容易引发 Full GC&#x1f4dd; S1 区大小 < MGC 存活的对象大小&#xff0c;对象的年龄才1岁&#x1f4dd; 相同年龄的对象所占总空间大小>s1区空间大小的一…...

[java进阶]——线程池的使用,自定义线程池

&#x1f308;键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 一、线程池的存在意义 二、线程池的使用 2.1线程池的核心原理 2.2线程池的代码实现 三、自定义线程池 3.1线程池的参数详解 3.2线程池的执行原理 3.3灵魂两问 3.4线程池多大合适 3.5拒绝策略 一、线程池…...

Linux 进程切换与命令行参数

假设进程1现在要切走了&#xff0c;切入进程2.那进程1就要先保存数据&#xff0c;方便以后恢复&#xff0c; 然后进程2再切走&#xff0c;进程1再把数据还原&#xff1a; 操作系统又分为实时操作系统和分时操作系统。 实时操作系统是是给操作系统一个进程&#xff0c;操作系统…...

Python基础入门例程6-NP6 牛牛的小数输出

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 示例1 解答&#xff1a; 说明&#xff1a; 描述 牛牛正在学习Python的输出&#xff0c;他想要使用print函数控制小数的位数&#xff0c;你能帮助它把所有读入的数据都保留两位小数输出吗&#xff1f; 输入描述&a…...

传奇游戏常见问题解决办法

GEE合区出现错误常规解决方案 GEE合区出现错误大部分因数据库损坏导致的合区报错&#xff0c;如果合区提示内存不足&#xff0c;更新64位合区&#xff0c;使用64位合区工具在服务器上进行合并&#xff0c;合区需要将2个区数据大部分提取到内存中&#xff0c;32位合区工具支持内…...

2310D的dll问题

原文 我正在开发一个游戏引擎,偶然发现了一些空针问题. 考虑此简单程序: class Test {void doIt(){} } void main() {Test t;t.doIt(); }它编译,然后在Linux上使用DMD时,用11信号干掉了. 如果使用Java,甚至不会构建该程序,因为它会失败,说明从未初化它. 但我不关心分析器,我宁…...

包管理工具

代码共享方案 放到npm仓库&#xff0c;下载到本地放到node_modules npm配置文件 必须填写的属性&#xff1a;name、version name是项目的名称&#xff1b; version是当前项目的版本号&#xff1b; description是描述信息&#xff0c;很多时候是作为项目的基本描述&#xff1b…...

Qt第六十五章:自定义菜单栏的隐藏、弹出

目录 一、效果图 二、qtDesigner 三、ui文件如下&#xff1a; 四、代码 一、效果图 二、qtDesigner 原理是利用属性动画来控制QFrame的minimumWidth属性。 ①先拖出相应的控件 ②布局一下 ③填上一些样式 相关QSS background-color: rgb(238, 242, 255); border:2px sol…...

element table中嵌套el-select 无法选择问题

<el-table-column align"left" label"姓名" show-overflow-tooltip :key"tableKey"><template slot-scope"scope"><el-select placeholder"请选择" :disabled"!saveButton" v-model"scope.ro…...

2.6.C++项目:网络版五子棋对战之数据管理模块-游戏房间管理模块的设计

文章目录 一、意义二、功能三、作用四、游戏房间类基本框架五、游戏房间管理类基本框架七、游戏房间类代码八、游戏房间管理类代码 一、意义 对匹配成功的玩家创建房间&#xff0c;建立起一个小范围的玩家之间的关联关系&#xff01; 房间里一个玩家产生的动作将会广播给房间里…...

计算机视觉中的数据预处理与模型训练技巧总结

计算机视觉主要问题有图像分类、目标检测和图像分割等。针对图像分类任务&#xff0c;提升准确率的方法路线有两条&#xff0c;一个是模型的修改&#xff0c;另一个是各种数据处理和训练的技巧(tricks)。图像分类中的各种技巧对于目标检测、图像分割等任务也有很好的作用&#…...

GeoHash分享

写在前边 复制的一个内部分享&#xff0c;所以可能更偏向PPT性质&#xff0c;本文提出的问题&#xff0c;在末尾参考材料中都会有所提及&#xff0c;包括更深层次的实现原理和各大API对于GeoHash的优化。感兴趣的读者可以拓展看一下。 START GeoHash是一种地址编码&#xff…...

【超详细】CentOS 7安装MySQL 5.7【安装及密码配置、字符集配置、远程连接配置】

准备工作&#xff1a;CentOS 7系统&#xff0c;并确保可以联通网络 1、获取MySQL 5.7 Community Repository软件包 注意&#xff1a;这里使用的是root用户身份。 wget https://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm2、安装软件包 rpm -ivh mysql5…...

Elasticsearch 8.X 分词插件版本更新不及时解决方案

1、关于 Elasticsearch 8.X IK 分词插件相关问题 球友在 ElasticSearch 版本选型问题中提及&#xff1a;如果要使用ik插件&#xff0c;是不是就使用目前最新的IK对应elasticsearch的版本“8.8.2”&#xff1f; https://github.com/medcl/elasticsearch-analysis-ik/releases/ta…...

Delete `␍`eslintprettier/prettier

将CRLF改为LF 然后就消失了 除此之外,也可以修改git全局配置 git config --global core.autocrlf false...

4种实用的制作URL 文件的方法

很多小伙伴有自己的博客、淘宝或者共享文件网站&#xff0c;想要分享、推广自己的网址做成url文件&#xff0c;让别人点击这个url文件直接访问自己的网站。URL文件其实就一个超级链接&#xff0c;制作的方法很多&#xff0c;这里列举4种。 收藏网站直接拖拽 1.第一种&#xf…...

css总结

记录做项目经常会写到的css 1、左边导航栏固定&#xff0c;右边div占满剩余宽度 <template><div class"entrance"><div class"left"></div><div class"right"><div class"content"></div>…...

[C语言]排序的大乱炖——喵喵的成长记

宝子&#xff0c;你不点个赞吗&#xff1f;不评个论吗&#xff1f;不收个藏吗&#xff1f; 最后的最后&#xff0c;关注我&#xff0c;关注我&#xff0c;关注我&#xff0c;你会看到更多有趣的博客哦&#xff01;&#xff01;&#xff01; 喵喵喵&#xff0c;你对我真的很重要…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...