Update dockerfile format

This commit is contained in:
khs1994 2018-12-31 14:50:01 +08:00
parent 11e2bf1701
commit 234ac706a3
No known key found for this signature in database
GPG Key ID: 0A380828B1C243A7
5 changed files with 26 additions and 34 deletions

View File

@ -36,7 +36,7 @@
下面是来自 `buildpack-deps` 镜像的例子:
```docker
```dockerfile
RUN apt-get update && apt-get install -y \
bzr \
cvs \
@ -72,7 +72,7 @@ RUN apt-get update && apt-get install -y \
>注意:如果你的字符串中包含空格,必须将字符串放入引号中或者对空格使用转义。如果字符串内容本身就包含引号,必须对引号使用转义。
```docker
```dockerfile
# Set one or more individual labels
LABEL com.example.version="0.0.1-beta"
@ -85,7 +85,7 @@ LABEL com.example.version.is-production=""
一个镜像可以包含多个标签,但建议将多个标签放入到一个 `LABEL` 指令中。
```docker
```dockerfile
# Set multiple labels at once, using line-continuation characters to break long lines
LABEL vendor=ACME\ Incorporated \
com.example.is-beta= \
@ -108,7 +108,7 @@ LABEL vendor=ACME\ Incorporated \
永远将 `RUN apt-get update``apt-get install` 组合成一条 `RUN` 声明,例如:
```docker
```dockerfile
RUN apt-get update && apt-get install -y \
package-bar \
package-baz \
@ -117,7 +117,7 @@ RUN apt-get update && apt-get install -y \
`apt-get update` 放在一条单独的 `RUN` 声明中会导致缓存问题以及后续的 `apt-get install` 失败。比如,假设你有一个 `Dockerfile` 文件:
```docker
```dockerfile
FROM ubuntu:18.04
RUN apt-get update
@ -127,7 +127,7 @@ RUN apt-get install -y curl
构建镜像后,所有的层都在 Docker 的缓存中。假设你后来又修改了其中的 `apt-get install` 添加了一个包:
```docker
```dockerfile
FROM ubuntu:18.04
RUN apt-get update
@ -139,7 +139,7 @@ Docker 发现修改后的 `RUN apt-get update` 指令和之前的完全一样。
使用 `RUN apt-get update && apt-get install -y` 可以确保你的 Dockerfiles 每次安装的都是包的最新的版本,而且这个过程不需要进一步的编码或额外干预。这项技术叫作 `cache busting`。你也可以显示指定一个包的版本号来达到 `cache-busting`,这就是所谓的固定版本,例如:
```docker
```dockerfile
RUN apt-get update && apt-get install -y \
package-bar \
package-baz \
@ -150,7 +150,7 @@ RUN apt-get update && apt-get install -y \
下面是一个 `RUN` 指令的示例模板,展示了所有关于 `apt-get` 的建议。
```docker
```dockerfile
RUN apt-get update && apt-get install -y \
aufs-tools \
automake \
@ -193,7 +193,7 @@ RUN apt-get update && apt-get install -y \
最后,`ENV` 也能用于设置常见的版本号,比如下面的示例:
```docker
```dockerfile
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
@ -211,7 +211,7 @@ ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
如果你的 `Dockerfile` 有多个步骤需要使用上下文中不同的文件。单独 `COPY` 每个文件,而不是一次性的 `COPY` 所有文件,这将保证每个步骤的构建缓存只在特定的文件变化时失效。例如:
```docker
```dockerfile
COPY requirements.txt /tmp/
RUN pip install --requirement /tmp/requirements.txt
@ -223,7 +223,7 @@ COPY . /tmp/
为了让镜像尽量小,最好不要使用 `ADD` 指令从远程 URL 获取包,而是使用 `curl``wget`。这样你可以在文件提取完之后删掉不再需要的文件来避免在镜像中额外添加一层。比如尽量避免下面的用法:
```docker
```dockerfile
ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
@ -233,7 +233,7 @@ RUN make -C /usr/src/things all
而是应该使用下面这种方法:
```docker
```dockerfile
RUN mkdir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.xz \
| tar -xJC /usr/src/things \
@ -250,7 +250,7 @@ RUN mkdir -p /usr/src/things \
例如,下面的示例镜像提供了命令行工具 `s3cmd`:
```docker
```dockerfile
ENTRYPOINT ["s3cmd"]
CMD ["--help"]
@ -295,7 +295,7 @@ exec "$@"
该辅助脚本被拷贝到容器,并在容器启动时通过 `ENTRYPOINT` 执行:
```docker
```dockerfile
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]

View File

@ -8,7 +8,7 @@
第一步,因为应用将要运行在一个满足所有环境依赖的 Docker 容器里面,那么我们可以通过编辑 `Dockerfile` 文件来指定 Docker 容器要安装内容。内容如下:
```docker
```dockerfile
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code

View File

@ -8,7 +8,7 @@
首先,因为应用将要运行在一个满足所有环境依赖的 Docker 容器里面,那么我们可以通过编辑 `Dockerfile` 文件来指定 Docker 容器要安装内容。内容如下:
```docker
```dockerfile
FROM ruby
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
RUN mkdir /myapp

View File

@ -40,7 +40,7 @@ if __name__ == "__main__":
编写 `Dockerfile` 文件,内容为
```docker
```dockerfile
FROM python:3.6-alpine
ADD . /code
WORKDIR /code
@ -60,7 +60,7 @@ services:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
```

View File

@ -8,15 +8,11 @@
一种方式是将所有的构建过程编包含在一个 `Dockerfile` 中,包括项目及其依赖库的编译、测试、打包等流程,这里可能会带来的一些问题:
* `Dockerfile` 特别长,可维护性降低
* 镜像层次多,镜像体积较大,部署时间变长
* 源代码存在泄露的风险
例如
编写 `app.go` 文件,该程序输出 `Hello World!`
例如,编写 `app.go` 文件,该程序输出 `Hello World!`
```go
package main
@ -30,7 +26,7 @@ func main(){
编写 `Dockerfile.one` 文件
```docker
```dockerfile
FROM golang:1.9-alpine
RUN apk --no-cache add git ca-certificates
@ -58,11 +54,9 @@ $ docker build -t go/helloworld:1 -f Dockerfile.one .
另一种方式,就是我们事先在一个 `Dockerfile` 将项目及其依赖库编译测试打包好后,再将其拷贝到运行环境中,这种方式需要我们编写两个 `Dockerfile` 和一些编译脚本才能将其两个阶段自动整合起来,这种方式虽然可以很好地规避第一种方式存在的风险,但明显部署过程较复杂。
例如
例如,编写 `Dockerfile.build` 文件
编写 `Dockerfile.build` 文件
```docker
```dockerfile
FROM golang:1.9-alpine
RUN apk --no-cache add git
@ -77,7 +71,7 @@ RUN go get -d -v github.com/go-sql-driver/mysql \
编写 `Dockerfile.copy` 文件
```docker
```dockerfile
FROM alpine:latest
RUN apk --no-cache add ca-certificates
@ -129,11 +123,9 @@ go/helloworld 1 f55d3e16affc 2 minutes ago 295MB
为解决以上问题Docker v17.05 开始支持多阶段构建 (`multistage builds`)。使用多阶段构建我们就可以很容易解决前面提到的问题,并且只需要编写一个 `Dockerfile`
例如
例如,编写 `Dockerfile` 文件
编写 `Dockerfile` 文件
```docker
```dockerfile
FROM golang:1.9-alpine as builder
RUN apk --no-cache add git
@ -184,7 +176,7 @@ go/helloworld 1 f55d3e16affc 2 minutes ago 295MB
FROM golang:1.9-alpine as builder
```
例如当我们只想构建 `builder` 阶段的镜像时,我们可以在使用 `docker build` 命令时加上 `--target` 参数即可
例如当我们只想构建 `builder` 阶段的镜像时,增加 `--target=builder` 参数即可
```bash
$ docker build --target builder -t username/imagename:tag .