【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应用程序性能的秘诀
文章目录 🍊 JVM调优🎉 增大Eden 空间大小🎉 如果MinorGC 频繁,且容易引发 Full GC📝 S1 区大小 < MGC 存活的对象大小,对象的年龄才1岁📝 相同年龄的对象所占总空间大小>s1区空间大小的一…...

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

Linux 进程切换与命令行参数
假设进程1现在要切走了,切入进程2.那进程1就要先保存数据,方便以后恢复, 然后进程2再切走,进程1再把数据还原: 操作系统又分为实时操作系统和分时操作系统。 实时操作系统是是给操作系统一个进程,操作系统…...

Python基础入门例程6-NP6 牛牛的小数输出
目录 描述 输入描述: 输出描述: 示例1 解答: 说明: 描述 牛牛正在学习Python的输出,他想要使用print函数控制小数的位数,你能帮助它把所有读入的数据都保留两位小数输出吗? 输入描述&a…...
传奇游戏常见问题解决办法
GEE合区出现错误常规解决方案 GEE合区出现错误大部分因数据库损坏导致的合区报错,如果合区提示内存不足,更新64位合区,使用64位合区工具在服务器上进行合并,合区需要将2个区数据大部分提取到内存中,32位合区工具支持内…...
2310D的dll问题
原文 我正在开发一个游戏引擎,偶然发现了一些空针问题. 考虑此简单程序: class Test {void doIt(){} } void main() {Test t;t.doIt(); }它编译,然后在Linux上使用DMD时,用11信号干掉了. 如果使用Java,甚至不会构建该程序,因为它会失败,说明从未初化它. 但我不关心分析器,我宁…...

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

Qt第六十五章:自定义菜单栏的隐藏、弹出
目录 一、效果图 二、qtDesigner 三、ui文件如下: 四、代码 一、效果图 二、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++项目:网络版五子棋对战之数据管理模块-游戏房间管理模块的设计
文章目录 一、意义二、功能三、作用四、游戏房间类基本框架五、游戏房间管理类基本框架七、游戏房间类代码八、游戏房间管理类代码 一、意义 对匹配成功的玩家创建房间,建立起一个小范围的玩家之间的关联关系! 房间里一个玩家产生的动作将会广播给房间里…...

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

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

【超详细】CentOS 7安装MySQL 5.7【安装及密码配置、字符集配置、远程连接配置】
准备工作:CentOS 7系统,并确保可以联通网络 1、获取MySQL 5.7 Community Repository软件包 注意:这里使用的是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 版本选型问题中提及:如果要使用ik插件,是不是就使用目前最新的IK对应elasticsearch的版本“8.8.2”? https://github.com/medcl/elasticsearch-analysis-ik/releases/ta…...

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

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

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

[C语言]排序的大乱炖——喵喵的成长记
宝子,你不点个赞吗?不评个论吗?不收个藏吗? 最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!! 喵喵喵,你对我真的很重要…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...