全部操作来自于英文官方文档(两三年前的)。官网地址:https://docs.docker.com/get-started/
docker的优点:
灵活的 Flexible: Even the most complex applications can be containerized.
轻量级 Lightweight: Containers leverage and share the host kernel.
可交互 Interchangeable: You can deploy updates and upgrades on-the-fly.
可移植 Portable: You can build locally, deploy to the cloud, and run anywhere.
可伸缩 Scalable: You can increase and automatically distribute container replicas.
可叠加 Stackable: You can stack services vertically and on-the-fly.
通过运行镜像image来启动容器。镜像是一个可执行的包,它包含了运行应用程序所需的一切——代码、运行时、库、环境变量和配置文件。
容器是镜像的运行实例,你可以是使用命令docker ps来查看运行情况,就跟在Linux当中一样。
举例来说,就相当于镜像是一个类,容器是镜像的一个实例。
一个容器和主机共享内核,属于轻量级。
相比之下,虚拟机试试建立了一个Guest账户,需要的资源比应用程序所需的多。
Docker两个版本:免费社区版(CE)和收费企业版(EE)。
Docker社区版(CE)有两个更新的渠道,stable和edge:
稳定版stable每季度提供更新
边缘版edge每月提供更新
后续所有的介绍,全部基于社区版。和企业版不同之处见下图:
Docker所有版本的安装步骤可以参看官网,本篇只介绍Docker CE 在Windows10 、 Ubuntu16.04 、 Mac 下的安装。 官网地址:https://docs.docker.com/install/
和其他绝大部分软件一样,只需要下载安装包,然后运行完成安装步骤即可。安装包下载地址可以从官网中找到,也可以直接访问https://docs.docker.com/docker-for-windows/install/, 链接中提供的基本的效果。
和Windows基本一致,先下载安装包,然后拖拽完成整个步骤。下载地址:https://docs.docker.com/docker-for-mac/install/#download-docker-for-mac
安装完成后,为了加快后续操作加载速度,可以修改下registry mirrors为http://hub-mirror.c.163.com
如果电脑已经安装了旧版本的Docker,可以先进行卸载
sudo apt-get remove docker docker-engine docker.io
依次执行以下命令
# 更新apt
sudo apt-get update
# 允许apt访问https
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
# 添加Docker的official GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 检查
sudo apt-key fingerprint 0EBFCD88
# 这个是检查的打印结果,不用输入
pub 4096R/0EBFCD88 2017-02-22
Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid Docker Release (CE deb)
sub 4096R/F273FCD8 2017-02-22
# 安装stable repository,这个是必须的
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 开始安装
sudo apt-get update
sudo apt-get install docker-ce
以上命令安装的是最新版本,如果是生产环境,可能会固定某个版本,通过以下命令查看支持的版本
apt-cache madison docker-ce
有了版本号,就可以安装指定的版本了
$ sudo apt-get install docker-ce=18.03.0~ce-0~ubuntu
安装完成后,查看版本
$ docker --version
Docker version 18.03.0-ce, build 0520e24
详细信息
# 下面两个命令是等价的,用哪个都可以
$ docker version
$ docker info
安装样例(docker镜像,这里先运行就可以,后续章节会有介绍)
$ docker run hello-world
查看已安装样例
$ docker image ls
$ docker container ls --all
# 查看Docker支持的所有命令
docker
docker container --help
# 查看Docker的版本信息和详细信息
docker --version
docker version
docker info
# 运行Docker的镜像
docker run hello-world
# 查看Docker中运行的镜像
docker image ls
# 查看Docker中所有镜像,包括停止的等等
docker container ls
docker container ls --all
docker container ls -aq
一个项目的部署问题。线上环境安装的JDK版本是1.6,而最新开发完成的项目需要的JDK版本最低是1.8,在1.6的条件下不能正常启动。但是,如果把线上的1.6升级到1.8,旧系统运行又会出现问题。
如果使用了Docker,那么就完全没有这方面的担忧了。Docker是直接运行镜像(image)的,跟服务器的环境无关,需要的运行环境都在镜像当中。如果要自己写个镜像,那么简单说就是需要一个名称是Dockerfile的文件(没有任何后缀,文件名称就是Dockerfile)来定义。
后续的例子都是来自官网,可以去看英文原版:https://docs.docker.com/get-started/part2/#recap-and-cheat-sheet-optional
这篇主要介绍什么是容器和镜像,涉及到具体语言和业务的,可以暂时不用深究,明白是要干什么的就行。操作环境使用的Ubuntu16.04。
在空白目录下新建名称是Dockerfile的文件
# 目录随意,是空的就行
sudo mkdir /usr/local/test
cd /usr/local/test
sudo vim Dockerfile
文件内容是
# 从远程拉取python需要的运行环境
FROM python:2.7-slim
# 设置工作目录
WORKDIR /app
# 复制当前目录内容到上面设置好的工作目录
ADD . /app
# 安装requirements.txt文件中指定的软件
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# 容器端口使用80(不是硬件设备的端口)
EXPOSE 80
# 定义环境变量
ENV NAME World
# 容器启动时运行app.py文件
CMD ["python", "app.py"]
Dockerfile中使用了两个文件,requirements.txt和app.py,在相同目录下新建这两个文件。
requirements.txt的内容
Flask
Redis
app.py的内容
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "cannot connect to Redis, counter disabled"
html = "Hello {name}!
" \
"Hostname: {hostname}
" \
"Visits: {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
以上的含义是完成Flask和Redis的安装,然后打印部分内容,因为Redis没有运行,会打印失败信息。
先确保cd进入了上面文件所在的文件夹,使用下面的命令开始编译,其中friendlyhello是自己定义的名称,最后面有个点(表示当前目录)
sudo docker build -t friendlyhello .
正常情况下,打印的内容为
Sending build context to Docker daemon 4.608kB
Step 1/7 : FROM python:2.7-slim
...(好多内容,忽略不写了)
Step 7/7 : CMD ["python", "app.py"]
---> Running in e710f92c9af1
Removing intermediate container e710f92c9af1
---> d68b0dcd2d36
Successfully built d68b0dcd2d36
Successfully tagged friendlyhello:latest
上面步骤完成后,就生成镜像了,查看下所有镜像的列表:
$ sudo docker image ls
生成镜像之后自然是运行,执行下面语句:
docker run -p 4000:80 friendlyhello
其中,4000:80的含义是使用计算机真实的4000端口和镜像中的80端口匹配(还记得Dockerfile中定义了一个80吗,不是服务器的,这里可以映射关系),要访问docker中的80端口,只需要访问计算机的4000端口即可。
此时计算机是卡住的状态,要想检查是不是正常,可以使用浏览器查看http://ip地址:4000
自然,我们是不希望窗口一直卡住不能动的(如果要停止, ctrl+c 就行了),能不能后台运行,不影响其他操作呢?只需要加上一个-d,就像其他linux命令一样
docker run -d -p 4000:80 friendlyhello
此时除了用浏览器查看,也可以使用curl命令,就像这样
curl http://localhost:4000
如果运行其实端口被占用,可以参照左侧目录附录一
上面的操作已经可以完成了本地的运行,但是docker还为我们提供了更方便的地方,比如我用mac运行成功了,现在要放到ubuntu服务器上,所有操作都再运行一次是很不方便的,假如我们把运行成功的镜像上传到一个地方,其他计算机要使用的时候,直接拉取这个镜像,岂不是更方便。那么我们就先登录可以放置我们镜像的网站:http://cloud.docker.com
如果没有账号,需要先注册,注册时候验证码会因为网络环境刷新比较吃力,可以换换网络或者找个梯子。我已经注册成功,用户名是fymod。
sudo docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: fymod
Password:
Login Succeeded
给镜像打个标记username/repository:tag,其中tag是可选的,但是强烈建议加上。
sudo docker tag friendlyhello fymod/get-started:part2
查看下当前运行的镜像是否多出来了fymod/get-started,这个镜像是可以推送到云端的。
sudo docker image ls
把本地镜像推送到云端
$ sudo docker push fymod/get-started:part2
推送完成后,使用注册下来的账号登录https://hub.docker.com/查看,如果有了,其他电脑就可以直接使用。
我们换台只安装了docker的计算机运行下面的命令:
$ sudo docker run -p 4000:80 fymod/get-started:part2
如果本地有这个镜像,就直接使用本地的,如果没有,就从云端拉取,和之前本地运行的命令很相似,只是将之前的friendhello换成了定义的tag。
# 使用Dockerfile建立一个镜像
docker build -t friendlyhello .
# 前端运行镜像
docker run -p 4000:80 friendlyhello
# 后台运行镜像
docker run -d -p 4000:80 friendlyhello
# 列出所有运行中的容器
docker container ls
# 列出全部容器,即便没有运行
docker container ls -a
# 停止特定的容器
docker container stop
# 强制停止指定的容器
docker container kill
# 移除指定的容器
docker container rm
# 移除全部容器
docker container rm $(docker container ls -a -q)
# 查看全部镜像列表
docker image ls -a
# 移除指定镜像
docker image rm
# 移除全部镜像
docker image rm $(docker image ls -a -q)
# 登录云端
docker login
# 给要上传云端的镜像打标记
docker tag username/repository:tag
# 指定标记的镜像上传到云端
docker push username/repository:tag
# 运行指定标记的镜像
docker run username/repository:tag
先声明服务和堆栈的概念。上一节介绍了镜像是容器的实例,而服务可以运行很多个容器。比如本篇要讲前一节介绍的demo做成5个容器实例来访问。其实很简单,编写一个yaml格式的文件就行了。本篇对应两篇官方英文网址为:
https://docs.docker.com/get-started/part3/
https://docs.docker.com/get-started/part4/
文件位置没有要求,放到哪里都行。
version: "3"
services:
web:
image: fymod/get-started:part2
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
ports:
- "80:80"
networks:
- webnet
networks:
webnet:
各个字段含义如下
image:换成自己的镜像
replicas:运行5个容器实例
limits:最大10%的cpu占用和最大50M的RAM占用。
restart_policy:失败之后立即重启
ports:映射外部端口和docker端口
networks:定义了一个默认的网络(支持负载均衡),可查看附录三
sudo docker swarm init
sudo docker stack deploy -c docker-compose.yml getstartedlab
根据docker-compose.yml中的定义,我们的一个服务栈运行5个容器实例,先验证下
sudo docker service ls
sudo docker service ps getstartedlab_web
# 如果想查看系统中全部的容器,可以运行
sudo docker container ls -q
访问http://ip地址,显示的hostname每请求5次一个循环,值就是sudo docker container ls -q当中的数据。
如果要把5个实例换成10个,只需要修改docker-compose.yml中的一个数字即可,然后重启。重启的命令和启动的是一模一样,不需要自己先停止再去启动
sudo docker stack deploy -c docker-compose.yml getstartedlab
停止应用
$ sudo docker stack rm getstartedlab
停止集群
$ sudo docker swarm leave --force
前面已经实现了一台计算机上运行很多容器实例,本部分介绍多台计算机的集群效果。docker集群由管理员和worker组成,本篇使用一台机器作为管理员(就是一直用的这台),另一台(一个安装了docker的新计算机)作为worker。
英文官网上这部分是用的虚拟机,因为我的ubuntu服务器不支持虚拟化,就用了两台物理机。如果要熟悉虚拟机相关注意事项和基本命令,可以先查看左侧附录二。
在一台服务器上执行命令,设置为管理员。
docker swarm init --advertise-addr 10.72.72.98
其中,10.72.72.98是计算机ip地址,替换为自己真实的即可
打印结果如下
Swarm initialized: current node (fszwnygfkgk0tdzlwlc1tuxf3) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5subd4cg5rjb6hs54b2ctxmihyxgfp32d81suuqqmiks1kawar-44u7f7vlhxydaj8dad35ff4x3 10.72.72.98:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
中间一行命令表示如果要把机器加入到这个集群成为worker,直接把这句复制过去运行。所以在第二台安装了docker的计算机上来直接运行:
docker swarm join --token SWMTKN-1-5subd4cg5rjb6hs54b2ctxmihyxgfp32d81suuqqmiks1kawar-44u7f7vlhxydaj8dad35ff4x3 10.72.72.98:2377
运行完成后可以来查看
sudo docker node ls
命令和之前的也一样:
sudo docker swarm init
sudo docker stack deploy -c docker-compose.yml getstartedlab
查看结果
sudo docker service ls
docker stack ps getstartedlab
访问两台计算机的80端口,看看是不是都有结果,也可以使用curl
curl 管理员计算机ip地址
curl worker计算机ip地址
其他命令可以查看附录二,docker-machine括号里面的都是真机可用的。
# 堆栈和应用列表
docker stack ls
# 运行指定的组成文件
docker stack deploy -c
# 列出运行的服务列表
docker service ls
# 列出与应用程序相关联的任务
docker service ps
# 检查任务或者容器
docker inspect
# 列出所有容器的id
docker container ls -q
# 移除应用
docker stack rm
# 从管理员移除单一节点
docker swarm leave --force
回头看下之前的docker-compose.yml,里面只有一个主节点web,用来运行我们demo当中的服务。其实这里面可以添加很多的节点,并非只能添加一个,比如前面例子一直没有实现的redis节点,同时也可以添加docker镜像已经有的可视化节点。这部分英文官方文档地址是:https://docs.docker.com/get-started/part5/
修改docker-compose.yml文件,添加两个节点,分别实现可视化和redis管理。
version: "3"
services:
web:
image: fymod/get-started:part2
deploy:
replicas: 5
restart_policy:
condition: on-failure
resources:
limits:
cpus: "0.1"
memory: 50M
ports:
- "80:80"
networks:
- webnet
visualizer:
image: dockersamples/visualizer:stable
ports:
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints: [node.role == manager]
networks:
- webnet
redis:
image: redis
ports:
- "6379:6379"
volumes:
- "/home/docker/data:/data"
deploy:
placement:
constraints: [node.role == manager]
command: redis-server --appendonly yes
networks:
- webnet
networks:
webnet:
其中,visualizer节点是可视化效果,可以用网页打开查看。redis节点是数据存储用的。因为redis数据最好存储到物理机上,而不是docker中的位置,volumes选项就是将docker中的位置映射到物理机的/home/docker/data目录下。稳妥起见,新建下目录。
sudo mkdir /home/docker/data
sudo mkdir ./data
然后运行
$ sudo docker stack deploy -c docker-compose.yml getstartedlabc
查看
sudo docker service ls
如果redis或者visualizer启动失败,可能是原因是本地没有镜像,也没有成功拉取下来,可以先手动执行下对应的步骤,然后ctrl+c停止
sudo docker run 8080:8080 dockersamples/visualizer:stable
sudo docker run -p 6379:6379 redis
继续运行
$ sudo docker stack deploy -c docker-compose.yml getstartedlabc
网页访问
http://ip地址:8080和http://ip地址查看
比如ssh连接自己断开了,没有使用ctrl+c停止,那么再连接上运行命令的时候,就会提示端口被占用。停止方法:
查看运行的镜像
$ sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e559c1e88f15 friendlyhello "python app.py" 36 seconds ago Up 34 seconds 0.0.0.0:4000->80/tcp sad_stallman
有了上面的编码,就能直接停止了,序号可以只输入一部分,比如
$ sudo docker container stop e559c
$ sudo apt-get install cpu-checker
$ kvm-ok
支持的话,打印的是
INFO: /dev/kvm exists
KVM acceleration can be used
不支持的话,打印的是
INFO: Your CPU does not support KVM extensions
INFO: For more detailed results, you should run this as root
HINT: sudo /usr/sbin/kvm-ok
如果支持虚拟化,安装虚拟机
sudo apt-get install libqt5x11extras5 libsdl1.2debian
sudo apt-get install virtualbox
当然也可以自己手动下载下来,然后安装下载下来的文件。下载地址是https://www.virtualbox.org/wiki/Linux_Downloads
安装命令是
$ sudo dpkg -i virtualbox-5.2_5.2.8-121009~Ubuntu~xenial_amd64.deb
下面的命令全部复制执行即可
curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
chmod +x /tmp/docker-machine &&
sudo cp /tmp/docker-machine /usr/local/bin/docker-machine
检查用
$ sudo docker-machine version
使用 docker-machine 建立 vms
docker-machine create --driver virtualbox myvm1
docker-machine create --driver virtualbox myvm2
查看
docker-machine ls
# 在Mac, Win7, Linux下建立虚拟机
docker-machine create --driver virtualbox myvm1
# Win10下建立虚拟机
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1
# 查下关于节点的基本信息
docker-machine env myvm1
# 集群下节点列表
docker-machine ssh myvm1 "docker node ls"
# 节点检查
docker-machine ssh myvm1 "docker node inspect "
# 查看加入使用的token
docker-machine ssh myvm1 "docker swarm join-token -q worker"
# 打开虚拟机的ssh连接,使用exit命令退出
docker-machine ssh myvm1
# 查看集群下节点列表
docker node ls
# worker撤离集群
docker-machine ssh myvm2 "docker swarm leave"
# 彻底关闭集群
docker-machine ssh myvm1 "docker swarm leave -f"
# 虚拟机列表
docker-machine ls
# 启动当前没有运行的虚拟机
docker-machine start myvm1
# 查看虚拟机的环境变量
docker-machine env myvm1
# mac电脑下连接到虚拟机
eval $(docker-machine env myvm1)
# windows电脑下连接到虚拟机
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression
# 编译:管理员服务器才能使用的命令
docker stack deploy -c
# 复制文件到节点主目录(ssh连接到管理员服务器)
docker-machine scp docker-compose.yml myvm1:~
# 使用ssh编译应用
docker-machine ssh myvm1 "docker stack deploy -c "
# 断开虚拟机连接
eval $(docker-machine env -u)
# 停止所有运行的虚拟机
docker-machine stop $(docker-machine ls -q)
# 删除所有虚拟机和他们的磁盘镜像
docker-machine rm $(docker-machine ls -q)
Docker安装后,默认会创建下面三种网络类型
docker network ls
NETWORK ID NAME DRIVER SCOPE
9781b1f585ae bridge bridge local
1252da701e55 host host local
237ea3d5cfbf none null local
启动 Docker的时候,用 --network 参数,可以指定网络类型
docker run -itd --name test1 --network bridge --ip 172.17.0.10 centos:latest /bin/bash
bridge:桥接网络
默认情况下启动的Docker容器,都是使用 bridge,Docker安装时创建的桥接网络,每次Docker容器重启时,会按照顺序获取对应的IP地址,这个就导致重启下,Docker的IP地址就变了
none:无指定网络
使用 --network=none ,docker 容器就不会分配局域网的IP
host: 主机网络
使用 --network=host,此时,Docker 容器的网络会附属在主机上,两者是互通的。
例如,在容器中运行一个Web服务,监听8080端口,则主机的8080端口就会自动映射到容器中。
创建自定义网络:(设置固定IP)
启动Docker容器的时候,使用默认的网络是不支持指派固定IP的,如下
# 错误命令示例
docker run -itd --net bridge --ip 172.17.0.10 centos:latest /bin/bash
6eb1f228cf308d1c60db30093c126acbfd0cb21d76cb448c678bab0f1a7c0df6
docker: Error response from daemon: User specified IP address is supported on user defined networks only.
步骤1: 创建自定义网络
docker network create --subnet=172.18.0.0/16 mynetwork
➜ ~ docker network ls
NETWORK ID NAME DRIVER SCOPE
9781b1f585ae bridge bridge local
1252da701e55 host host local
4f11ae9c85de mynetwork bridge local
237ea3d5cfbf none null local
步骤2: 创建Docker容器
docker run -itd --name networkTest1 --net mynetwork --ip 172.18.0.2 centos:latest /bin/bash
本篇文章来自于https://www.jianshu.com/p/2217cfed29d7
先来看一份 docker-compose.yml 文件,不用管这是干嘛的,只是有个格式方便后文解说:
version: '2'
services:
web:
image: dockercloud/hello-world
ports:
- 8080
networks:
- front-tier
- back-tier
redis:
image: redis
links:
- web
networks:
- back-tier
lb:
image: dockercloud/haproxy
ports:
- 80:80
links:
- web
networks:
- front-tier
- back-tier
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
front-tier:
driver: bridge
back-tier:
driver: bridge
可以看到一份标准配置文件应该包含 version、services、networks 三大部分,其中最关键的就是 services 和 networks 两个部分,下面先来看 services 的书写规则。
services:
web:
image: hello-world
在 services 标签下的第二级标签是 web,这个名字是用户自己自定义,它就是服务名称。
image 则是指定服务的镜像名称或镜像 ID。如果镜像在本地不存在,Compose 将会尝试拉取这个镜像。
例如下面这些格式都是可以的:
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd
build: /path/to/build/dir
也可以是相对路径,只要上下文确定就可以读取到 Dockerfile。
build: ./dir
设定上下文根目录,然后以该目录为准指定 Dockerfile。
build:
context: ../
dockerfile: path/of/Dockerfile
注意 build 都是一个目录,如果你要指定 Dockerfile 文件需要在 build 标签的子级标签中使用 dockerfile 标签指定,如上面的例子。
如果你同时指定了 image 和 build 两个标签,那么 Compose 会构建镜像并且把镜像命名为 image 后面的那个名字。
build: ./dir
image: webapp:tag
既然可以在 docker-compose.yml 中定义构建任务,那么一定少不了 arg 这个标签,就像 Dockerfile 中的 ARG 指令,它可以在构建过程中指定环境变量,但是在构建成功后取消,在 docker-compose.yml 文件中也支持这样的写法:
build:
context: .
args:
buildno: 1
password: secret
下面这种写法也是支持的,一般来说下面的写法更适合阅读。
build:
context: .
args:
- buildno=1
- password=secret
与 ENV 不同的是,ARG 是允许空值的。例如:
args:
- buildno
- password
这样构建过程可以向它们赋值。
注意:YAML 的布尔值(true, false, yes, no, on, off)必须要使用引号引起来(单引号、双引号均可),否则会当成字符串解析。
command: bundle exec thin -p 3000
也可以写成类似 Dockerfile 中的格式:
command: [bundle, exec, thin, -p, 3000]
4.container_name
前面说过 Compose 的容器名称格式是:
虽然可以自定义项目名称、服务名称,但是如果你想完全控制容器的命名,可以使用这个标签指定:
container_name: app
这样容器的名字就指定为 app 了。
5.depends_on
在使用 Compose 时,最大的好处就是少打启动命令,但是一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。
例如在没启动数据库容器的时候启动了应用容器,这时候应用容器会因为找不到数据库而退出,为了避免这种情况我们需要加入一个标签,就是 depends_on,这个标签解决了容器的依赖、启动先后的问题。
例如下面容器会先启动 redis 和 db 两个服务,最后才启动 web 服务:
version: '2'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
注意的是,默认情况下使用 docker-compose up web 这样的方式启动 web 服务时,也会启动 redis 和 db 两个服务,因为在配置文件中定义了依赖关系。
6.dns
和 --dns 参数一样用途,格式如下:
dns: 8.8.8.8
也可以是一个列表:
dns:
- 8.8.8.8
- 9.9.9.9
此外 dns_search 的配置也类似:
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
tmpfs: /run
tmpfs:
- /run
- /tmp
entrypoint: /code/entrypoint.sh
格式和 Docker 类似,不过还可以写成这样:
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunit
9.env_file
还记得前面提到的 .env 文件吧,这个文件可以设置 Compose 的变量。而在 docker-compose.yml 中可以定义一个专门存放变量的文件。
如果通过 docker-compose -f FILE 指定了配置文件,则 env_file 中路径会使用配置文件路径。
如果有变量名称与 environment 指令冲突,则以后者为准。格式如下:
env_file: .env
或者根据 docker-compose.yml 设置多个:
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
注意的是这里所说的环境变量是对宿主机的 Compose 而言的,如果在配置文件中有 build 操作,这些变量并不会进入构建过程中,如果要在构建中使用变量还是首选前面刚讲的 arg 标签。
environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET
expose:
- "3000"
- "8000"
external_links:
- redis_1
- project_db_1:mysql
- project_db_1:postgresql
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
启动之后查看容器内部hosts:
162.242.195.82 somehost
50.31.209.229 otherhost
labels:
com.example.description: "Accounting webapp"
com.example.department: "Finance"
com.example.label-with-empty-value: ""
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
links:
- db
- db:database
- redis
使用的别名将会自动在服务容器中的/etc/hosts里创建。例如:
172.12.2.186 db
172.12.2.186 database
172.12.2.187 redis
相应的环境变量也将被创建。
logging:
driver: syslog
options:
syslog-address: "tcp://192.168.0.42:123"
默认的driver是json-file。只有json-file和journald可以通过docker-compose logs显示日志,其他方式有其他日志查看方式,但目前Compose不支持。对于可选值可以使用options指定。
有关更多这方面的信息可以阅读官方文档:
https://docs.docker.com/engine/admin/logging/overview/
pid: "host"
将PID模式设置为主机PID模式,跟主机系统共享进程命名空间。容器使用这个标签将能够访问和操纵其他容器和宿主机的名称空间。
ports:
- "3000"
- "8000:8000"
- "49100:22"
- "127.0.0.1:8001:8001"
注意:当使用HOST:CONTAINER格式来映射端口时,如果你使用的容器端口小于60你可能会得到错误得结果,因为YAML将会解析xx:yy这种数字格式为60进制。所以建议采用字符串格式。
security_opt:
- label:user:USER
- label:role:ROLE
stop_signal: SIGUSR1
volumes:
// 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。
- /var/lib/mysql
// 使用绝对路径挂载数据卷
- /opt/data:/var/lib/mysql
// 以 Compose 配置文件为中心的相对路径作为数据卷挂载到容器。
- ./cache:/tmp/cache
// 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。
- ~/configs:/etc/configs/:ro
// 已经存在的命名的数据卷。
- datavolume:/var/lib/mysql
如果你不使用宿主机的路径,你可以指定一个volume_driver。
volume_driver: mydriver
volumes_from:
- service_name
- service_name:ro
- container:container_name
- container:container_name:rw
cap_add:
- ALL
cap_drop:
- NET_ADMIN
- SYS_ADMIN
cgroup_parent: m-executor-abcd
devices:
- "/dev/ttyUSB0:/dev/ttyUSB0"
extends:
file: common.yml
service: webapp
用户可以在任何地方使用这个标签,只要标签内容包含file和service两个值就可以了。file的值可以是相对或者绝对路径,如果不指定file的值,那么Compose会读取当前YML文件的信息。
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
可以指定使用服务或者容器的网络。
services:
some-service:
networks:
- some-network
- other-network
关于这个标签还有一个特别的子标签aliases,这是一个用来设置服务别名的标签,例如:
services:
some-service:
networks:
some-network:
aliases:
- alias1
- alias3
other-network:
aliases:
- alias2
相同的服务可以在不同的网络有不同的别名。
cpu_shares: 73
cpu_quota: 50000
cpuset: 0,1
user: postgresql
working_dir: /code
domainname: foo.com
hostname: foo
ipc: host
mac_address: 02:42:ac:11:65:43
mem_limit: 1000000000
memswap_limit: 2000000000
privileged: true
restart: always
read_only: true
shm_size: 64M
stdin_open: true
tty: true
docker pull redis:latest
docker images
其中fymod-redis可以任意命名。
docker run -itd --name fymod-redis -p 6379:6379 redis
docker ps
先连接上
docker exec -it fymod-redis /bin/bash
使用命令redis-cli测试,添加key如set test 123321
docker pull mysql
docker image ls
docker run --name fymod-mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql
docker ps
运行docker ps查看到mysql对应的容器id
docker exec -it 容器ID数值 /bin/bash
mysql -uroot -p123456 // 123456是密码
mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';