1. Dockerfile
1.1. dockerfile的说明
建立镜像,镜像是基于DockerFile建立镜像的,在DockerFile中是一行行命令,Docker程序将读取Dockerfile ,根据指令生产定制的image
FROM <image>(最先的命令)
MAINTAINER <author>(选填)(作者信息)
RUN <command>(安装软件用)(这里的命令是镜像构建命令)
ADD\COPY[与ADD不同的是COPY不会自动解压] <FileName> <PathURL>
CMD <command>(设置container启动时执行的操作)
EXPOSE <port>(较为重要的一个参数)(映射端口)
格式:
EXPOSE <port> [<port>...] # 映射一个端口 EXPOSE port1 # 相应的运行容器使用的命令 docker run -p port1 image # 映射多个端口 EXPOSE port1 port2 port3 # 相应的运行容器使用的命令 docker run -p port1 -p port2 -p port3 image # 还可以指定需要映射到宿主机器上的某个端口号 docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image |
ENV <key><value>(当需要配置参数时,填写。例如:ENV JAVA_HOME/path/to/java/dirent)
VOLUME(指定挂载点)
WORKDIR(切换目录)设置指令,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效。
DockerFile的命令是忽略大小写的,但建议使用大写
1.2. 实例
我们以dinp中的mysql为例:
1. 你要有一个可以放mysql文件的文件夹
2. 你可以从git下载mysql文件,其中包括了Dockerfile,内容如下:
#本文参考了「tutum」的 Dockerfile FROM sshd MAINTAINER Waitfish <dwj_zz@163.com> #安装软件 ENV DEBIAN_FRONTEND noninteractive RUN apt-get update && \ apt-get -yq install mysql-server-5.6 pwgen && \ rm -rf /var/lib/apt/lists/* # 删除预安装的数据库文件 RUN rm -rf /var/lib/mysql/* # 添加文件夹下的 MYSQL 配置文件 ADD my.cnf /etc/mysql/conf.d/my.cnf ADD mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf # 添加 MYSQL 的脚本 ADD import_sql.sh /import_sql.sh ADD run.sh /run.sh RUN chmod 755 /*.sh # 设置环境变量,用户名以及秘密 ENV MYSQL_USER admin ENV MYSQL_PASS **Random** # 设置主从复制模式下的环境变量 ENV REPLICATION_MASTER **False** ENV REPLICATION_SLAVE **False** ENV REPLICATION_USER replica ENV REPLICATION_PASS replica # 设置可以允许挂载的卷,可以用来备份数据库和配置文件 VOLUME ["/etc/mysql", "/var/lib/mysql"] # 设置可以映射的端口,如果是从我们的 sshd 镜像继承的话,默认还会开启 22 端口 EXPOSE 3306 CMD ["/run.sh"] |
3. 用build –t建立镜像,如果你有相应的变量或者是端口的改变,可以参照上面Dockerfile的注解进行相应的修改
2. Docker compose
2.1. Docker compose的安装
运行下边的命令来安装 Compose:
curl -Lhttps://github.com/docker/compose/releases/download/1.3.1/docker-compose-`uname-s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x/usr/local/bin/docker-compose
注意:如果你在安装的时候出现了 “Permissiondenied” 的错误信息,这说明你的 /usr/local/bin
目录是不可写的,你需要使用超级用户来安装。运行 sudo -i
, 然后运行上边的两个命令,然后 exit
退出。如果你用的是阿里云服务器,并且已经是超级用户还出现上述问题可以用以下命令处理:
首先先查看一下属性,查看该文件是否带i属性,如果带的话去掉i属性
lsattr <FileName>
去掉i属性
chattr –i <FileName>
之后赋予权限
chomd 777 <FileName>
执行上面的两个命令
上面的安装方法会相当的慢,我这里安装目测很可能超过8、9个小时,所以你不妨尝试下面的方法
你也可以在 shell 中使用命令行安装。Compose 适用于 OS X 和 64位的Linux。 如果你使用其他平台,你可以安装一个 Compose 的Python 包来完成安装。
apt-getinstall python-pip python-dev
pip install docker-compose
chomd +x /usr/local/bin/docker-compose
到这里安装就结束了;Compose已经安装完成。你可以使用 docker-compose--version 来进行测试
(这里很可能出现这样的问题Cannot open self/usr/local/bin/docker-compose or archive /usr/local/bin/docker-compose.pkg,把/usr/local/bin/docker-compose删掉或者再次执行pip,多试几次,我就是这样之后它就好了)
2.2. Docker Compose的工作原理
DockerCompose将所管理的容器分为三层,工程(project),服务(service)以及容器(contaienr)。Docker Compose运行的目录下的所有文件(docker-compose.yml, extends文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。一个服务当中可包括多个容器实例,Docker Compose并没有解决负载均衡的问题,因此需要借助其他工具实现服务发现及负载均衡。Docker Compose的工程配置文件默认为docker-compose.yml,可通过环境变量COMPOSE_FILE或-f参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器。
DockerCompose提供一个简单的基于YAML配置语言,用于描述和组装多容器的分布式应用。 使用docker定义和运行复杂的应用,使用compose,可以在一个文件里,定义多容器的应用。只需要三步即可完成一个应用的创建。
l Dockerfile定义app的运行环境
l docker-compose.yml定义组成app的services
l run
2.3. Docker Compose运行python工程
从这里开始我们要建立一个简单的python web应用在docker compose运行,这个应用Flask framework和maintains(一个点击计数器用的是Redis),当然也使用了python,如果你不熟悉的话我将在下面进行演示
准备工作
你必须安装了docker和docker compose
2.3.1. 建立工程文件夹
建造一个文件夹用来放你的工程
mkdir composetest
cd composetest
2.3.2. 创建app.py
在工程文件夹建立app.py文件,并写入以下内容:
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis',port=6379)
@app.route('/')
def hello():
count = redis.incr('hits')
return 'Hello World! I have been seen {} times.\n'.format(count)
if __name__ =="__main__":
app.run(host="0.0.0.0", debug=True)
2.3.3. 创建requirements.txt
建立另一个文件requirements.txt,并写入以下内容:
flask
redis
2.3.4. 建立Dockerfile
这一步你需要创建Dockerfile,以便创建docker镜像,这个镜像容器仅仅依赖python
在你的工程文件夹中建立Dockerfile,并加入以下的内容:
FROM python:3.4-alpine
ADD. /code
WORKDIR/code
RUNpip install -r requirements.txt
CMD["python", "app.py"]
这是为了告诉docker:
l 建立这个镜像需要python3.4基础镜像
l 把镜像放入当前文件夹中的code
l 创建文件夹code
l 安装python依赖的程序
l 用系统命令建立容器通过python app.py
关于Dockerfile怎么写可参考https://docs.docker.com/engine/getstarted/step_four/和
https://docs.docker.com/engine/reference/builder/
2.3.5. 定义服务在compose文件中
在工程文件中建立docker-compose.yml并写下以下内容:
version:'2'
services:
web:
build: .
ports:
-"5000:5000"
volumes:
- .:/code
redis:
image:"redis:alpine"
在compose文件中定义了两个服务,web和redis,这两个web服务:
l 使用一个镜像(通过Dockerfile在当前文件建立的镜像)
l 映射容器的端口5000到机器端口的5000
l 将项目目录安装在容器的主机/代码上,可以省去修改完代码重建镜像的麻烦
The redis
service uses a public Redis imagepulled from the Docker Hub registry.
Tip:你的工程文件最好建立在你的用户文件中[cd ~]
2.3.6. 用compose建立和运行你的app
进入你的工程文件夹中,运行一下命令:
docker-compose up
2.3.7. 输入IP:5000在浏览器中访问
2.4. Docker Compose运行php工程
2.4.1. 建立工程文件夹
mikdr php
cd php
2.4.2. 建立docker-compopse.yml
version: '2'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: root
MYSQL_PASSWORD: root
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_PASSWORD: root
volumes:
db_data:
2.4.3. 运行
docker-compose up -d
2.5. Docker Compose Yaml文件参考
composer 文件格式有两种版本:
l version 1: 已经废弃,不支持volumes 和 networks,默认 version key 是省略的。
l version 2: 推荐的格式,目前是最新的,需要通过 version '2' 指定
在上面的yaml文件中,我们可以看到compose文件的基本结构。首先是定义一个服务名,下面是yaml服务中的一些选项条目:
image:镜像ID,镜像文件不存在,Compose会尝试去远端拉取。
build:直接从pwd的Dockerfile来build,而非通过image选项来pull
link:link到其他服务容器,可以使用服务名+alias(SERVICE:ALIAS ), 也可以只使用服务名。每个占一行,格式为SERVICE[:ALIAS],例如 – db[:database]
web:
links:
- db
- db:database
- redis
external_links:连接到该compose.yaml文件之外的容器中,比如是提供共享或者通用服务的容器服务。格式同links
command:替换默认的command命令
ports:导出端口。格式可以是:
ports:-"3000"-"8000:8000"-"127.0.0.1:8001:8001"
expose:导出端口,但不映射到宿主机的端口上。它仅对links的容器开放。格式直接指定端口号即可。
expose:
- "3000"
- "8000"
volumes:加载路径作为卷,可以指定只读模式:
volumes:-/var/lib/mysql
- cache/:/tmp/cache
-~/configs:/etc/configs/:ro
volumes_from:加载其他容器或者服务的所有卷
environment:-RACK_ENV=development
- SESSION_SECRET
env_file:从一个文件中导入环境变量,文件的格式为RACK_ENV=development
extends:扩展另一个服务,可以覆盖其中的一些选项。一个sample如下:
common.yml
webapp:
build:./webapp
environment:- DEBUG=false- SEND_EMAILS=false
development.yml
web:extends:
file:common.yml
service: webapp
ports:-"8000:8000"
links:- db
environment:- DEBUG=true
db:
image: postgres
net:容器的网络模式,可以为”bridge”, “none”, “container:[nameor id]”, “host”中的一个。
dns:可以设置一个或多个自定义的DNS地址。
dns_search:可以设置一个或多个DNS的扫描域。
其他的working_dir, entrypoint, user, hostname, domainname,mem_limit, privileged, restart, stdin_open, tty, cpu_shares,和docker run命令是一样的,这些命令都是单行的命令。例如:
cpu_shares:73
working_dir:/code
entrypoint:/code/entrypoint.sh
user: postgresql
hostname: foo
domainname: foo.com
mem_limit:1000000000
privileged:true
restart: always
stdin_open:true
tty:true
depends_on表示服务之间的依赖关系, 有两个影响:
l docker-compose up 将会根据依赖关系的顺序开启所有服务,下面的例子中,db 和redis 会早于web 服务先启动。
l docker-compose up SERVICE 会自动包含 SERVICE 的依赖,下面的例子中, docker-compose up web 将会创建,同时也会启动 db 和 redis 服务。
version: '2'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
web 服务启动前并不会等待db和redis到ready状态才启动。如果需要等待其他服务到ready状态,可以参考 Controlling startuporder
environment添加环境变量。可以是数组或者字典格式。任何的boolean值(eg: true , false , yes, no )都需要被引号引用,避免被 YAML 解析器解析为 True 或 False。只有一个key的环境变量可以在运行Compose的机器上找到对应的值,这有助于加密的或者特殊主机的值,也可以与env_file同时使用,env_file用来指定一个文件,在这个文件中有变量的默认值与变量名称,而environment用来对变量值进行从新赋值
environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET
2.6. Docker Compose常见的命令
在第二节中的docker-compose up,这两个容器都是在前台运行的。我们可以指定-d命令以daemon的方式启动容器。除此之外,docker-compose还支持下面参数:
--verbose:输出详细信息
-f 制定一个非docker-compose.yml命名的yaml文件
-p 设置一个项目名称(默认是directory名)
docker-compose的动作包括:
build:构建服务
kill -s SIGINT:给服务发送特定的信号。
logs:输出日志
port:输出绑定的端口
ps:输出运行的容器
pull:pull服务的image
rm:删除停止的容器
run: 运行某个服务,例如docker-composerun web python manage.py shell
start:运行某个服务中存在的容器。
stop:停止某个服务中存在的容器。
up:create + run +attach容器到服务。
scale:设置服务运行的容器数量。例如:docker-composescale web=2 worker=3
2.7. Docker Compose一些常见问题
2.7.1. links 与 depends_on 的区别
link:
当你创建一个数据库容器,比如:
docker run -d --name=test-mysql --env="MYSQL_ROOT_PASSWORD=mypassword"-P mysql
docker inspect d54cf8a0fb98 |grep HostPort
这样你可以在本机找到:
"HostPort":"32777"
这就意味着你可以连接数据库用本地的端口32777(在容器中为3306)。但是这个端口是会随时改变的当你重启或者移除容器时。所以为保证你总是可以连接上并且并不知道端口时可以用link
web:
links:
- db
depend_on:
当docker-compose使用version: '2'时,它会自动生成所有文件中定义的容器之间的一个网络,每个容器将立即指向docker-compose.yml文件中定义的容器名字,并且我们不再需要连接;连接数据库与我们web的网络已经建立完成通过docker-compose
depend_on明确了从属关系:
l docker-compose启动容器将根据容器从属顺序启动,就像例子中的,db和redis将先于web启动
l docker-compose up服务将自动包含服务依赖,就像例子中的docker-compose up也将创建db和redis
Simple example:
version: '2'
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
2.7.2. 环境变量environment的使用
environment
加入环境变量,可以使用数组或者字典,只有一个key的环境变量可以在运行Compose的机器上找到对应的值,这有助于加密的或者特殊主机的值
environment:
RACK_ENV: development
SESSION_SECRET:
environments:
- RACK_ENV=development
- SESSION_SECRET 123456
env_file
从一个文件中加入环境变量,该文件可以是一个单独的值或者一张列表,在environment中指定的环境变量将会重写这些值
env_file:
- .env RACK_ENV: development 12345