该文章已被《从零开始学docker》收录

之前在制作dockerfile的时候,流程是写完然后build然后run,这还是单个的容器,比如公司有五十个微服务,难道要打包五十个docker吗,依赖关系啥的手动操作很麻烦!这个时候使用dockercompose高效的管理,可以定义运行多个容器!
定义,运行多个容器。 YAML file配置文件,single command 命令有哪些。所有环境都可以使用dockercompose,以及它的三个步骤:
1.定义应用的环境dockerfile,保证项目在任何地方都可以运行
2.定义一个服务,把应用写在dockercomposeyml文件里。
3.启动跟停止项目
compose是docker官方的开源项目,需要安装!
dockerfile让程序在任何地方运行。在一个web服务,链接redis,mysql,nginx等一个一个启动太麻烦了,compose为此而生。
docker-compose是docker官方提供的容器编排工具!
官方文档是这样的
version: "3.9" # optional since v1.27.0
services:
web:
build: .
ports:
- "8000:5000"
volumes: #持久化挂载
- .:/code
- logvolume01:/var/log
links:
- redis
redis: #redis和web写在了一起,links是连接在一起,先启动redis然后启动web,运行之后他们同时启动了,不用一个一个run了!哪怕有一百个服务,文件写不错就能上线。
image: redis
volumes:
logvolume01: {}
compose重要概念
1.服务services,容器,应用(web,redis,mysql都可以想成单独的服务),跑起来是一个完整的项目。
2.可以把它想象成一个项目,project。也就是一组关联的容器!
下载
curl -SL https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

有compose就完成了。
#然后是授权 其实这就是一个二进制文件
chmod +x /usr/local/bin/docker-compose
#然后可以执行了!
[root@VM-16-7-centos bin]# docker-compose version
docker-compose version 1.25.5, build 8a1c60f6
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
#看到version就算成功了
Compose 项目是由Python编写的,实际上就是调用了Docker服务提供的API来对容器进行管理,因此,只要所在的操作系统的平台支持Docker API,就可以在其上利用Compose来进行编排管理。
compose 中常常提及的概念:
project
通过 docker compose 管理的一个项目被抽象称为一个 project,它是由一组关联的应用容器组成的一个完整的业务单元。简单点说就是一个 docker-compose.yml 文件定义一个 project。
我们可以在执行 docker-compose 命令时通过 -p 选项指定 project 的名称,如果不指定,则默认是 docker-compose.yml 文件所在的目录名称。
service
运行一个应用的容器,实际上可以是一个或多个运行相同镜像的容器。可以通过 docker-compose up 命令的 --scale 选项指定某个 service 运行的容器个数,比如:
docker-compose up -d --scale redis=2
compose流程调用

重新启动 services
前面我们提到当前宿主机已经存在与该应用对应的容器,docker-compose 会进行判断并决定是否重新启动已有服务。
强制 recreate
Recreate 就是删除现有的容器并且重新创建新的容器,为 docker-compose up 命令指定 --force-recreate 选项可以强制 recreate 容器。
创建个别容器
如果应用中的个别 service 对应的容器被删除了,docker-compose up 命令会新建相关的容器。
启动个别容器
与上面类似,如果应用中的个别 service 对应的容器被停止(stop)了,docker-compose up 命令会重新启动相关的容器。
跟着官方来搞一个玩玩
1.创建一个目录然后进入。
[root@VM-16-7-centos home]# mkdir composetest
[root@VM-16-7-centos home]# cd composetest/
[root@VM-16-7-centos composetest]# ls
2.创建一个文件(app.py)在当前目录下!
import time #时间
import redis #redis
from flask import Flask #flask的框架
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379) #redis缓存 调用redis
def get_hit_count():
retries = 5
while True:
try:
return cache.incr('hits') #每次调用都会自增 使用了redis的incr
except redis.exceptions.ConnectionError as exc:
if retries == 0:
raise exc
retries -= 1
time.sleep(0.5)
@app.route('/') #访问
def hello():
count = get_hit_count() #计数器+1
return 'Hello World! I have been seen {} times.\n'.format(count)
然后写一个依赖包 requirements.txt
flask
redis
这是未来dockerfile里要用的,单独没啥用
写一个dockerfile
vim Dockerfile
FROM python:3.7-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python","app.py"]
在compose里部署一个服务,以前是一个一个run服务,现在定义一个docker-compose.yml
version: "3.9" #版本
services: #服务
web: #web服务
build: . #web使用build让dockerfile生成镜像
ports:
- "8000:5000"
redis: #redis服务
image: "redis:alpine" #使用官方现成的镜像 也可以自己写!
最后buildandrun一下就可以了docker-compose up
1.创建网络
2.启动yaml
3.启动服务

正常启动成功有两个服务

[root@VM-16-7-centos ~]# curl 172.18.0.2:5000
Hello World! I have been seen 1 times.
[root@VM-16-7-centos ~]# curl 172.18.0.2:5000
Hello World! I have been seen 2 times.
[root@VM-16-7-centos ~]# curl 172.18.0.2:5000
Hello World! I have been seen 3 times.
[root@VM-16-7-centos ~]# curl 172.18.0.2:5000
Hello World! I have been seen 4 times.
[root@VM-16-7-centos ~]# curl 172.18.0.2:5000
Hello World! I have been seen 5 times.
[root@VM-16-7-centos ~]# curl 172.18.0.2:5000
Hello World! I have been seen 6 times.
#访问结果
docker images查看 docker compose的东西全都自动下载了

网络规则
只要通过compose启动就会生成自己的网络!
比如运行十个服务,要打包成一个项目,这个项目上了之后对内网络十分麻烦,compose自动帮我们维护了这些(项目中内容都在同一个网络下面。域名访问)
我们现在就可以写mysql:3306来访问了!
可能有十个容器实例,都跑的mysql,十个就是十个ip写死了肯定不行,这个时候我们把它们写成mysql,访问就会通过mysql到后面这里。

用docker network inspect 服务名来查看这个 发现没有问题

如果没有在一个网络下或者没有联通是ping不通的 官方这里把host改成redis了,可以直接通过redis访问!如果在同一个网络下就直接通过域名访问,如果服务挂了重新拉就行了,比如这里的redis是03,可能重新拉是04,重新拉之后连接还是没有问题,这就是好处。
可以通过编写dockercompose yaml文件一键启动所有服务!
docker compose yaml 核心
# 只有3层
version: #版本,是和docker对应的
services: #服务 也是核心
服务1: web
#服务配置
images
build
network
...
服务2: redis
...
服务3: redis
...
#其他配置 网路配置/卷挂载/全局规则
volumes:
netwokrs:
configs:
#可以在官方网站的version右边查看yaml的编写信息

然后很重要的这个:依赖,我们项目是有启动顺序的,比如web启动需要redis,现在得保证先启动redis,不然web启动会报错,这个时候需要使用depends_on保证关系,比如上面web依赖于redis和postgres,web下面要写depends_on这两个。

后面dns,entrypoint,environment环境都可以配置 比如mysql密码

1.创建目录 my_wordpressr然后进入
2.写docker-compose.yml
version: "3.9"
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- wordpress_data:/var/www/html
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
wordpress_data: {}
服务里第一个是db数据库 第二个是wordpress,博客,博客下面有dpon先启动db 然后restart是否重启 always总是重启 environment是键值对(默认规则) 下面的是image 下载了镜像,然后暴露8000端口,然后env是怎么连接数据库 密码 名字 用户名等 然后是volumes 数据卷。
然后可以直接访问ip:8000了!可以在后台看到日志信息
docker-compose -d也是后台启动
| 命令 | 功能 |
|---|---|
| docker-compose -h | 查看帮助 |
| docker-composeup | 启动所有docker-compose服务 |
| docker-composeup -d | 启动所有docker-compose服务并后台运行 |
| docker-composedown | 停止并删除容器、网络、卷、镜像 |
| docker-composeexec ${yml内服务的id} /bin/bash | 进入容器实例内部 |
| docker-composeps | 展示当前docker-compose编排过的运行的所有容器 |
| docker-composetop | 展示当前docker-compose编排过的容器进程 |
| docker-composelogs ${yml内服务的id} | 查看容器输出日志 |
| docker-composeconfig | 检查配置 |
| docker-composeconfig -q | 检查配置,有问题才输出 |
| docker-composerestart | 重启服务 |
| docker-composestart | 启动服务 |
| docker-composestop | 停止服务 |
Docker篇终于完结了!如果我的文章帮助到你了,希望你可以给我个关注,点赞,收藏支持一下,这将是我更新的动力,感谢你们的支持!咱们k8s见!

这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
我正在开发一个Rails应用程序,我需要在其中找到给定特定偏移量或时区的夏令时开始和结束日期。我基本上在我的数据库中保存了从用户浏览器接收到的时区偏移量(“+3”,“-5”),我想在它出现时修改它由于夏令时的变化。我知道Time实例变量有dst?和isdst方法,如果存储在它们中的日期在夏令时与否。>Time.new.isdst=>true但是使用它来查找夏令时的开始和结束日期会占用太多资源,而且我还必须为我拥有的每个时区偏移量执行此操作。我想知道更好的方法。 最佳答案 好的,基于你所说的和@dhouty'sanswer:您希望能够
我有一台生产机器和一台开发机器,都运行ubuntu8.10并且都运行最新的phusionpassenger。当我在osx上的本地开发机器上使用ruby1.9.1时,我想知道外面的人是否已经在使用带有ruby1.9.1甚至1.9.2的phusionpassenger?如果是这样,请告诉我们您的设置!此外,有没有办法在apache上使用phusionpassenger同时运行ruby1.8.7(ree)和1.9.1?感谢您的指点,我在任何地方都找不到任何提示... 最佳答案 是的,从某些2.2.x版本开始就正式支持它,我不记
date_select方法只能设置:start_year,但我想设置开始日期(例如3个月前的日期)(但没有这样的选项)。那么,我可以将开始日期设置为date_select方法吗?或者,要制作这样的选择框,我应该使用select_tag和options_for_select吗?或者,有什么解决办法吗?谢谢, 最佳答案 有可能……例如:start_year–设置年份选择的开始年份。默认为Time.now.year-5参见thisresource. 关于ruby-Rails3-我可以将开始日期
我想从特定索引开始遍历数组。我该怎么做?myj.eachdo|temp|...end 最佳答案 执行以下操作:your_array[your_index..-1].eachdo|temp|###end 关于ruby-从特定索引开始迭代数组,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/44151758/
目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一
我有一些使用delayed_job的小程序。在我的本地主机上一切正常,但是当我将我的应用程序部署到Heroku并单击应该由delayed_job执行的链接时,没有任何反应,“任务”只是保存到表delayed_job中。Inthisarticleonherokublog写入时,执行delayed_job表中的任务,当运行此命令时rakejobs:work。但是我怎样才能运行这个命令呢?命令应该放在哪里?在代码中,还是从终端控制台? 最佳答案 如果您正在运行Cedar堆栈,请从终端控制台运行以下命令:herokurunrakejobs:
我正在尝试使用docker运行一个Rails应用程序。通过github的sshurl安装的gem很少,如下所示:Gemfilegem'swagger-docs',:git=>'git@github.com:xyz/swagger-docs.git',:branch=>'my_branch'我在docker中添加了keys,它能够克隆所需的repo并从git安装gem。DockerfileRUNmkdir-p/root/.sshCOPY./id_rsa/root/.ssh/id_rsaRUNchmod700/root/.ssh/id_rsaRUNssh-keygen-f/root/.ss
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。多年来,我一直在使用多种语言进行编程,并且认为自己总体上相当擅长。但是,我从未编写过任何自动化测试:没有单元测试,没有TDD,没有BDD,什么都没有。我已经尝试开始为我的项目编写适当的测试套件。我可以看到在进行任何更改后能够自动测试项目中所有代码的理论值(value)。我可以看到像RSpec和Mocha这样的测试框架应该如何使设置和运行所述测试变得相当容易