Continue Using .env Files As Usual. 1) I can genuinely say I don't think I understand your first paragraph. 2) Sure, it takes some guts to say anything, I suppose. Although, I don't think it takes that much guts to type something on the Internet. That aside, the post would have been great if it had just been to the point, but instead it included a level of toxicity that wasn't necessary to make the point. That is what I commented on. I love sharing ideas and learning new things - I really do, but I can also do without the toxicity that is already so prevalent elsewhere on the Internet. It'd be nice if people as smart as software developers could get rid of the ape mind and just have an academic discussion or debate without taking pot shots that don't add anything.

2025-06-04

继续照常使用 .env 文件。

1) 我可以坦白地说,我认为我没有理解你的第一段。

2) 没错,我想,说什么都需要勇气。不过,我觉得在网上发帖其实没那么大的勇气。撇开这点不谈,如果这篇文章能切中要点就好了,但它却包含了一些与要点无关的恶意内容。这就是我评论的原因。我喜欢分享想法和学习新事物——真的喜欢,但我也可以避免网络上其他地方已经盛行的恶意内容。如果像软件开发人员这样聪明的人能够摆脱猿猴思维,只进行学术讨论或辩论,而不是进行毫无意义的攻击,那就太好了。

目录(TOC)。

👉简介。

我们都知道,第一印象至关重要。文章的第一句话也同样如此。事实上,对于一篇文章来说,第一印象可能更为关键,因为第一句话决定了读者是否会继续阅读。

但就这篇文章而言,声称从事大型系统开发就能让你有资格撰写相关主题的文章,这说法相当滑稽。这句话会产生一种心理效应,让读者觉得自己很愚蠢,注定要失败,因为他们都认为自己在做“Hello World”之类的项目。

不用说,作为读者,你可能会开始疑惑:“他说他曾经在大型系统上工作过,这到底是什么意思?”我的意思是,现在每个人都在做这件事。我不认为这可以作为一个独特的卖点或其他什么;几乎每个人都有在大型企业系统上工作的经验。

即使是资历最浅的工程师,也可能参与过每天处理数百万条请求/记录的系统。那么,在大型系统上工作究竟有何独特之处?是什么让你觉得你的经验如此宝贵?你需要展现出你的独特之处,否则,它只不过是文章中又一个多余的句子而已。好了,我们继续吧。

让我们首先批评每一个看起来像.env文件问题的观点,但实际上,它们根本不是问题,而是误解。

👉 1.存储.env 文件。

🔝前往目录


Linux 中的一切都是文件。

本节由以下人员开始:

问题是...这是一个文件。

好吧,我不知道你的情况,也不知道你现在用的是什么操作系统,但Linux 中的一切都是字面意义上的文件。这包括设备、进程、套接字、文件、管道等等。然而,关键问题是:这到底有什么问题?

如果你认为将 Linux 中的所有内容(包括环境变量)都保存为文件不是一个好主意,那么你应该邀请 Linus 进行辩论,讨论这种方法的缺点。并提供你的解决方案。

此外,容器基于 Linux cgroup、命名空间和其他组件,这意味着它们也基于“一切皆文件”的概念构建。这使得 Linux 成为运行容器的强大操作系统,因为一切都可以通过文件轻松管理和控制。

此外,Kubernetes 中的所有内容也都是一个文件,一个 YAML 文件。这一概念使得 Kubernetes 极其灵活且可定制。您可以随意配置任何内容,而且几乎没有任何限制。

由于作者目前在 Google 工作,他有机会与 K8s 背后的智囊们探讨文件的弊端,并与我们分享他的见解。我们很想听听他对此的看法!

此外,问题是:谁会把.env文件提交到公共仓库?实际上,据我所知,没有一个脑子好使的人愿意提交环境变量文件。GitHub上的一些开发者包括我在内,只提交了该文件的模板,以帮助其他人理解特定项目中使用的环境变量。如果你想忽略该文件的提交,可以使用一个.gitignore文件;这是基本原则,每个人都应该了解这一点。

即使您不喜欢为每个新 repo 包含一个文件,您也可以在全局文件.gitignore中添加一个新条目,这样您就不必担心每次创建新 repo 时都包含该文件。~/.gitignore

现在,您可能会想:那么,如何.env与其他开发人员共享文件呢?答案是这样的:如果您正在与其他人合作一个项目,则必须将.env文件保持私密,以便只有受邀的合作者才能看到它(例如,为该文件创建私人仓库.env)。

👉 2. 更新秘密配置

🔝前往目录

我在公司工作多年,从来没有机会更新数据库密码。这是因为总有人负责管理数据库。拥有更新密码的权限是一项巨大的责任,而且可能会导致安全漏洞。

因此,设立专人负责可以确保密码保持最新和安全。这也意味着,如果密码出现问题,只需联系一个人即可解决。这个系统可能并不完美,但它是保护公司数据的最佳方法。

我所能获取的只是环境名称,并在应用内使用它们。仅此而已,没有其他的了。这就是为什么指定专人如此重要。这不仅能减轻员工的工作负担,还能确保每个人的进度一致、安全可靠。

👉3.版本控制。

🔝前往目录

环境变量不是应用程序代码的一部分,因此无需对其进行版本控制。我从未使用过会跟踪密码历史记录更改的应用程序,而且我认为没有必要这样做。它们只是静态值,不会经常更改。

但无论如何,如果您想对.env存储在私有存储库中的文件应用版本控制,则可以为每个值更改发布一个新版本。

然后作者继续为一个根本不存在的问题提供一个解决方案。更可笑的是,这个解决方案竟然会带来潜在的安全风险。所以,说白了,如果你不想管理自己的秘密,那就让别人来帮你管理吧,更何况你共享秘密的一方又是一个中心化的地方。一旦它被攻破,全世界所有人的秘密都会暴露。

因此,每个人都可以控制自己的秘密,而不必依赖第三方,尤其是在涉及敏感信息的情况下。

👉 为什么要.env提交?

🔝前往目录

作为开发人员,我们使用.env文件来存储环境变量。这些文件不适用于生产环境,在部署到生产环境之前,应该从代码库中删除/忽略它们。如果您曾经使用过容器化应用,您就会明白这一点。

在代码库中保存文件的目的.env是,以文档的形式提供所需环境变量的示例或模板,说明该项目需要哪些变量。这些变量可以有默认值,但众所周知,它们绝不能包含纯文本凭证。这就像告诉其他开发者,X、Y 和 Z 是此应用中的环境变量。.env在代码库中保存模板文件可以为其他开发者设定预期,并维护最佳实践。这可以帮助新开发者轻松克隆代码库并使用它。

然后,应用程序应该加载此模板.env,并根据当前环境查找其他地方来覆盖这些默认值。这些地方可能是.env.local系统上的文件、已设置的系统环境变量,或者来自配置存储的变量。如果你曾经使用过 Jenkins 或构建过 DevOps 流水线,你可能遇到过这种情况。

我们明白;在生产中使用文件不是一个好主意,.env因为它们可能包含敏感信息,如数据库密码、API 密钥和其他不应被他人访问的凭据。

但是,您可以采取额外的预防措施来确保您的.env文件或环境变量的安全。

👉 保护 .env 文件?

🔝前往目录

如果文件.env用于生产目的,则不安全。任何有权访问该机器的人都可以在未经许可的情况下查看和修改它。

但是,您可以为此文件设置权限。我不知道您是怎么做的,但您可以使用以下命令来保护您的 env 文件:

chmod 0400 .env
Enter fullscreen mode Exit fullscreen mode

这样做之后,该.env文件只有所有者才能读取,其他任何人都无法读取。如果需要将 Docker File 复制到 Docker 镜像中,可以在 Docker File 中使用此命令。但通常情况下,不建议这样做。对于 Docker,可以使用 Secrets,这将在后续章节中讨论。

如果您曾经使用过laravel,那么在生产环境中使用该文件的可能性.env很高。只要您保证其安全,就完全没问题。以下是 Laravel 开发人员使用的典型安全实践:

#Disable index view
options -Indexes

#hide a Specific File

<Files .env>
order allow, deny
Deny from all
</Files>
Enter fullscreen mode Exit fullscreen mode

在 docker 中,您可以使用以下命令通过 docker-compose导入环境变量:

docker-compose --env-file .env
Enter fullscreen mode Exit fullscreen mode

或者您可以在 YAML 文件中指定环境文件:

version: "3.8"

services:
  frontend:
    image: awesome/webapp
    env_file:
      - .env     # path to your .env file
Enter fullscreen mode Exit fullscreen mode

如果您想传递秘密,那么您可以在文件中定义一个秘密部分docker-compose.yaml

version: "3.8"

services:
  frontend:
    image: awesome/webapp
    secrets:
      - server-certificate

secrets:
  server-certificate:
    file: ./server.cert
Enter fullscreen mode Exit fullscreen mode

如果您正在构建 docker 镜像,则可以创建一个 env 文件来存储机密并将该文件挂载到容器。

PYPI_USER=dev_bro
PYPI_PASS=my_super_duper_secret_token
Enter fullscreen mode Exit fullscreen mode

现在,您可以加载该.env文件并为其指定一个名为 的 ID my_secret。我们可以在下一步中使用此密钥来访问该.env文件。然后修改 Dockerfile,使其能够挂载这些机密。

FROM python:3.9-slim-buster
COPY build-script.sh .
RUN --mount=type=secret,id=my_secret . ./build-script.sh
Enter fullscreen mode Exit fullscreen mode
# build-script.sh:
cat /run/secrets/my_secret
Enter fullscreen mode Exit fullscreen mode

现在,您可以构建文件并将其注入.env容器中:

export DOCKER_BUILDKIT=1
docker build --progress=plain -t "my_app" --secret id=my_secret,src=.env . --no-cache
Enter fullscreen mode Exit fullscreen mode

请注意,这些环境变量未记录到历史记录中,因此运行以下命令不会泄露秘密:

docker history my_app --no-trunc | grep PYPI_PASS
Enter fullscreen mode Exit fullscreen mode

有关 docker 中的 secrets 的更多信息,可以参考这篇文档

此外,如果您使用 Kubernetes,则可以使用ConfigMap等 API 对象来存储配置数据,以及使用Secrets 等API 对象来存储机密数据。或者,您也可以在 Pod 中设置环境变量

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod

spec:
  containers:
    - name: test-container
      image: registry.k8s.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        # Define the environment variable
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              # The ConfigMap containing the value you want to assign to SPECIAL_LEVEL_KEY
              name: special-config
              # Specify the key associated with the value
              key: special.how
  restartPolicy: Never
Enter fullscreen mode Exit fullscreen mode

我参与过很多项目,其中一些是开源的。在一些项目中,比如这个,我使用环境变量在 circleci 中存储我的机密信息,以便自动将新版本发布到 PyPi。

此外,出于安全考虑,我注意到 PyPi 已经实现了一项功能,允许使用API 令牌与其服务器进行身份验证,而无需再输入密码。因此,现在您可以将加密的 PyPi 凭据存储在环境变量中。

如果您曾经使用 Azure DevOps 构建过管道,那么您可能希望使用复制文件任务.env将文件复制到 docker 镜像中

steps:
- task: DownloadSecureFile@1
  displayName: 'Download secure file'
  inputs:
    secureFile: .env

- task: CopyFiles@2
  displayName: 'Copy Files to: $(System.DefaultWorkingDirectory)'
  inputs:
    SourceFolder: '$(Agent.TempDirectory)'
    Contents: .env
    TargetFolder: '$(System.DefaultWorkingDirectory)'
Enter fullscreen mode Exit fullscreen mode

如果您使用的是 Jenkins,则可以使用envinject等插件注入环境变量

因此,正如您所看到的,遵循最佳实践来安全地使用文件取决于您正在处理的应用程序类型.env

👉使用.env文件的优点。

🔝前往目录

使用文件或环境变量有很多优点.env,例如:

  • 易于管理:在参与过许多后端项目后,我发现.env文件易于管理,因为它们不言自明,不需要额外的文档。

  • 简单性.env文件简化了管理不同后端的任务,因为它允许您在一个地方配置每个后端的所有必要设置。

  • 调试和测试:由于开发人员可以为每个应用程序修改特定的环境,因此变得更加容易。

  • 共享:可以.env将文件模板.env.example添加到 git 存储库,以便团队中的其他开发人员知道该项目使用了哪些环境变量。

👉 集中式配置服务器的问题。

🔝前往目录

在为应用程序使用集中式配置服务器时,可能会出现一些潜在问题。如果服务器离线,应用程序将无法启动。如果服务器更新并重命名了应用程序未预期的环境变量,应用程序可能会在下次重启时崩溃。最后,如果应用程序离线托管,如果没有互联网连接从外部加载环境变量,它将无法启动。

👉结论。

🔝前往目录

总而言之,.env只要您知道如何使用这些文件,文件和环境变量就可以正常工作,并且对于开发目的来说足够简单。但是,完全取决于您根据个人喜好选择最佳方法,以最适合您的特定应用程序或系统。

👉 Linux 爱好者的奖励。

🔝前往目录

在 Linux 上,如果要打印出LOGNAME当前进程的特定环境变量(如),请运行以下命令:

strings /proc/$$/environ | grep LOGNAME
Enter fullscreen mode Exit fullscreen mode

最后但同样重要的一点是,请记住 Linux 中的所有内容都只是一个文件,包括您刚刚执行的命令:

cat /usr/bin/strings
Enter fullscreen mode Exit fullscreen mode

注意:本文绝不是要侮辱任何人;我只是想与大家分享,以澄清情况.env并提供一些如何使用它们的提示。

祝大家周末愉快。

封面图片Mike Souza在Flickr上发布

文章来源:https://dev.to/wiseai/continue-using-env-files-as-usual-2am5
PREV
使用 React、Typescript 和 react-testing-library 编写单元测试
NEXT
如何使用 React 构建 Electron 应用。简介 先决条件 入门 打包应用 背景 后续