Node.js 如何在不推送.env文件的情况下使用环境变量构建docker映像

Node.js 如何在不推送.env文件的情况下使用环境变量构建docker映像,node.js,gitlab,environment-variables,devops,gitlab-ci,Node.js,Gitlab,Environment Variables,Devops,Gitlab Ci,我刚接触开发人员,发现自己有点困惑。 我有一个启动服务器的节点项目。该服务器的一个端点应写入数据库。在我的本地机器上,我用本地数据库测试这种行为。 我创建了一个.env.prod-file和一个.env.dev-file来确定是使用本地数据库还是服务器数据库(在我的服务器上运行)。我还在博客文章中读到,我永远不应该将我的.env文件推送到远程存储库 然后我创建了一个Dockerfile来构建和发布我的应用程序 在我的远程Gitlab存储库中,我创建了一个.Gitlab-ci.yml,每当有新的提

我刚接触开发人员,发现自己有点困惑。 我有一个启动服务器的节点项目。该服务器的一个端点应写入数据库。在我的本地机器上,我用本地数据库测试这种行为。 我创建了一个.env.prod-file和一个.env.dev-file来确定是使用本地数据库还是服务器数据库(在我的服务器上运行)。我还在博客文章中读到,我永远不应该将我的.env文件推送到远程存储库

然后我创建了一个Dockerfile来构建和发布我的应用程序

在我的远程Gitlab存储库中,我创建了一个.Gitlab-ci.yml,每当有新的提交给master时,它都应该从Dockerfile构建docker映像

但现在我面临的问题是,当我想要构建docker映像时,我需要.env.prod文件,但我不应该推送这个文件,这样GitLab就无法访问它

这种描述方式是一种合适的解决方案,还是我做了一些完全错误的事情(我在开发操作中遗漏了一些核心概念)

这是我的文件

FROM node:12.7-alpine AS build

WORKDIR /usr/graphql-server
COPY package.json /usr/graphql-server/

RUN npm install
COPY ./ /usr/graphql-server

RUN npm run build
COPY ./ /usr/graphql-server

EXPOSE 4000

CMD ["npm", "run", "start:prod"]
npm运行start:prod
执行以下操作:

tsc&&cross-env-NODE\u-env=prod-NODE-dist/index.js

这就是我决定使用哪个配置的方式(index.ts):


最后,多亏了@AndreasJägle,我为我最初的想法想出了一个完全不同的解决方案。 我不再需要.env文件,也不再使用所述的getConfig()方法来解决此问题。此外,无需在Gitlab中存储环境变量

首先,我现在通过在node命令末尾传递环境变量来启动节点进程,如
node dist/index.js variable1
。 可以在运行时读取此环境变量:
const baseUrl=process.argv[2]
。 baseUrl变量可用于向该特定url发送请求

第二,因为我正在使用docker构建我的项目,所以我必须将环境变量的值注入到我的docker映像中。为此,我修改了dockerfile,如下所示

FROM node:12.7-alpine AS build

ENV BASE_URL=localhost
    
...

CMD ["sh", "-c", "node dist/index.js $BASE_URL"]
version: "3"

    services:
      test-service:
        image: my-image:latest
        container_name: 'my-container'
        environment:
          - BASE_URL=mydomain.com
(请注意,localhost是BASE_URL环境变量的默认值,将被覆盖)

最后,我在服务器上的docker compose文件中使用前面构建的映像,并像下面这样设置环境变量

FROM node:12.7-alpine AS build

ENV BASE_URL=localhost
    
...

CMD ["sh", "-c", "node dist/index.js $BASE_URL"]
version: "3"

    services:
      test-service:
        image: my-image:latest
        container_name: 'my-container'
        environment:
          - BASE_URL=mydomain.com

可以存储在gitlab中。您可以提供Dockerfile吗?配置值(如db凭据)不应该是映像的一部分(因此不与映像捆绑在一起)。从环境中使用配置是一种很好的模式。部署应用程序时,相应的运行时应处理这些变量的注入。您最终在哪里运行您的容器?顺便说一句:以编程方式与dotenv文件交互并不是最佳实践。在prod期间,env应该由运行时之类的其他进程发布……我在自己的托管服务器上运行容器。在那里,我创建了一个docker-compose.yml文件来运行它们。docker compose文件是注入环境变量的更合适的地方吗?我尝试了一种不同的方法,对它感到更满意。在我的Dockerfile中,我现在有了环境变量。这些变量用于根据环境启动节点进程。docker环境变量在my docker-compose.yml@AndreasJägle中提供。这就是您想要的吗!不过,您不需要在Dockerfile中包含环境变量。图像/代码应该从env变量读取值,当使用docker compose时,传递这些值的一种方法是将它们放入compose文件中。您还可以在主机上将它们设置为env,并且只传递变量名,这样您就可以在每个系统上使用相同的compose文件。请参见此处的详细信息