docker,dockerfile与docker-compose区别

docker 和操作系统无关的一个沙箱容器,宿主机安装的什么操作系统和其本身无关,在它基础上可以制作各种系统类型的基础服务
Dockerfile 是把我们手工安装docer镜像的过程变成一个配置文件的方式运行,这样每次不用一步步手敲命令去安装了,而只是需要一个配置文件运行既可生成一个镜像
docker-compos 提供了服务和项目的概念,这样一个服务可以配置多个项目,这个服务是多个项目的集合体,启动和关闭都相对一个一个项目的启动要方便很多

假如你不用 docker ,搭建 wordpress 怎么弄?
1.买台服务器 server ,假设其 OS 为 Ubuntu ,然后按照文档一步步敲命令,写配置,对吧?
2.用 docker 呢? 随便找台 server ,不管什么操作系统,只要支持 docker 就行, docker run ubuntu, docker 会从官方源里拉取最新的 Ubuntu 镜像,可以认为你开了个 Ubuntu 虚拟机,然后一步步安装,跟上面一样。
但是这样安装有个显著的缺点,一旦 container 被删,你做的工作就都没了。当然可以用 docker commit 来保存成镜像,这样就可以复用了。
但是镜像文件一般比较大,而且只分享镜像的话,别人也不知道你这镜像到底包含什么,这些问题都不利于分享和复用。
一个直观的解决方案就是,写个脚本把安装过程全部记录下来,这样再次安装的时候,执行脚本就行了。 Dockerfile 就是这样的脚本,它记录了一个镜像的制作过程。
3.有了 Dockerfile, 只要执行 docker build . 就能制作镜像,而且 Dockerfile 就是文本文件,修改也很方便。
现在有了 wordpress 的镜像,只需要 docker run 就把 wordpress 启动起来了。
如果仅仅是 wordpress, 这也就够了。但是很多时候,需要多个镜像合作才能启动一个服务,比如前端要有 nginx , 数据库 mysql, 邮件服务等等,当然你可以把所有这些都弄到一个镜像里去,但这样做就无法复用了。
更常见的是, nginx, mysql, smtp 都分别是个镜像,然后这些镜像合作,共同服务一个项目。
4.docker-compose 就是解决这个问题的。你的项目需要哪些镜像,每个镜像怎么配置,要挂载哪些 volume, 等等信息都包含在 docker-compose.yml 里。
要启动服务,只需要 docker-compose up 就行,停止也只需要 docker-compse stop/down

简而言之, Dockerfile 记录单个镜像的构建过程, docker-compse.yml 记录一个项目(project, 一般是多个镜像)的构建过程。

你说有些教程用了 dockerfile+docker-compose, 是因为 docker-compose.yml 本身没有镜像构建的信息,
如果镜像是从 docker registry 拉取下来的,那么 Dockerfile 就不需要;
如果镜像是需要 build 的,那就需要提供 Dockerfile.

Compose简介

Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。它是一个定义和运行多容器的docker应用工具。使用compose,你能通过YMAL文件配置你自己的服务,然后通过一个命令,你能使用配置文件创建和运行所有的服务。

Compose是一个定位“定义和运行多个Docker容器应用的工具”,其前身是Fig,目前使用的Compose仍然兼容Fig格式的模板文件。
Compose的代码主要使用Python编写,其开源地址为:https://github.com/docker/compose。

注意:Fig时代支持的配置文件名为fig.yml以及fig.yaml;为了兼容遗留的Fig化配置,目前Compose支持的配置文件类型非常丰富,主要有以下几种:fig.yaml、docker-compose.yml、docker-compose.yaml以及用户指定的配置文件路径。(可通过环境变量COMPOSE_FILE或-f参数自定义配置文件)

在Compose中有两个重要的概念:
服务(service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
项目(project):由一组关联的应用容器组成的一个完成业务单元,在docker-compose.yml中定义。

以上可以理解为:
服务(service)就是在它下面可以定义应用需要的一些服务,代表配置文件中的每一项服务。每个服务都有自己的名字、使用的镜像、挂载的数据卷、所属的网络、依赖哪些其他服务等等,即以容器为粒度,用户需要Compose所完成的任务。
项目(project)代表用户需要完成的一个项目,即是Compose的一个配置文件可以解析为一个项目,即Compose通过分析指定配置文件,得出配置文件所需完成的所有容器管理与部署操作。

Compose的默认管理对象时项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。

Compose安装与卸载

Centos系统安装

1、Compose安装
Compose目前已经完全支持Linux、Mac OS和Windows,在我们安装Compose之前,需要先安装Docker,对于Mac OS和Windows的安装比较容易,可以参考Install Docker for Mac和Install Docker for Windows,对于Linux的安装可以参考Ubuntu下docker安装及简单应用。

(1)、Linux平台的安装
这里是使用了官方编译好的二进制包,地址:https://github.com/docker/compose/releases。把这些二进制文件下载后直接放到执行路径下面,并添加权限即可。

curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

然后我们执行docker-compose -version可以查看到具体的信息

Mac OS 系统 & Windows系统安装

对于Mac和windows用户来说,Docker for Mac 、Docker for Windows 和 Docker Toolbox 早已经集成了docker-compose,所以用户不需要分别再安装docker-compose了。

其他可选方式安装
因为Compose是Python编写的,我们可以将其当做一个Python应用从pip源中安装。
如果是使用virtualenv环境,
则执行如下命令:

pip install docker-compose

当在本地环境安装,则执行:

sudo pip install docker-compose

Compose卸载

如果是二进制包方式安装的,删除二进制文件即可:

sudo rm /usr/local/bin/docker-compose

如果是通过Python pip工具安装的,则执行如下命令删除:

sudo pip uninstall docker-compose

Compose模板文件

模板文件是使用Compose的核心,涉及的指令关键字也比较多,大部分指令与docker run相关参数的含义都是类似的。
默认的模板文件迷城为docker-compose.yml,格式为YAML格式。
比如一个Compose模板文件:

version: "2"
services:
	web:
		images:	nginx
		ports:
			- "80:80"
		volumes:
			- "/data"
#volumes:

#networks:

Docker Compose的模板文件主要分为3个区域,为:
services
服务,在它下面可以定义应用需要的一些服务,每个服务都有自己的名字、使用的镜像、挂载的数据卷、所属的网络、依赖哪些其他服务等等。

volumes
数据卷,在它下面可以定义的数据卷(名字等等),然后挂载到不同的服务下去使用。

networks
应用的网络,在它下面可以定义应用的名字、使用的网络类型等等。

注意:每个服务都必须通过image指令指定镜像或build指令(需要Dockerfile)等来自动构建生成镜像。如果使用build指令,在Dockefile中设置的选项(例如:CMD、EXPOSE、VOLUME、ENV等)将会自动被获取,无需在docker-compose.yml中再次设置。

Compose实战

讲了那么多,我们开始结合前面的知识点进行讲解使用Compose。首先新建一个文件夹compose,然后创建文件docker-compose.yml

mkdir -p docker/compose
cd docker/compose/
touch docker-compse.yml
vi docker-compse.yml
# 粘贴如下内容
version: '2'
services:
  web1:
    image: nginx
    ports: 
      - "8080:80"
    container_name: "web1"
  web2:
    image: nginx
    ports: 
      - "8081:80"
    container_name: "web2"
#volumes:

#networks:

这里我们创建了两个服务,web1和web2,它们都从镜像nginx为基础对应不同的端口号,如果ninx不在本地则从hub中下载

使用docker-compose up 启动该服务 -d 后台模式启动

docker-compose up -d
Creating network "compose_default" with the default driver
Creating web2 ... done
Creating web1 ... done

首先创建了一个默认的compose_default的网络,然后创建容器,并「Attaching to …」,将网络应用到服务上。

我们可以查看一下具体的网络,使用docker network ls 如下:

 docker network ls 
NETWORK ID          NAME                DRIVER              SCOPE
65dc1fa3890d        bridge              bridge              local
579be42a6c29        compose_default     bridge              local
966d4b133a72        host                host                local
b6dce98ab539        none                null                local

访问该宿主机的IP和端口则可以成功访问到nginx服务,这里的IP换成你自己的宿主机IP
http://192.168.1.101:8081/

docker-compose ps查看服务进程

docker-compose ps
Name         Command          State          Ports        
----------------------------------------------------------
web1   nginx -g daemon off;   Up      0.0.0.0:8080->80/tcp
web2   nginx -g daemon off;   Up      0.0.0.0:8081->80/tcp

docker-compose stop [name] 停止服务,docker-compose start [name]启动服务

 # docker-compose stop web1
Stopping web1 ... done
# docker-compose ps
Name         Command          State           Ports        
-----------------------------------------------------------
web1   nginx -g daemon off;   Exit 0                       
web2   nginx -g daemon off;   Up       0.0.0.0:8081->80/tcp

docker-compose rm [name]删除服务,需要停止服务,否则使用-f参数,与docker rm命令类似

注意:这个docker-compose rm不会删除应用的网络和数据卷。查看一下网络,可以看到应用创建的网络
如果要删除数据卷、网络、应用则使用docker-compose down命令。

docker-compose logs -f [name]查看具体服务的日志

通过docker-compose exec [name] shell可以进入容器内部,例如,进入web1容器内部,使用docker-compose exec web1 /bin/bash命令。

指定网络

version: '2'
services:
  web1:
    image: nginx
    ports: 
      - "8080:80"
    container_name: "web1"
    networks:
      - dev
  web2:
    image: nginx
    ports: 
      - "8081:80"
    container_name: "web2"
    networks:
      - dev
      - pro
  web3:
    image: nginx
    ports: 
      - "8082:80"
    container_name: "web3"
    networks:
      - pro

networks:
  dev:
    driver: bridge
  pro:
    driver: bridge

#volumes:

我们添加了容器web3,并指定了网络。使用docker-compose down关闭先前的服务,重新启动服务。

我们指定了dev、pro网络,同时给web1指定了dev网络,web2指定了dev、pro网络,web3指定了pro网络,因此web1和web2可以互相访问到,web2和web3可以互相访问到,而web1与web3就无法访问。这就可以通过配置来实现容器直接的互通和隔离。

docker-compose up -d 
Creating network "compose_dev" with driver "bridge"
Creating network "compose_pro" with driver "bridge"
Creating web2 ... done
Creating web1 ... done
Creating web3 ... done
[root@localhost compose]# docker-compose ps
Name         Command          State          Ports        
----------------------------------------------------------
web1   nginx -g daemon off;   Up      0.0.0.0:8080->80/tcp
web2   nginx -g daemon off;   Up      0.0.0.0:8081->80/tcp
web3   nginx -g daemon off;   Up      0.0.0.0:8082->80/tcp

配置卷

再次修改配置文件

version: '2'
services:
  web1:
    image: nginx
    ports: 
      - "8080:80"
    container_name: "web1"
    networks:
      - dev
    volumes:
      - ntfs:/data
  web2:
    image: nginx
    ports: 
      - "8081:80"
    container_name: "web2"
    networks:
      - dev
      - pro
    volumes:
      - ./:/usr/share/nginx/html
  web3:
    image: nginx
    ports: 
      - "8082:80"
    container_name: "web3"
    networks:
      - pro
    volumes:
      - ./:/usr/share/nginx/html

networks:
  dev:
    driver: bridge
  pro:
    driver: bridge

volumes:
  ntfs:
    driver: local

我们添加了volumes声明,在web1中我们挂载数据在本地,而web2、web3我们则挂载compose当前目录与nginx的/usr/share/nginx/html相通。同样使用docker-compose down关闭先前的服务,并重新启动服务。

然后我们在当前compose目录新建index.html文件,这里的index.html随便编写一些内容,
进入web2中的目录查看路径,发现下面的文件和宿主机当前的docker-compose.yml所在目录的文件完全相同

 docker-compose exec web2 /bin/bash
# cd /usr/share/nginx/html/
# ls
docker-compose.yml  docker-compose.yml.1  docker-compose.yml.2	index.html

当然我们也可以通过web3的链接访问其默认页面的内容,因为我们已经修改了nginx对应的目录对应到了宿主机,所以原有的nginx页面已经看不到了,只能 显示宿主机上的index.html
http://192.168.1.101:8082/
在这里插入图片描述
nginx的镜像默认配置文件在镜像中的路径是/etc/nginx/conf.d/default.conf它的默认路径配置如下

location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

因此我们只需要把 /usr/share/nginx/html对应到宿主机的实际路径地址就可以修改宿主机上的index.html文件内容即可,其他情况可以根据你的实际情况进行处理

通过Compose,我们快速创建一套基于Docker容器的服务栈,然后使用docker-compose脚本来启动,停止和重启应用,非常适合组合使用多个容器进行开发的场景。因此掌握Compose的使用也是非常重要的,到此Compose的知识点也介绍完毕,Docker三剑客-compse的知识也到此结束,有什么建议欢迎一起讨论。

环境变量environment

设置环境变量,可以使用数组或字典两种格式。

只给定名称的变量会自动获取运行Compose主机上对应变量的值,可以用来防止防泄露不必要的数据。例如:

environment: 
	RACK_ENV: development
	SESSION_SECRET:

或者:

environment: 
	- RACK_ENV=development
	- SESSION_SECRET

注意:如果变量名称或者值中用到true|false,yes|no等表达布尔含义的词汇,最好放到引号里,避免YAML自动解析某些内容为对应的布尔语义:
y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF

extends

基于其他模板文件进行扩展。例如,我们已经有了一个webapp服务,定义一个基础模板文件为common.yml,如下所示:

# common.yml

webapp:
	build: ./webapp
	environment:
		- DEBUG=false
		- SEND_EMAILS=false

再编写一个新的development.yml文件,使用common.yml中的webapp服务进行扩展:

# development.yml

web:
	extends:
		file: common.yml
		service: webapp
	ports:
		- "8000:8000"
	links:
		- db
	environment:
		- DEBUG=true
db:
	image: mysql

后者会自动继承common.yml中的webapp服务及环境变量定义。

使用extends需要注意以下几点:

  • 要避免出现循环依赖,例如A依赖B,B依赖C,C反过来依赖A的情况
  • extends不会继承links和volumes_from中定义的容器和数据卷资源

一般情况下,推荐在基础模板中只定义一些可以共享的镜像和环境变量,在扩展模板中具体指定应用变量、链接、数据卷等信息

Compose常用命令

在我们使用Compose前,可以通过执行docker-compose --help|-h来查看Compose基本命令用法。
Docker Compose常用命令列表如下:

命令说明
build构建项目中的服务容器
help获得一个命令的帮助
kill通过发送SIGKILL信号来强制停止服务容器
config验证和查看compose文件配置
create为服务创建容器。只是单纯的create,还需要使用start启动compose
down停止并删除容器,网络,镜像和数据卷
exec在运行的容器中执行一个命令
logs查看服务容器的输出
pause暂停一个服务容器
port打印某个容器端口所映射的公共端口
ps列出项目中目前的所有容器
pull拉取服务依赖的镜像
push推送服务镜像
restart重启项目中的服务
rm删除所有(停止状态的)服务容器
run在指定服务上执行一个命令
scale设置指定服务运行的容器个数
start启动已经存在的服务容器
stop停止已经处于运行状态的容器,但不删除它
top显示运行的进程
unpause恢复处于暂停状态中的服务
up自动完成包括构建镜像、创建服务、启动服务并关闭关联服务相关容器的一些列操作

docker-compose一键部署java,mysql,redis

https://blog.csdn.net/u011913691/article/details/90665639

#参考资料
作者:Anumbrella
来源:CSDN
原文:https://blog.csdn.net/Anumbrella/article/details/80877643

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐