mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-10 20:04:36 +00:00
Fix and improve
This commit is contained in:
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
WORKDIR <工作目录路径>
|
||||
```
|
||||
@@ -14,8 +12,6 @@ WORKDIR <工作目录路径>
|
||||
|
||||
### 基本用法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
WORKDIR /app
|
||||
|
||||
@@ -30,8 +26,6 @@ COPY . . # 复制到 /app/
|
||||
|
||||
#### 常见错误
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 错误:cd 在下一个 RUN 中无效
|
||||
|
||||
@@ -41,8 +35,6 @@ RUN echo "hello" > world.txt # 文件在根目录!
|
||||
|
||||
#### 原因分析
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
RUN cd /app
|
||||
↓
|
||||
@@ -58,8 +50,6 @@ RUN echo "hello" > world.txt
|
||||
|
||||
#### 正确做法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 正确:使用 WORKDIR
|
||||
|
||||
@@ -85,8 +75,6 @@ RUN pwd # 输出 /a/b/c
|
||||
|
||||
### 使用环境变量
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENV APP_HOME=/app
|
||||
WORKDIR $APP_HOME
|
||||
@@ -98,8 +86,6 @@ RUN pwd # 输出 /app
|
||||
|
||||
### 多阶段构建中的 WORKDIR
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 构建阶段
|
||||
|
||||
@@ -123,8 +109,6 @@ COPY --from=builder /build/dist .
|
||||
|
||||
#### 1. 尽早设置 WORKDIR
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM node:20
|
||||
WORKDIR /app # 尽早设置
|
||||
@@ -137,8 +121,6 @@ CMD ["node", "server.js"]
|
||||
|
||||
#### 2. 使用绝对路径
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 推荐:绝对路径,意图明确
|
||||
|
||||
@@ -151,8 +133,6 @@ WORKDIR app
|
||||
|
||||
#### 3. 不要用 RUN cd
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 避免
|
||||
|
||||
@@ -166,8 +146,6 @@ RUN echo "hello" > world.txt
|
||||
|
||||
#### 4. 适时重置 WORKDIR
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
WORKDIR /app
|
||||
## ... 应用相关操作 ...
|
||||
@@ -175,8 +153,7 @@ WORKDIR /app
|
||||
WORKDIR /data
|
||||
## ... 数据相关操作 ...
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
@@ -224,6 +201,6 @@ $ docker run -w /tmp myimage pwd
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [COPY 复制文件](copy.md):文件复制
|
||||
- [RUN 执行命令](../../04_image/4.5_build.md):执行构建命令
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
- [COPY 复制文件](7.2_copy.md):文件复制
|
||||
- [RUN 执行命令](../04_image/4.5_build.md):执行构建命令
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
USER <用户名>[:<用户组>]
|
||||
USER <UID>[:<GID>]
|
||||
@@ -39,8 +37,6 @@ root 用户运行的风险:
|
||||
|
||||
#### 创建并切换用户
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM node:20-alpine
|
||||
|
||||
@@ -65,8 +61,6 @@ CMD ["node", "server.js"]
|
||||
|
||||
#### 使用 UID/GID
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 也可以使用数字
|
||||
|
||||
@@ -214,8 +208,6 @@ CMD ["node", "server.js"]
|
||||
|
||||
#### 1. 始终使用非 root 用户
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 推荐
|
||||
|
||||
@@ -242,8 +234,6 @@ USER 1000:1000
|
||||
|
||||
#### 3. 多阶段构建中的 USER
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 构建阶段可以用 root
|
||||
|
||||
@@ -302,6 +292,6 @@ RUN mkdir -p /app/data && chown appuser:appuser /app/data
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [安全](../../security/README.md):容器安全实践
|
||||
- [ENTRYPOINT](entrypoint.md):入口脚本中的用户切换
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 安全
|
||||
- [安全](../11_ops/security/README.md):容器安全实践
|
||||
- [ENTRYPOINT](7.5_entrypoint.md):入口脚本中的用户切换
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 安全
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
HEALTHCHECK [选项] CMD <命令>
|
||||
HEALTHCHECK NONE
|
||||
@@ -38,8 +36,6 @@ Starting ──成功──> Healthy ──失败N次──> Unhealthy
|
||||
|
||||
#### Web 服务检查
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM nginx
|
||||
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
|
||||
@@ -94,8 +90,6 @@ HEALTHCHECK CMD wget -q --spider http://localhost/ || exit 1
|
||||
|
||||
#### 数据库
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## MySQL
|
||||
|
||||
@@ -108,8 +102,6 @@ HEALTHCHECK CMD redis-cli ping || exit 1
|
||||
|
||||
#### 自定义脚本
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
COPY healthcheck.sh /usr/local/bin/
|
||||
HEALTHCHECK CMD ["healthcheck.sh"]
|
||||
@@ -119,7 +111,7 @@ HEALTHCHECK CMD ["healthcheck.sh"]
|
||||
|
||||
### 在 Compose 中使用
|
||||
|
||||
可以在 `docker-compose.yml` 中覆盖或定义健康检查:
|
||||
可以在 `compose.yaml`(或 `docker-compose.yml`)中覆盖或定义健康检查:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -218,6 +210,6 @@ HEALTHCHECK --start-period=60s CMD curl -f http://localhost/ || exit 1
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [CMD 容器启动命令](cmd.md):启动主进程
|
||||
- [Compose 模板文件](../../compose/10.5_compose_file.md):Compose 中的健康检查
|
||||
- [Docker 调试](../../16_appendix/16.2_debug.md):容器排障
|
||||
- [CMD 容器启动命令](7.4_cmd.md):启动主进程
|
||||
- [Compose 模板文件](../10_compose/10.5_compose_file.md):Compose 中的健康检查
|
||||
- [Docker 调试](../16_appendix/16.2_debug.md):容器排障
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ONBUILD <其它指令>
|
||||
```
|
||||
@@ -52,16 +50,13 @@ FROM my-node-base
|
||||
|
||||
## 构建时会自动执行 COPY 和 RUN
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 执行机制
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
基础镜像构建:
|
||||
Dockerfile (含 ONBUILD) ──build──> 基础镜像 (记录了 ONBUILD 触发器)
|
||||
@@ -77,8 +72,6 @@ FROM 基础镜像 ──build──> 读取基础镜像触发器 ──> 执行
|
||||
|
||||
#### 1. 自动处理依赖安装
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Python 基础镜像
|
||||
|
||||
@@ -88,8 +81,6 @@ ONBUILD RUN pip install -r requirements.txt
|
||||
|
||||
#### 2. 自动编译代码
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Go 基础镜像
|
||||
|
||||
@@ -99,8 +90,6 @@ ONBUILD RUN go build -o app main.go
|
||||
|
||||
#### 3. 处理静态资源
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Nginx 静态网站基础镜像
|
||||
|
||||
@@ -165,5 +154,5 @@ python:3.12-onbuild
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [COPY 指令](copy.md):文件复制
|
||||
- [Dockerfile 最佳实践](../../16_appendix/16.1_best_practices.md):基础镜像设计
|
||||
- [COPY 指令](7.2_copy.md):文件复制
|
||||
- [Dockerfile 最佳实践](../16_appendix/16.1_best_practices.md):基础镜像设计
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
LABEL <key>=<value> <key>=<value> ...
|
||||
```
|
||||
@@ -25,8 +23,6 @@ LABEL <key>=<value> <key>=<value> ...
|
||||
|
||||
#### 定义单个标签
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
LABEL version="1.0"
|
||||
LABEL description="这是一个 Web 应用服务器"
|
||||
@@ -34,8 +30,6 @@ LABEL description="这是一个 Web 应用服务器"
|
||||
|
||||
#### 定义多个标签(推荐)
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
LABEL maintainer="user@example.com" \
|
||||
version="1.2.0" \
|
||||
@@ -65,8 +59,6 @@ LABEL maintainer="user@example.com" \
|
||||
|
||||
#### 示例
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
LABEL org.opencontainers.image.authors="yeasy" \
|
||||
org.opencontainers.image.documentation="https://yeasy.gitbooks.io" \
|
||||
@@ -101,7 +93,7 @@ LABEL org.opencontainers.image.authors="user@example.com"
|
||||
|
||||
### 动态标签
|
||||
|
||||
配合 `ARG` 使用,可以在构建时动态注入标签:
|
||||
配合 `ARG` 使用,可以在构建时动态注入标签:
|
||||
|
||||
```docker
|
||||
ARG BUILD_DATE
|
||||
@@ -164,4 +156,4 @@ $ docker rmi $(docker images -q --filter "label=stage=builder")
|
||||
### 延伸阅读
|
||||
|
||||
- [OCI 标签规范](https://github.com/opencontainers/image-spec/blob/main/annotations.md)
|
||||
- [Dockerfile 最佳实践](../../16_appendix/16.1_best_practices.md)
|
||||
- [Dockerfile 最佳实践](../16_appendix/16.1_best_practices.md)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
SHELL ["executable", "parameters"]
|
||||
```
|
||||
@@ -150,5 +148,5 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [RUN 指令](../../04_image/4.5_build.md):执行命令
|
||||
- [Dockerfile 最佳实践](../../16_appendix/16.1_best_practices.md):错误处理与调试
|
||||
- [RUN 指令](../04_image/4.5_build.md):执行命令
|
||||
- [Dockerfile 最佳实践](../16_appendix/16.1_best_practices.md):错误处理与调试
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
## 7.17 多阶段构建
|
||||
|
||||
## 之前的做法
|
||||
|
||||
在 Docker 17.05 版本之前,我们构建 Docker 镜像时,通常会采用两种方式:
|
||||
|
||||
### 全部放入一个 Dockerfile
|
||||
|
||||
一种方式是将所有的构建过程编包含在一个 `Dockerfile` 中,包括项目及其依赖库的编译、测试、打包等流程,这里可能会带来的一些问题:
|
||||
一种方式是将所有的构建过程包含在一个 `Dockerfile` 中,包括项目及其依赖库的编译、测试、打包等流程,这里可能会带来的一些问题:
|
||||
|
||||
* 镜像层次多,镜像体积较大,部署时间变长
|
||||
|
||||
|
||||
@@ -27,8 +27,7 @@ storage/
|
||||
|
||||
## 自行添加其他需要排除的文件,例如 .env.* 文件
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
在 `laravel.conf` 文件中写入 nginx 配置。
|
||||
@@ -123,8 +122,6 @@ RUN set -x ; cd ${LARAVEL_PATH} \
|
||||
|
||||
### 最后一个阶段构建 NGINX 镜像
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM nginx:alpine as nginx
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
RUN <command>
|
||||
RUN ["executable", "param1", "param2"]
|
||||
@@ -17,8 +15,6 @@ RUN ["executable", "param1", "param2"]
|
||||
|
||||
#### 1. Shell 格式
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
RUN apt-get update
|
||||
```
|
||||
@@ -32,8 +28,6 @@ RUN apt-get update
|
||||
|
||||
#### 2. Exec 格式
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
RUN ["apt-get", "update"]
|
||||
```
|
||||
@@ -105,8 +99,6 @@ RUN wget http://url | gzip -d > file
|
||||
|
||||
#### Q: 为什么 `RUN cd /app` 不生效?
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
RUN cd /app
|
||||
RUN touch hello.txt
|
||||
@@ -125,8 +117,6 @@ RUN touch hello.txt
|
||||
|
||||
#### Q: 环境变量不生效?
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
RUN export MY_VAR=hello
|
||||
RUN echo $MY_VAR
|
||||
@@ -189,6 +179,6 @@ RUN --mount=type=secret,id=mysecret \
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [CMD 容器启动命令](cmd.md):容器启动时的命令
|
||||
- [WORKDIR 指定工作目录](workdir.md):改变目录
|
||||
- [Dockerfile 最佳实践](../../16_appendix/16.1_best_practices.md)
|
||||
- [CMD 容器启动命令](7.4_cmd.md):容器启动时的命令
|
||||
- [WORKDIR 指定工作目录](7.10_workdir.md):改变目录
|
||||
- [Dockerfile 最佳实践](../16_appendix/16.1_best_practices.md)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
COPY [选项] <源路径>... <目标路径>
|
||||
COPY [选项] ["<源路径1>", "<源路径2>", ... "<目标路径>"]
|
||||
@@ -17,8 +15,6 @@ COPY [选项] ["<源路径1>", "<源路径2>", ... "<目标路径>"]
|
||||
|
||||
#### 复制单个文件
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 复制文件到指定目录
|
||||
|
||||
@@ -31,8 +27,6 @@ COPY config.json /app/settings.json
|
||||
|
||||
#### 复制多个文件
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 复制多个指定文件
|
||||
|
||||
@@ -46,8 +40,6 @@ COPY src/*.js /app/src/
|
||||
|
||||
#### 复制目录
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 复制整个目录的内容(不是目录本身)
|
||||
|
||||
@@ -86,9 +78,8 @@ COPY app[0-9].js /app/ # app0.js ~ app9.js
|
||||
|
||||
### 目标路径
|
||||
|
||||
#### 绝对路径
|
||||
|
||||
具体内容如下:
|
||||
#### 绝对路径
|
||||
|
||||
```docker
|
||||
COPY app.js /usr/src/app/
|
||||
@@ -96,8 +87,6 @@ COPY app.js /usr/src/app/
|
||||
|
||||
#### 相对路径(基于 WORKDIR)
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
WORKDIR /app
|
||||
COPY package.json ./ # 复制到 /app/package.json
|
||||
@@ -182,8 +171,6 @@ ADD app.tar.gz /app/
|
||||
|
||||
#### 从其他构建阶段复制
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 构建阶段
|
||||
|
||||
@@ -202,8 +189,6 @@ COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
#### 使用 --link 优化缓存(BuildKit)
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 使用 --link 后,文件以独立层添加,不依赖前序指令
|
||||
|
||||
@@ -243,8 +228,6 @@ Dockerfile
|
||||
|
||||
#### 1. 利用缓存,先复制依赖文件
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 好:先复制依赖定义,再安装,最后复制代码
|
||||
|
||||
@@ -260,22 +243,17 @@ RUN npm install
|
||||
|
||||
#### 2. 使用 .dockerignore
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 确保 node_modules 不被复制
|
||||
|
||||
COPY . .
|
||||
## .dockerignore 中应包含 node_modules
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 3. 明确复制路径
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 好:明确的路径
|
||||
|
||||
@@ -301,7 +279,7 @@ COPY . .
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [ADD 指令](add.md):复制和解压
|
||||
- [WORKDIR 指令](workdir.md):设置工作目录
|
||||
- [多阶段构建](../multistage-builds.md):优化镜像大小
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
- [ADD 指令](7.3_add.md):复制和解压
|
||||
- [WORKDIR 指令](7.10_workdir.md):设置工作目录
|
||||
- [多阶段构建](7.17_multistage_builds.md):优化镜像大小
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ADD [选项] <源路径>... <目标路径>
|
||||
ADD [选项] ["<源路径>", ... "<目标路径>"]
|
||||
@@ -31,9 +29,7 @@ ADD [选项] ["<源路径>", ... "<目标路径>"]
|
||||
|
||||
### 自动解压功能
|
||||
|
||||
#### 基本用法
|
||||
|
||||
具体内容如下:
|
||||
#### 基本用法(自动解压本地 tar)
|
||||
|
||||
```docker
|
||||
## 自动解压 tar.gz 到目标目录
|
||||
@@ -58,8 +54,6 @@ ADD ubuntu-noble-core-cloudimg-amd64-root.tar.gz /
|
||||
|
||||
#### 解压过程
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
ADD app.tar.gz /app/
|
||||
│
|
||||
@@ -79,8 +73,6 @@ app.tar.gz 包含: /app/ 目录结果:
|
||||
|
||||
#### 基本用法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 从 URL 下载文件
|
||||
|
||||
@@ -98,8 +90,6 @@ ADD https://example.com/app.zip /app/app.zip
|
||||
|
||||
#### 推荐替代方案
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 不推荐:使用 ADD 下载
|
||||
|
||||
@@ -120,8 +110,6 @@ RUN curl -fsSL https://example.com/app.tar.gz | tar -xz -C /app
|
||||
|
||||
### 修改文件所有者
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ADD --chown=node:node app.tar.gz /app/
|
||||
ADD --chown=1000:1000 files/ /app/
|
||||
@@ -133,8 +121,6 @@ ADD --chown=1000:1000 files/ /app/
|
||||
|
||||
#### ✅ 适合使用 ADD
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 解压本地 tar 文件
|
||||
|
||||
@@ -148,8 +134,6 @@ ADD dist.tar.gz /app/
|
||||
|
||||
#### ❌ 不适合使用 ADD
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 复制普通文件(用 COPY)
|
||||
|
||||
@@ -199,8 +183,6 @@ ADD app.tar.gz /app/
|
||||
|
||||
#### 1. 默认使用 COPY
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 大多数场景使用 COPY
|
||||
|
||||
@@ -209,8 +191,6 @@ COPY . /app/
|
||||
|
||||
#### 2. 仅在需要解压时使用 ADD
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 自动解压场景
|
||||
|
||||
@@ -219,8 +199,6 @@ ADD app.tar.gz /app/
|
||||
|
||||
#### 3. 不要用 ADD 下载文件
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 避免
|
||||
|
||||
@@ -233,8 +211,6 @@ RUN curl -fsSL https://example.com/file.tar.gz | tar -xz -C /app
|
||||
|
||||
#### 4. 解压后清理
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 如果需要控制解压过程
|
||||
|
||||
@@ -257,6 +233,6 @@ RUN tar -xzf /tmp/app.tar.gz -C /app && \
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [COPY 复制文件](copy.md):基本复制操作
|
||||
- [多阶段构建](../multistage-builds.md):减少镜像体积
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
- [COPY 复制文件](7.2_copy.md):基本复制操作
|
||||
- [多阶段构建](7.17_multistage_builds.md):减少镜像体积
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
|
||||
@@ -20,8 +20,6 @@ CMD 有三种格式:
|
||||
|
||||
#### exec 格式(推荐)
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
CMD ["python", "app.py"]
|
||||
@@ -35,8 +33,6 @@ CMD ["node", "server.js"]
|
||||
|
||||
#### shell 格式
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
CMD echo "Hello World"
|
||||
CMD nginx -g "daemon off;"
|
||||
@@ -70,8 +66,6 @@ CMD ["sh", "-c", "echo $HOME"]
|
||||
|
||||
#### 信号传递问题示例
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ shell 格式:docker stop 会超时
|
||||
|
||||
@@ -85,8 +79,7 @@ CMD node server.js
|
||||
CMD ["node", "server.js"]
|
||||
## SIGTERM 直接发给 node
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
@@ -117,8 +110,6 @@ CMD ["/bin/bash"] + cat /etc/os-release
|
||||
|
||||
#### 错误示例
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 容器启动后立即退出
|
||||
|
||||
@@ -127,8 +118,6 @@ CMD service nginx start
|
||||
|
||||
#### 原因分析
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
1. CMD service nginx start
|
||||
↓ 被转换为
|
||||
@@ -145,8 +134,6 @@ CMD service nginx start
|
||||
|
||||
#### 正确做法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 让 nginx 在前台运行
|
||||
|
||||
@@ -164,8 +151,6 @@ CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
#### 单独使用 CMD
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Dockerfile
|
||||
|
||||
@@ -179,8 +164,6 @@ $ docker run myimage curl -v ... # 完全覆盖
|
||||
|
||||
#### 搭配 ENTRYPOINT
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Dockerfile
|
||||
|
||||
@@ -193,7 +176,7 @@ $ docker run myimage # curl -s http://example.com
|
||||
$ docker run myimage http://other.com # curl -s http://other.com(参数覆盖)
|
||||
```
|
||||
|
||||
详见 [ENTRYPOINT 入口点](entrypoint.md) 章节。
|
||||
详见 [ENTRYPOINT 入口点](7.5_entrypoint.md) 章节。
|
||||
|
||||
---
|
||||
|
||||
@@ -201,8 +184,6 @@ $ docker run myimage http://other.com # curl -s http://other.com(参数覆盖
|
||||
|
||||
#### 1. 优先使用 exec 格式
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 推荐
|
||||
|
||||
@@ -215,8 +196,6 @@ CMD ["sh", "-c", "echo $PATH && python app.py"]
|
||||
|
||||
#### 2. 确保应用在前台运行
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 前台运行
|
||||
|
||||
@@ -232,8 +211,6 @@ CMD systemctl start nginx
|
||||
|
||||
#### 3. 使用双引号
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 正确:双引号
|
||||
|
||||
@@ -246,8 +223,6 @@ CMD ['node', 'server.js']
|
||||
|
||||
#### 4. 配合 ENTRYPOINT 使用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 用于可配置参数的场景
|
||||
|
||||
@@ -257,6 +232,8 @@ CMD ["--port", "8080"]
|
||||
## 运行时可以覆盖端口
|
||||
|
||||
$ docker run myapp --port 9000
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
@@ -274,8 +251,6 @@ CMD ["echo", "second"] # 只有这个生效
|
||||
|
||||
#### Q: 如何在 CMD 中使用环境变量?
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 方法1:使用 shell 格式
|
||||
|
||||
@@ -314,6 +289,6 @@ CMD ["python", "app.py"]
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [ENTRYPOINT 入口点](entrypoint.md):固定的启动命令
|
||||
- [后台运行](../../05_container/5.2_daemon.md):容器前台/后台概念
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
- [ENTRYPOINT 入口点](7.5_entrypoint.md):固定的启动命令
|
||||
- [后台运行](../05_container/5.2_daemon.md):容器前台/后台概念
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
|
||||
@@ -40,8 +40,6 @@ ENTRYPOINT nginx -g "daemon off;"
|
||||
|
||||
#### 行为对比
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 只用 CMD
|
||||
|
||||
@@ -82,14 +80,12 @@ $ docker run myimage -v http://other.com # curl -s -v http://other.com ✓
|
||||
|
||||
### 场景一:让镜像像命令一样使用
|
||||
|
||||
#### 需求
|
||||
#### 需求(启动前准备)
|
||||
|
||||
创建一个查询公网 IP 的"命令"镜像。
|
||||
|
||||
#### 使用 CMD 的问题
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM ubuntu:24.04
|
||||
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
|
||||
@@ -104,14 +100,11 @@ $ docker run myip -i # ✗ 错误!
|
||||
exec: "-i": executable file not found
|
||||
## -i 替换了整个 CMD,被当作可执行文件
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 使用 ENTRYPOINT 解决
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM ubuntu:24.04
|
||||
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
|
||||
@@ -130,8 +123,6 @@ HTTP/1.1 200 OK
|
||||
|
||||
#### 交互图示
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
ENTRYPOINT ["curl", "-s", "http://myip.ipip.net"]
|
||||
│
|
||||
@@ -153,8 +144,6 @@ curl -s http://myip.ipip.net -i
|
||||
|
||||
#### 实现方式
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM redis:7-alpine
|
||||
COPY docker-entrypoint.sh /usr/local/bin/
|
||||
@@ -186,8 +175,6 @@ exec "$@"
|
||||
|
||||
#### 工作流程
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
docker run redis docker run redis bash
|
||||
│ │
|
||||
@@ -210,8 +197,6 @@ docker-entrypoint.sh redis-server docker-entrypoint.sh bash
|
||||
|
||||
### 场景三:带参数的应用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM python:3.12-slim
|
||||
WORKDIR /app
|
||||
@@ -238,8 +223,7 @@ $ docker run myapp --host 0.0.0.0 --port 9000
|
||||
$ docker run myapp --help
|
||||
## 执行: python app.py --help
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
@@ -282,8 +266,6 @@ $ docker run --entrypoint /bin/cat myimage /etc/os-release
|
||||
|
||||
#### 1. 使用 exec 格式
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 推荐
|
||||
|
||||
@@ -296,8 +278,6 @@ ENTRYPOINT python app.py
|
||||
|
||||
#### 2. 提供有意义的默认参数
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENTRYPOINT ["nginx"]
|
||||
CMD ["-g", "daemon off;"]
|
||||
@@ -346,6 +326,6 @@ wait $PID
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [CMD 容器启动命令](cmd.md):默认命令
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):启动命令设计
|
||||
- [后台运行](../../05_container/5.2_daemon.md):前台/后台概念
|
||||
- [CMD 容器启动命令](7.4_cmd.md):默认命令
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):启动命令设计
|
||||
- [后台运行](../05_container/5.2_daemon.md):前台/后台概念
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 格式一:单个变量
|
||||
|
||||
@@ -20,8 +18,6 @@ ENV <key1>=<value1> <key2>=<value2> ...
|
||||
|
||||
#### 设置单个变量
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENV NODE_VERSION 20.10.0
|
||||
ENV APP_ENV production
|
||||
@@ -29,8 +25,6 @@ ENV APP_ENV production
|
||||
|
||||
#### 设置多个变量
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENV NODE_VERSION=20.10.0 \
|
||||
APP_ENV=production \
|
||||
@@ -45,8 +39,6 @@ ENV NODE_VERSION=20.10.0 \
|
||||
|
||||
#### 1. 后续指令中使用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENV NODE_VERSION=20.10.0
|
||||
|
||||
@@ -67,8 +59,6 @@ COPY . $APP_HOME
|
||||
|
||||
#### 2. 容器运行时使用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENV DATABASE_URL=postgres://localhost/mydb
|
||||
```
|
||||
@@ -149,8 +139,6 @@ DATABASE_URL=postgres://localhost/mydb
|
||||
|
||||
#### 组合使用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ARG 接收构建时参数
|
||||
|
||||
@@ -177,8 +165,6 @@ $ docker build --build-arg NODE_VERSION=18 -t myapp .
|
||||
|
||||
#### 1. 统一管理版本号
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 好:版本集中管理
|
||||
|
||||
@@ -195,8 +181,6 @@ RUN apt-get install nginx=1.25.0
|
||||
|
||||
#### 2. 不要存储敏感信息
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 错误:密码写入镜像
|
||||
|
||||
@@ -206,14 +190,11 @@ ENV DB_PASSWORD=secret123
|
||||
|
||||
## docker run -e DB_PASSWORD=xxx myimage
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 3. 为应用提供合理默认值
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENV APP_ENV=production \
|
||||
APP_PORT=8080 \
|
||||
@@ -222,8 +203,6 @@ ENV APP_ENV=production \
|
||||
|
||||
#### 4. 使用有意义的变量名
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 好:清晰的命名
|
||||
|
||||
@@ -265,8 +244,6 @@ $ docker exec mycontainer env
|
||||
|
||||
#### Q: 多行 ENV 还是多个 ENV
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 推荐:减少层数
|
||||
|
||||
@@ -295,6 +272,6 @@ ENV VAR3=value3
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [ARG 构建参数](arg.md):构建时变量
|
||||
- [Compose 环境变量](../../compose/10.5_compose_file.md):Compose 中的环境变量
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
- [ARG 构建参数](7.7_arg.md):构建时变量
|
||||
- [Compose 环境变量](../10_compose/10.5_compose_file.md):Compose 中的环境变量
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG <参数名>[=<默认值>]
|
||||
```
|
||||
@@ -37,8 +35,6 @@ ARG <参数名>[=<默认值>]
|
||||
|
||||
#### 定义和使用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 定义有默认值的 ARG
|
||||
|
||||
@@ -70,8 +66,6 @@ $ docker build --build-arg NODE_VERSION=18 -t myapp .
|
||||
|
||||
#### FROM 之前的 ARG
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## FROM 之前的 ARG 只能用于 FROM 指令
|
||||
|
||||
@@ -87,8 +81,6 @@ RUN echo $REGISTRY # 输出空
|
||||
|
||||
#### FROM 之后重新声明
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG NODE_VERSION=20
|
||||
|
||||
@@ -102,8 +94,6 @@ RUN echo "Node version: $NODE_VERSION"
|
||||
|
||||
#### 多阶段构建中的 ARG
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG BASE_VERSION=alpine
|
||||
|
||||
@@ -126,8 +116,6 @@ RUN echo "Running with Node $NODE_VERSION"
|
||||
|
||||
#### 1. 控制基础镜像版本
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG ALPINE_VERSION=3.19
|
||||
FROM alpine:${ALPINE_VERSION}
|
||||
@@ -139,8 +127,6 @@ $ docker build --build-arg ALPINE_VERSION=3.18 .
|
||||
|
||||
#### 2. 设置软件版本
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG NGINX_VERSION=1.25.0
|
||||
|
||||
@@ -149,8 +135,6 @@ RUN curl -fsSL https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz | tar -x
|
||||
|
||||
#### 3. 配置构建环境
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG BUILD_ENV=production
|
||||
ARG ENABLE_DEBUG=false
|
||||
@@ -164,8 +148,6 @@ RUN if [ "$ENABLE_DEBUG" = "true" ]; then \
|
||||
|
||||
#### 4. 配置私有仓库
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG NPM_TOKEN
|
||||
|
||||
@@ -223,8 +205,6 @@ $ docker build --build-arg HTTP_PROXY=http://proxy:8080 .
|
||||
|
||||
#### 1. 为 ARG 提供合理默认值
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 好:有默认值
|
||||
|
||||
@@ -237,8 +217,6 @@ ARG NODE_VERSION
|
||||
|
||||
#### 2. 不要用 ARG 存储敏感信息
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 错误:密码会被记录在镜像历史中
|
||||
|
||||
@@ -247,14 +225,11 @@ RUN echo "password=$DB_PASSWORD" > /app/.env
|
||||
|
||||
## ✅ 正确:使用 secrets 或运行时环境变量
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 3. 使用 ARG 提高构建灵活性
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG BASE_IMAGE=python:3.12-slim
|
||||
FROM ${BASE_IMAGE}
|
||||
@@ -263,8 +238,7 @@ FROM ${BASE_IMAGE}
|
||||
|
||||
## docker build --build-arg BASE_IMAGE=python:3.11-alpine .
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
@@ -282,6 +256,6 @@ FROM ${BASE_IMAGE}
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [ENV 设置环境变量](env.md):运行时环境变量
|
||||
- [FROM 指令](../../04_image/4.5_build.md):基础镜像指定
|
||||
- [多阶段构建](../multistage-builds.md):复杂构建场景
|
||||
- [ENV 设置环境变量](7.6_env.md):运行时环境变量
|
||||
- [FROM 指令](../04_image/4.5_build.md):基础镜像指定
|
||||
- [多阶段构建](7.17_multistage_builds.md):复杂构建场景
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
VOLUME ["/路径1", "/路径2"]
|
||||
VOLUME /路径
|
||||
@@ -40,8 +38,6 @@ VOLUME /路径
|
||||
|
||||
#### 定义单个卷
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM mysql:8.0
|
||||
VOLUME /var/lib/mysql
|
||||
@@ -49,8 +45,6 @@ VOLUME /var/lib/mysql
|
||||
|
||||
#### 定义多个卷
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM myapp
|
||||
VOLUME ["/data", "/logs", "/config"]
|
||||
@@ -110,8 +104,6 @@ RUN echo "hello" > /data/test.txt
|
||||
|
||||
#### 正确做法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM ubuntu
|
||||
|
||||
@@ -130,8 +122,6 @@ VOLUME /data
|
||||
|
||||
#### 数据库持久化
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM postgres:15
|
||||
VOLUME /var/lib/postgresql/data
|
||||
@@ -139,8 +129,6 @@ VOLUME /var/lib/postgresql/data
|
||||
|
||||
#### 日志目录
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM nginx
|
||||
VOLUME /var/log/nginx
|
||||
@@ -148,8 +136,6 @@ VOLUME /var/log/nginx
|
||||
|
||||
#### 上传文件目录
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM myapp
|
||||
VOLUME /app/uploads
|
||||
@@ -219,8 +205,7 @@ volumes:
|
||||
$ docker run --rm mysql:8.0
|
||||
## 容器停止后,数据丢失!
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
**解决**:始终使用命名卷
|
||||
@@ -235,8 +220,6 @@ $ docker run -v mysql_data:/var/lib/mysql mysql:8.0
|
||||
|
||||
#### 1. 定义必须持久化的路径
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 数据库必须使用卷
|
||||
|
||||
@@ -246,8 +229,6 @@ VOLUME /var/lib/postgresql/data
|
||||
|
||||
#### 2. 不要在 VOLUME 后修改目录
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 避免
|
||||
|
||||
@@ -262,8 +243,6 @@ VOLUME /app/data
|
||||
|
||||
#### 3. 文档中说明 VOLUME 用途
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 持久化用户上传的文件
|
||||
|
||||
@@ -288,6 +267,6 @@ VOLUME /var/lib/mysql
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [数据卷](../../08_data_network/data/volume.md):卷的管理和使用
|
||||
- [挂载主机目录](../../08_data_network/data/bind-mounts.md):Bind Mount
|
||||
- [Compose 数据管理](../../compose/10.5_compose_file.md):Compose 中的卷配置
|
||||
- [数据卷](../08_data_network/data/volume.md):卷的管理和使用
|
||||
- [挂载主机目录](../08_data_network/data/bind-mounts.md):Bind Mount
|
||||
- [Compose 数据管理](../10_compose/10.5_compose_file.md):Compose 中的卷配置
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
EXPOSE <端口> [<端口>/<协议>...]
|
||||
```
|
||||
@@ -14,8 +12,6 @@ EXPOSE <端口> [<端口>/<协议>...]
|
||||
|
||||
### 基本用法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 声明单个端口
|
||||
|
||||
@@ -97,16 +93,13 @@ $ docker port $(docker ps -q)
|
||||
|
||||
#### 没有 EXPOSE 也能 -p
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 即使没有 EXPOSE,也可以使用 -p
|
||||
|
||||
FROM nginx
|
||||
## 没有 EXPOSE
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -121,8 +114,6 @@ $ docker run -p 8080:80 mynginx
|
||||
|
||||
#### 误解:EXPOSE 会打开端口
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 错误理解:这不会让容器可从外部访问
|
||||
|
||||
@@ -138,8 +129,6 @@ EXPOSE 只是元数据声明。容器是否实际监听该端口,取决于容
|
||||
|
||||
#### 正确理解
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Dockerfile
|
||||
|
||||
@@ -159,8 +148,6 @@ $ docker run -p 8080:80 nginx # 2. 映射:宿主机 8080 → 容器 80
|
||||
|
||||
#### 1. 总是声明应用使用的端口
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Web 服务
|
||||
|
||||
@@ -180,8 +167,6 @@ EXPOSE 6379
|
||||
|
||||
#### 2. 使用明确的协议
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 默认是 TCP
|
||||
|
||||
@@ -198,8 +183,6 @@ EXPOSE 53/tcp 53/udp
|
||||
|
||||
#### 3. 与应用实际端口保持一致
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 好:EXPOSE 与应用端口一致
|
||||
|
||||
@@ -217,8 +200,6 @@ CMD ["node", "server.js"] # 实际监听 3000
|
||||
|
||||
### 使用环境变量
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG PORT=80
|
||||
EXPOSE $PORT
|
||||
@@ -256,6 +237,6 @@ services:
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [网络配置](../../network/README.md):Docker 网络详解
|
||||
- [端口映射](../../network/port_bindingbindingbinding.md):-p 参数详解
|
||||
- [Compose 端口](../../compose/10.5_compose_file.md):Compose 中的端口配置
|
||||
- [网络配置](../08_data_network/network/README.md):Docker 网络详解
|
||||
- [端口映射](../08_data_network/network/port_mapping.md):-p 参数详解
|
||||
- [Compose 端口](../10_compose/10.5_compose_file.md):Compose 中的端口配置
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Dockerfile 是一个文本文件,其內包含了一条条的 **指令(Instruction)**,每一条指令构建一层,therefore 每一条指令的内容,就是描述该层应当如何构建。
|
||||
|
||||
在 [第四章](04_image/README.md) 中,我们通过 `docker commit` 学习了镜像的构成。但是,手动 `commit` 只能作为临时修补,并不适合作为生产环境镜像的构建方式。
|
||||
在 [第四章](../04_image/README.md) 中,我们通过 `docker commit` 学习了镜像的构成。但是,手动 `commit` 只能作为临时修补,并不适合作为生产环境镜像的构建方式。
|
||||
|
||||
使用 Dockerfile 构建镜像有以下优势:
|
||||
|
||||
@@ -35,7 +35,7 @@ Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像
|
||||
* [ONBUILD 为他人作嫁衣裳](7.13_onbuild.md)
|
||||
* [LABEL 为镜像添加元数据](7.14_label.md)
|
||||
* [SHELL 指令](7.15_shell.md)
|
||||
* [RUN 执行命令](5.1_run.md)
|
||||
* [RUN 执行命令](7.1_run.md)
|
||||
|
||||
此外,我们还将介绍 Dockerfile 的最佳实践和常见问题。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user