赞
踩
基础镜像信息
维护者信息
镜像操作指令
容器启动时执行指令
指明构建的新镜像是来自于哪个基础镜像,例如:
FROM centos:6
指明镜像维护着及其联系方式(一般是邮箱地址),例如:
MAINTAINER Edison Zhou <xxx@xxx.com>
不过,MAINTAINER并不推荐使用,更推荐使用LABEL来指定镜像作者,例如:
LABEL maintainer="xxxxx.cn"
构建镜像时运行的Shell命令,例如:
RUN ["yum", "install", "httpd"]
RUN yum install httpd
启动容器时执行的Shell命令,例如:
CMD ["-C", "/start.sh"]
CMD ["/usr/sbin/sshd", "-D"]
CMD /usr/sbin/sshd -D
声明容器运行的服务端口,例如:
EXPOSE 80 443
设置环境内环境变量,例如:
ENV MYSQL_ROOT_PASSWORD 123456
ENV JAVA_HOME /usr/local/jdk1.8.0_45
拷贝文件或目录到镜像中,例如:
ADD <src>...<dest>
ADD html.tar.gz /var/www/html
ADD https://xxx.com/html.tar.gz /var/www/html
***PS:***如果是URL或压缩包,会自动下载或自动解压
拷贝文件或目录到镜像中,用法同ADD,只是不支持自动下载和解压,例如:
COPY ./start.sh /start.sh
启动容器时执行的Shell命令,同CMD类似,只是由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定指定的程序,例如:
ENTRYPOINT ["/bin/bash", "-C", "/start.sh"]
ENTRYPOINT /bin/bash -C '/start.sh'
***PS:***Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效。
指定容器挂载点到宿主机自动生成的目录或其他容器,例如:
VOLUME ["/var/lib/mysql"]
***PS:***一般不会在Dockerfile中用到,更常见的还是在docker run的时候指定-v数据卷。
为RUN、CMD和ENTRYPOINT执行Shell命令指定运行用户,例如:
USER <user>[:<usergroup>]
USER <UID>[:<UID>]
USER edisonzhou
为RUN、CMD、ENTRYPOINT以及COPY和AND设置工作目录,例如:
WORKDIR /data
告诉Docker如何测试容器以检查它是否仍在工作,即健康检查,例如:
HEALTHCHECK --interval=5m --timeout=3s --retries=3 \
CMD curl -f http:/localhost/ || exit 1
其中,一些选项的说明:
一些返回值的说明:
在构建镜像时,指定一些参数,例如:
FROM centos:6
ARG user # ARG user=root
USER $user
这时,在docker build时可以带上自定义参数user了,如下所示:
docker build --build-arg user=xxxxx Dockerfile .
.dockerignore` 语法与 `.gitignore` 语法一致。使用它排除构建无关的文件及目录,如 `node_modules
对于多阶段构建,可以在 Dockerfile 中使用多个 FROM
语句。每个 FROM
指令都可以使用不同的基镜像,并且它们都开始了构建的新阶段,示例如下:
FROM golang:1.7.3
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
在这种模式下,第二个FROM会以alpine:latest镜像为基础,开始一个新的构建,其中**–from=0**意为将前一阶段的构建工件复制到此新阶段。Go SDK 和任何中间工件都会被留下,不会保存在最终的镜像中
FROM
指令从 0 开始,也可以通过添加一个 AS <NAME>
到 FROM
指令来命名阶段,示例如下:
FROM golang:1.7.3 AS builder
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
CMD ["./app"]
在构建映像时,不必构建包括每个阶段的整个 Dockerfile。你可以指定目标构建阶段。以下命令假设你正在使用之前的 Dockerfile
,但是在名为 builder
的阶段停止:
$ docker build --target builder -t alexellis2/href-counter:latest .
这可能非常强有力的几个场景是:
调试(debug)
阶段和一个精益的 生产(production)
阶段测试(testing)
阶段,在这个阶段你的应用会被测试数据填充,但是在构建产品时,使用一个使用真实数据的不同阶段。当使用多阶段构建时,您不受限于从 Dockerfile 中先前创建的阶段进行复制。您可以使用 COPY --from
指令从单独的镜像中进行复制,可以使用本地镜像名称、本地或 Docker 注册表上可用的标签或标签 ID。Docker 客户端会在必要时拉取镜像并从中复制工件。语法是:
COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf
在使用 FROM
指令时,您可以引用前一阶段的内容。例如:
FROM alpine:latest as builder
RUN apk --no-cache add build-base
FROM builder as build1
COPY source1.cpp source.cpp
RUN g++ -o /binary source.cpp
FROM builder as build2
COPY source2.cpp source.cpp
RUN g++ -o /binary source.cpp
减小体积,减少构建时间。如前端应用使用 npm install --production
只装生产环境所依赖的包。
如一个web应用将会包含三个部分,web 服务,数据库与缓存。把他们解耦到多个容器中,方便横向扩展。如果你需要网络通信,则可以将他们至于一个网络下,示例如下:
version: '3' services: # 该镜像会暴露出自身的 `header` 信息 whoami: image: containous/whoami restart: always labels: # 设置Host 为 whoami.docker.localhost 进行域名访问 - "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)" # 使用已存在的 traefik 的 network networks: default: external: name: traefik_default
RUN
, COPY
, ADD
会创建层数, 其它指令不会增加镜像的体积使用以下方法安装依赖
RUN yum install -y node python go
错误的方法安装依赖,这将增加镜像层数
RUN yum install -y node
RUN yum install -y python
RUN yum install -y go
便于可读性以及不小心地重复装包
RUN apt-get update && apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion
在镜像的构建过程中 docker
会遍历 Dockerfile
文件中的所有指令,顺序执行。对于每一条指令,docker
都会在缓存中查找是否已存在可重用的镜像,否则会创建一个新的镜像
我们可以使用 docker build --no-cache
跳过缓存
ADD
和 COPY
将会计算文件的 checksum
是否改变来决定是否利用缓存RUN
仅仅查看命令字符串是否命中缓存,如 RUN apt-get -y update
可能会有问题如一个 node
应用,可以先拷贝 package.json
进行依赖安装,然后再添加整个目录,可以做到充分利用缓存的目的。
FROM node:10-alpine as builder
WORKDIR /code
ADD package.json /code
# 此步将可以充分利用 node_modules 的缓存
RUN npm install --production
ADD . /code
RUN npm run build
命令用于使用 Dockerfile 创建镜像
docker build [OPTIONS] PATH | URL | - --build-arg=[] :设置镜像创建时的变量; --cpu-shares :设置 cpu 使用权重; --cpu-period :限制 CPU CFS周期; --cpu-quota :限制 CPU CFS配额; --cpuset-cpus :指定使用的CPU id; --cpuset-mems :指定使用的内存 id; --disable-content-trust :忽略校验,默认开启; -f :指定要使用的Dockerfile路径; --force-rm :设置镜像过程中删除中间容器; --isolation :使用容器隔离技术; --label=[] :设置镜像使用的元数据; -m :设置内存最大值; --memory-swap :设置Swap的最大值为内存+swap,"-1"表示不限swap; --no-cache :创建镜像的过程不使用缓存; --pull :尝试去更新镜像的新版本; --quiet, -q :安静模式,成功后只输出镜像 ID; --rm :设置镜像成功后删除中间容器; --shm-size :设置/dev/shm的大小,默认值是64M; --ulimit :Ulimit配置。 --tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式;可以在一次构建中为一个镜像设置多个标签。 --network: 默认 default。在构建期间设置RUN指令的网络模式
示例如下,使用当前目录的 Dockerfile 创建镜像,标签为 runoob/ubuntu:v1:
docker build -t runoob/ubuntu:v1 .
从容器创建一个新的镜像
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;
-p :在commit时,将容器暂停。
示例如下:
docker commit -a "runoob.com" -m "my apache" a404c6c174a2 mymysql:v1
标记本地镜像,将其归入某一仓库
docker tag [OPTIONS] IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]
示例如下,将镜像ubuntu:15.10标记为 runoob/ubuntu:v3 镜像:
docker tag ubuntu:15.10 runoob/ubuntu:v3
docker-compose.yml组成一个project,project里包括多个service,每个service定义了容器运行的镜像(或构建镜像),网络端口,文件挂载,参数,依赖等,每个service可包括同一个镜像的多个容器实例,即 project 包含 service ,service 包含 container ,示例如下:
version:"3.7"
services:
webapp:
build:
context:./dir
dockerfile:Dockerfile-alternate
args:
buildno:1
指定 docker-compose.yml 文件的写法格式
多个容器集合environment:环境变量配置,可以用数组或字典两种方式
指定服务所使用的镜像
image: java
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数(一般用来标识镜像使用的端口,方便用ports映射)
expose:
- "3000"
- "8000"
定义宿主机端口和容器端口的映射,可使用宿主机IP+宿主机端口进行访问 宿主机端口:容器端口
ports: # 暴露端口信息 - "宿主机端口:容器暴露端口"
- "8763:8763"
- "8763:8763"
动态挂载,卷挂载路径,定义宿主机的目录/文件和容器的目录/文件的映射 宿主机路径:容器路径
volumes:
# 只需指定一个路径,让引擎创建一个卷
- /var/lib/mysql
# 指定绝对路径映射
- /opt/data:/var/lib/mysql
# 相对于当前compose文件的相对路径
- ./cache:/tmp/cache
# 用户家目录相对路径
- ~/configs:/etc/configs/:ro
# 命名卷
- datavolume:/var/lib/mysql
添加环境变量,可以使用数组或字典两种形式, 任何布尔值; true,false,yes,no需要用引号括起来,以确保它们不被YML解析器转换为True或False
environment:
RACK_ENV: development
SHOW: 'true'
SESSION_SECRET:
environment:
- RACK_ENV=development
- SHOW=true
- SESSION_SECRET
规定service加载顺序,例如数据库服务需要在后台服务前运行
version: '2'
services:
db:
image: postgres
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
类似于docker里的–add-host参数 配置DNS域名解析(域名和IP的映射)
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
默认值为 no
,即在任何情况下都不会重新启动容器;当值为 always
时,容器总是重新启动;当值为 on-failure
时,当出现 on-failure
报错容器退出时,容器重新启动
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped
开启特权模式
指定容器运行的用户名
指定容器名称进行不同容器间的通信
web:
links:
- db
- db:database
- redis
日志服务
logging:
driver: "gelf"
options:
gelf-address: "udp://graylogserver:12201"
tag: front-tomcat
设置网络模式
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
置构建时,Compose 会利用它自动构建镜像,该值可以是一个路径,也可以是一个对象,用于指定 Dockerfile 路径
注:如果指定build同时也指定image,那么会从build里构建,镜像的名字和tag将取image指定的
日志服务
logging:
driver: "gelf"
options:
gelf-address: "udp://graylogserver:12201"
tag: front-tomcat
设置网络模式
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
置构建时,Compose 会利用它自动构建镜像,该值可以是一个路径,也可以是一个对象,用于指定 Dockerfile 路径
注:如果指定build同时也指定image,那么会从build里构建,镜像的名字和tag将取image指定的
覆盖容器启动后默认执行的命令
command: bundle exec thin -p 3000
----------------------------------
command: [bundle,exec,thin,-p,3000]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。