Files
docker_practice/07_dockerfile/7.6_env.md

302 lines
5.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 7.6 ENV 设置环境变量
本节涵盖了相关内容与详细描述主要探讨以下几个方面
### 基本语法
如下代码块所示展示了相关示例
```docker
## 格式一:单个变量
ENV <key> <value>
## 格式二:多个变量(推荐)
ENV <key1>=<value1> <key2>=<value2> ...
```
---
### 基本用法
本节涵盖了相关内容与详细描述主要探讨以下几个方面
#### 设置单个变量
如下代码块所示展示了相关示例
```docker
ENV NODE_VERSION 20.10.0
ENV APP_ENV production
```
#### 设置多个变量
如下代码块所示展示了相关示例
```docker
ENV NODE_VERSION=20.10.0 \
APP_ENV=production \
APP_NAME="My Application"
```
> 💡 包含空格的值用双引号括起来
---
### 环境变量的作用
本节涵盖了相关内容与详细描述主要探讨以下几个方面
#### 1后续指令中使用
如下代码块所示展示了相关示例
```docker
ENV NODE_VERSION=20.10.0
## 在 RUN 中使用
RUN curl -fsSL https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.xz \
| tar -xJ -C /usr/local --strip-components=1
## 在 WORKDIR 中使用
ENV APP_HOME=/app
WORKDIR $APP_HOME
## 在 COPY 中使用
COPY . $APP_HOME
```
#### 2容器运行时使用
如下代码块所示展示了相关示例
```docker
ENV DATABASE_URL=postgres://localhost/mydb
```
应用代码中可以读取
```python
import os
db_url = os.environ.get('DATABASE_URL')
```
```javascript
const dbUrl = process.env.DATABASE_URL;
```
---
### 支持环境变量的指令
以下指令可以使用 `$变量名` `${变量名}` 格式
| 指令 | 示例 |
|------|------|
| `RUN` | `RUN echo $VERSION` |
| `CMD` | `CMD ["sh", "-c", "echo $HOME"]` |
| `ENTRYPOINT` | 同上 |
| `COPY` | `COPY . $APP_HOME` |
| `ADD` | `ADD app.tar.gz $APP_HOME` |
| `WORKDIR` | `WORKDIR $APP_HOME` |
| `EXPOSE` | `EXPOSE $PORT` |
| `VOLUME` | `VOLUME $DATA_DIR` |
| `USER` | `USER $USERNAME` |
| `LABEL` | `LABEL version=$VERSION` |
| `FROM` | `FROM node:$NODE_VERSION` |
---
### 运行时覆盖
使用 `-e` `--env` 覆盖 Dockerfile 中定义的环境变量
```bash
## 覆盖单个变量
$ docker run -e APP_ENV=development myimage
## 覆盖多个变量
$ docker run -e APP_ENV=development -e DEBUG=true myimage
## 从环境变量文件读取
$ docker run --env-file .env myimage
```
#### 概述
总体概述了以下内容
#### env 文件格式
运行以下命令
```bash
## .env
APP_ENV=development
DEBUG=true
DATABASE_URL=postgres://localhost/mydb
```
---
### ENV vs ARG
| 特性 | ENV | ARG |
|------|-----|-----|
| **生效时间** | 构建时 + 运行时 | 仅构建时 |
| **持久性** | 写入镜像运行时可用 | 构建后消失 |
| **覆盖方式** | `docker run -e` | `docker build --build-arg` |
| **适用场景** | 应用配置 | 构建参数如版本号 |
#### 概述
总体概述了以下内容
#### 组合使用
如下代码块所示展示了相关示例
```docker
## ARG 接收构建时参数
ARG NODE_VERSION=20
## ENV 保存到运行时
ENV NODE_VERSION=$NODE_VERSION
## 后续指令使用
RUN curl -fsSL https://nodejs.org/dist/v${NODE_VERSION}/...
```
```bash
## 构建时指定版本
$ docker build --build-arg NODE_VERSION=18 -t myapp .
```
---
### 最佳实践
本节涵盖了相关内容与详细描述主要探讨以下几个方面
#### 1统一管理版本号
如下代码块所示展示了相关示例
```docker
## ✅ 好:版本集中管理
ENV NGINX_VERSION=1.25.0 \
NODE_VERSION=20.10.0 \
PYTHON_VERSION=3.12.0
RUN apt-get install nginx=${NGINX_VERSION}
## ❌ 差:版本分散在各处
RUN apt-get install nginx=1.25.0
```
#### 2不要存储敏感信息
如下代码块所示展示了相关示例
```docker
## ❌ 错误:密码写入镜像
ENV DB_PASSWORD=secret123
## ✅ 正确:运行时传入
## docker run -e DB_PASSWORD=xxx myimage
...
```
#### 3为应用提供合理默认值
如下代码块所示展示了相关示例
```docker
ENV APP_ENV=production \
APP_PORT=8080 \
LOG_LEVEL=info
```
#### 4使用有意义的变量名
如下代码块所示展示了相关示例
```docker
## ✅ 好:清晰的命名
ENV REDIS_HOST=localhost \
REDIS_PORT=6379
## ❌ 差:模糊的命名
ENV HOST=localhost \
PORT=6379
```
---
### 常见问题
本节涵盖了相关内容与详细描述主要探讨以下几个方面
#### Q环境变量在 CMD 中不展开
exec 格式不会自动展开环境变量
```docker
## ❌ 不会展开 $PORT
CMD ["python", "app.py", "--port", "$PORT"]
## ✅ 使用 shell 格式或显式调用 sh
CMD ["sh", "-c", "python app.py --port $PORT"]
```
#### Q如何查看容器的环境变量
运行以下命令
```bash
$ docker inspect mycontainer --format '{{json .Config.Env}}'
$ docker exec mycontainer env
```
#### Q多行 ENV 还是多个 ENV
如下代码块所示展示了相关示例
```docker
## ✅ 推荐:减少层数
ENV VAR1=value1 \
VAR2=value2 \
VAR3=value3
## ⚠️ 多个 ENV 会创建多层
ENV VAR1=value1
ENV VAR2=value2
ENV VAR3=value3
```
---